DrawBrepShaded rendering artifacts in DisplayConduit

DrawBrepShaded rendering artifacts in DisplayConduit

Description

I’m experiencing a rendering issue with DisplayPipeline.DrawBrepShaded() in a custom DisplayConduit. When I render a Brep in the conduit’s preview, the rendered result appears incorrect - some parts are missing while other parts seem duplicated or misplaced. However, the same Brep renders perfectly fine when added to the Rhino document using doc.Objects.AddBrep().

Expected Behavior

The Brep should render correctly in the DisplayConduit preview, matching how it appears when added to the document.

Actual Behavior

The Brep renders with visual artifacts:

  • Some surfaces are missing
  • Some areas appear duplicated or rendered in wrong positions
  • The overall geometry looks corrupted in the preview

Steps to Reproduce

  1. Create a Brep (in my case, a flanging/offset geometry from Brep edges)
  2. Enable a custom DisplayConduit that renders the Brep using DrawBrepShaded()
  3. Observe the incorrect rendering in the conduit preview
  4. Add the same Brep to document - it displays correctly

Code Sample

DisplayConduit Implementation

public class FlangingDisplayer : DisplayConduit
{
    public List<FlangingItem> Items { get; set; } = [];
    
    protected override void CalculateBoundingBox(CalculateBoundingBoxEventArgs e)
    {
        if (Items.Count == 0)
        {
            return;
        }
        foreach (var item in Items)
        {
            if (item.Parent != null)
            {
                e.IncludeBoundingBox(item.Parent.GetBoundingBox(false));
            }
        }
    }
    
    protected override void DrawForeground(DrawEventArgs e)
    {
        if (Items.Count == 0)
        {
            return;
        }
        foreach (var item in Items)
        {
            item.Preview(e.Display);
        }
    }
}

Preview Method

public void Preview(DisplayPipeline pipeline)
{
    if (Flangings.Count > 0)
    {
        foreach (var brep in Flangings)
        {
            if (brep == null)
            {
                continue;
            }
            pipeline.DrawBrepShaded(brep, SurfaceRenderConfig.PreviewMaterial);
            pipeline.DrawBrepWires(brep, Color.DarkGreen, 2);
        }
    }
}

Material Configuration

public static SurfaceRenderConfig Preview { get; } = new SurfaceRenderConfig
{
    Diffuse = Color.FromArgb(100, 200, 100),     
    BackDiffuse = Color.FromArgb(100, 200, 100),  
    Specular = Color.White,
    BackSpecular = Color.White,
    Shine = 0.4,
    BackShine = 0.4,
    Transparency = 0.5,
    BackTransparency = 0.5,
    IsTwoSided = true
};

public DisplayMaterial DefaultDisplayMaterial
{
    get
    {
        var material = new DisplayMaterial
        {
            Diffuse = Diffuse,
            BackDiffuse = BackDiffuse,
            Specular = Specular,
            BackSpecular = BackSpecular,
            Emission = Emission,
            BackEmission = BackEmission,
            Shine = Shine,
            BackShine = BackShine,
            Transparency = Transparency,
            BackTransparency = BackTransparency,
            IsTwoSided = IsTwoSided
        };
        return material;
    }
}

Observations

  • The wireframe rendering (DrawBrepWires) appears correct
  • Only the shaded rendering (DrawBrepShaded) has issues
  • The Brep validates as correct (can be added to document without issues)
  • The problem occurs in DrawForeground override of DisplayConduit
  • The bounding box calculation seems correct
  • The problem seems related to rendering, not the geometry itself

Questions

  1. Does DrawBrepShaded require the Brep to be in a specific state when called from DisplayConduit?
  2. Is there a render mesh preparation step I’m missing before calling DrawBrepShaded?
  3. Could the transparency setting (0.5) be causing Z-fighting or depth sorting issues in the conduit?
  4. Should I call any Brep preparation methods before rendering (e.g., Brep.Compact(), CreateMeshes())?
  5. Is DrawForeground the correct override to use for drawing shaded Breps, or should I use a different event?

Environment

  • Rhino Version: [Your Version]
  • RhinoCommon SDK Version: [Your Version]
  • Operating System: [Your OS]

Screenshots

The normal display should look like this.

Additional Information

I’m implementing a custom preview for an edge flanging operation. The Brep is generated from offset edge curves and appears geometrically valid. The DisplayConduit is enabled during command execution to show real-time preview of the operation result. Any insights into what might cause this rendering discrepancy would be greatly appreciated.

You forgot your systeminfo and the RhinoCommon version.

If the brep has no errors no special preparation is required for most of the breps i’ve used. If it has errors, is invalid or has certain geometric problems, creating the display meshes with custom settings may help to improve the display.

No, better use PostDrawObjects event and report back if this solves your problem.

_

c.

oh.

os version is windows 10

rhino version is 8.18

Thank you for your reply. I tried both of the solutions you mentioned, but neither had any effect.

I’ve found an issue: the broken surface appears when viewed from the back, but it seems fine from the front.

@yangf85 - why are you running such an old service release?

– Dale

Hi Dale.

Do you mean that upgrading to the new version could resolve this issue?

Hi @yangf85 ,

what does brep.IsValidWithLog() report on your brep before you draw it ?

Have you tried brep.SetTolerancesBoxesAndFlags() with all flags enabled yet ?

Can you post that surface / brep ?

_

c.

Hi , the brep is valid,so the log is null.

brep.SetTolerancesBoxesAndFLags

I rendered it again from the front side of the Brep, and there’s still a slight issue.

@yangf85, it’s hard to find without some geometry. Was the lower part created by extruding it ?

What happens if you call one of these on the brep(s):

brep.Repair(scriptcontext.doc.ModelAbsoluteTolerance)
brep.SetTolerancesBoxesAndFlags(True, True, True, True, True, True, True, True)
brep.Faces.SplitKinkyFaces(radians(1.0), True)
brep.Compact()

for the green brep, did you try to rebuild the edges yet ?

_

c.

I suspect the way I generated the Brep might be incorrect—perhaps I didn’t rebuild the Brep’s edges. I’ll try the method you provided.

Thank you so much! The issue has been resolved—using this piece of code fixed the Brep.