Preview NurbsSurface in conduit

Hi, i’m trying to give a preview of a nurbs surface my plugin is generating before the users presses enter to confirm the settings.
In the CRhinoDisplayPipeline there is DrawNurbsSurface(const ON_NurbsSurface &nurbs_surface, int display_density=1), which is useful, but it only dispalys the wires. What i’d like is to offer a shaded preview of the nurbs surface.

Any idea how to get that done?

NOTE:what i tried was to try to use ON_Brep::Create(ON_NurbsSurface *&pNurbsSurface) method to create a Brep out of the ON_NurbsSurface, and use that to call DrawShadedBrep (brep), but the Create() method throws an access violation.

Hi @adl.architetto,

First, if you want to draw anything shaded, you will need to do so in a a custom CRhinoDisplayConduit. This is because dynamic drawing, the kind done by CRhinoGetPoint::DynamicDraw, does not support any sort of depth buffering.

You can find conduit samples in the developer samples repo on GitHub.

Also, when and where to draw ON_Breps highly depends on the desired effect.

If you’re drawing wireframes that you always want on top, then you should probably draw them in the SC_DRAWFOREGROUND channel.

If you’re drawing shaded objects, then you’ll probably want to draw them in either the SC_PREDRAWOBJECTS or SC_POSTDRAWOBJECTS channel. However, if transparency is involved, then you’ll have to draw them in SC_POSTDRAWOBJECTS in order for all other objects to “show through” your transparent ones.

Basically, all of the DRAWOBJECT channels support depth buffered drawing, and doing any kind of drawing anywhere else will not have or support depth buffering.

Hope this helps.

– Dale

Thank you @dale. I was already implemening my own custom conduit class - that’s how i got the ON_NurbsSurface wireframe preview to get displayed. Can you point out one git sample where a ON_NurbsSurface is displayed in a conduit with shading?
Thanks in advance

Hi @adl.architetto,

To draw a surface shaded, you’ll need to create a Brep from it and then draw the Brep.

class CSampleConduit : public CRhinoDisplayConduit
{
public:
  CSampleConduit(const CRhinoDoc& doc, const ON_Surface& surface);
  bool ExecConduit(CRhinoDisplayPipeline& dp, UINT nActiveChannel, bool& bTerminateChannel) override;

private:
  const CRhinoDoc& m_doc;
  ON_Brep m_brep;
};

CSampleConduit::CSampleConduit(const CRhinoDoc& doc, const ON_Surface& surface)
  : CRhinoDisplayConduit(CSupportChannels::SC_CALCBOUNDINGBOX |CSupportChannels::SC_PREDRAWOBJECTS)
  , m_doc(doc)
{
  surface.BrepForm(&m_brep);
}

bool CSampleConduit::ExecConduit(CRhinoDisplayPipeline& dp, UINT nActiveChannel, bool& bTerminateChannel)
{
  switch (nActiveChannel)
  {
  case CSupportChannels::SC_CALCBOUNDINGBOX:
  {
    if (m_brep.IsValid())
    {
      ON_BoundingBox bbox;
      if (m_brep.GetTightBoundingBox(bbox))
        m_pChannelAttrs->m_BoundingBox.Union(bbox);
    }
    break;
  }
  case CSupportChannels::SC_PREDRAWOBJECTS:
  {
    if (m_brep.IsValid())
    {
      ON_Color layer_color = m_doc.m_layer_table.CurrentLayer().Color();
      const CDisplayPipelineAttributes* da = dp.DisplayAttrs();
      if (da->m_bShadeSurface)
      {
        CDisplayPipelineMaterial material;    
        dp.SetupDisplayMaterial(material, layer_color);
        dp.DrawShadedBrep(&m_brep, &material, nullptr);
      }
      dp.DrawBrep(m_brep, layer_color);
    }
  }
  break;
  }
  return true;
}

Note, I have not tested the above…

– Dale

@dale
Works as expected. Thank you for that!