DrawMeshWires makes mesh transparent

Hey,

I’m drawing a few elements from the OnDynamicDraw part of a custom GetPoint class.
Drawing a shaded mesh works ok, but when I add wires to the display, the mesh becomes transparent:

protected override void OnDynamicDraw(GetPointDrawEventArgs e)
        {
        base.OnDynamicDraw(e);
        var displayColor = System.Drawing.Color.Blue;
        var displayMaterial = new Rhino.Display.DisplayMaterial(displayColor);
        e.Display.DrawMeshShaded(_mesh, displayMaterial);
        e.Display.DrawMeshWires(_mesh, displayColor);
        }

Desired display style:

DrawMeshShaded only:

DrawMeshShaded & DrawMeshWires together:

Any ideas what causes this?

Dynamic drawing of GetPoint is I think not depth-buffered, so you will see stuff that is behind parts of the shaded geometry. Either use a custom display conduit, or use OnPostDrawObjects (see docs below)

Thanks @menno!

Overriding OnPostDrawObjects fixed the mesh transparency issue. I’m a bit worried about the deteriorated performance, though. To quote the specs:

NOTE!! Overriding this function comes with a significant performance penalty because the scene needs to be fully regenerated every frame where the standard DynamicDraw event draws temporary decorations (geometry) on top of a static scene.

Also, I just discovered a weird issue with DynamicDraw from GetPoint level - all works fine with an empty scene, but once there is at least one additional object the geometry disappears. This happens both from ‘DynamicDraw’ as well as ‘OnPostDrawObjects’ Please refer to this short clip:

Is this intended behavior?

I don’t think this is intended behavior. Are you calling the base-class implementation in your implementation? It may be related to that, I think I remember that this is needed, not sure though.

First, the dynamic display mechanism is primarily (if not fully) meant for drawing “feedback”, it’s not meant for drawing objects that you want hanging around longer than a given command, which is what it looks like you want in your case.

Second, the “terrain” geometry/mesh should be getting drawn as part of the “object drawing” phase, if you want it to participate in any/all depth buffering calculations.

Third, any/all other type of drawing (i.e. the terrain editing cursor) should get drawn in the dynamic drawing phase, as it seems like it always wants to draw “on top” of the terrain, and it’s part of some editing command.

Given that, I would draw all meshes and wires inside the post object drawing phase, and I would draw all terrain editing tools/icons/cursors etc… inside the dynamic drawing (the one you’re using now).

Note: Keeping a feedback/overlay conduit or a GetObject object hanging around just to draw something is going to be somewhat of a performance drain (and IMO quite heavy handed), as they always cause a frame update…even the slightest mouse move will generate a call to the dynamic drawing mechanism…so if you’re drawing heavy meshes or objects, then you can/will eventually bring Rhino to its knees just by moving the mouse. The “object drawing phases” only get executed if/when something has actually changed the projection or frustum, an object state change, or if some command has forced an entire redraw of the document.

We may need to reword the comments for the post object drawing, because I think it’s confusing the real meaning and functionality.

The disappearing act is somewhat of a mystery, but for now I will attribute it to improper use of the dynamic drawing mechanism. If after you make the simple changes suggested above, you’re still seeing things disappear, then I’ll probably want to see your plugin, or a small example that easily reproduces and demonstrates the problem.

Lastly…this is more of a side note, but I want to make sure it’s clear… What you’re seeing is not “transparency” occurring…you’re seeing all the wires getting drawn on top of all polygons, giving the perception that they’re “showing through” the mesh…but if you look more closely at the actual mesh, it’s still opaque (i.e. you can’t see portions of the mesh that lie behind other portions of the mesh). I only mention this because knowing and understanding this can help you diagnose possible future situations that have similar results.

Hope this helps.
-Jeff

1 Like

Ok, I think I see the real issue here…

You’re using a “GetPoint” object handler to do everything!.. The OnPostObjectsDraw() method on the GetPoint object is definitely NOT how you should be drawing things. You should be using a conduit to draw your objects/geometry. I just assumed you were because “Post Objects Draw” is a conduit phase.

-Jeff

1 Like

Thanks for a great explanation @jeff!

I switched to replacing the mesh object in doc.Objects to solve the display issues.

How would you structure such a conduit? As you pointed out - currently the entire sculpting logic happens in OnDynamicDraw of a custom GetPoint class. Here is a truncated version of what I currently have:

Class derived from GetPoint responsible for finding the Mesh-Cursor intersection, displaying the brush cursor and calling the sculpting method when mouse is pressed and moving:

public class Brush : GetPoint
{
        protected override void OnMouseDown(GetPointMouseEventArgs e)
        {
            mousePressed = true; // toggle sculpting flag
            Sculpt.SculptMesh(ref mesh, verticesCenter, verticesFalloff); // Modify mesh vertices
        }

        protected override void OnDynamicDraw(GetPointDrawEventArgs e)
        {
         findCursorMeshIntersection(); // find affected mesh vertices
                
                if (mousePressed) // sculpt geometry
                {
                    Sculpt.SculptMesh(ref mesh, verticesCenter, verticesFalloff);
                    doc.Objects.Replace(getObject.Object(0).ObjectId, mesh);
                }
                else // Only draw the cursor when mouse is not pressed
                {
                    // Draw circles
                    e.Display.DrawCircle(circle, System.Drawing.Color.DodgerBlue, 3);
                    e.Display.DrawCircle(circleFalloff, System.Drawing.Color.DodgerBlue);

                    // Draw points
                    e.Display.DrawPoints(_center, PointStyle.RoundSimple, 3f, System.Drawing.Color.Red);
                    e.Display.DrawPoints(_falloff, PointStyle.RoundSimple, 3f, System.Drawing.Color.GreenYellow);
                }
        }
}

In the Rhino command I create an instance of the above class and listen for click events like so:

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            var sculptMesh = new Brush();

            while (true)
            {
                var result = sculptMesh.Get(true); // wait until the mouse button is released

                if (result == GetResult.Point)
                {
                    Brush.mousePressed = false;
                    doc.Objects.Replace(Brush.getObject.Object(0).ObjectId, Brush.mesh);
                    continue;
                }

                break;
            }
            doc.Views.Redraw();
            return Result.Success;
        }

Ideally, I’d like to be able to handle high-poly meshes and would appreciate any hint on how to optimize this logic for maximum performance. I’m happy to share the full code with you if needed.