[C++ SDK] Change curve thickness when drawing

I would like to change the curve thickness that I draw when I get a CRhinoDrawGripsSettings object.

Currently I can do this for a polyline:

CRhinoDrawGripsSettings dgs; // defined elsewhere
ON_Polyline pl; // defined elsewhere
int thickness = 2; // <-- here I can change the thickness for a polyline
COLORREF clr = RGB(255,0,0);

dgs.m_dp.DrawPolyline(pl, crl, thickness);

I also want to draw a curve. For that I can’t use the display pipeline m_dp but I can use the viewport m_vp like so:

CRhinoDrawGripsSettings dgs; // defined elsewhere
ON_Curve crv; // defined elsewhere
ON_NurbsCurve nc;
if (crv.GetNurbForm(nc)) {
    COLORREF clr = RGB(255,0,0);
    COLORREF old = dgs.m_vp.DrawColor();
    dgs.m_vp.SetDrawColor(clr);
    dgs.m_vp.DrawNurbsCurve(nc); // <-- How to set the thickness for this curve?
    dgs.m_vp.SetDrawColor(old);  // set to previous value
}

So, what I want to achieve is, given a CRhinoDrawGripsSettings object, to draw a curve with thickness of 2. Currently, I use the viewport to call DrawNurbsCurve but I don’t see how to set the thickness with which the curve is drawn.

Hi Menno,

It is not clear to me why you are using a CRhinoDrawGripsSettings object, which is used for drawing grips and their control polygon.

Keep in mind that drawing routines, found on CRhinoViewport, eventually end calling lower-level drawing routines on CRhinoDisplayPipeline. CRhinoViewport::DrawNurbsCurve, for example, ends up iterating the curve and calling CRhinoDisplayPipeline::DrawBezier.

Thus, if you want to draw a thick NURBS from within conduit, you can do something like this:

  case CSupportChannels::SC_DRAWFOREGROUND:
    {
      if( m_nurbs.IsValid() )
      {
        m_pDisplayAttrs->m_nCurveThickness = 3;
        dp.GetRhinoVP().DrawNurbsCurve( m_nurbs );
      }
    }

I’m drawing some extra supporting geometry as the custom grips on a custom surface object are being drawn. So, I am not drawing from within a conduit and have no access to m_pDisplayAttrs.

I did find, however, the DisplayPipeline.SetCurveThickness function that I can run prior to drawing curves on the viewport using dgs.m_vp.DrawNurbsCurve This also works.

All of the CRhinoViewport “draw” functions actually end up going through the display pipeline which is why this works. We will eventually move all of these draw functions off of CRhinoViewport and on to the display pipeline class, but that won’t happen until at least V6.

I tried hijacking your approach for controlling curve thickness for use in my C++ code:

ON_3dmObjectAttributes attribs;
// Assign default values.
pDoc->GetDefaultObjectAttributes(attribs);
attribs.m_layer_index = layer_index;
// Find end-points of edge.
x0 = xyz[v0]; x1 = xyz[v1]; y0 = xyz[v0 + 1]; y1 = xyz[v1 + 1]; z0 = xyz[v0 + 2]; z1=xyz[v1 + 2];
SP(ON_3dPoint(x0, y0, z0), 255, 0, 255, pDoc, layer_index, layer_name_num, mesh_name);
SP(ON_3dPoint(x1, y1, z1), 255, 0, 255, pDoc, layer_index);
// Put line joining ends on same layer as dots.
attribs.m_layer_index = layer_index;
// Increase thickness of curve.
attribs.m_pDisplayAttrs->m_nCurveThickness = 3;
// Create pointer to attributes.
auto pattribs = &attribs;
// Draw line between end points of naked edge.
pDoc->AddCurveObject(ON_Line(ON_3dPoint(x0, y0, z0), ON_3dPoint(x1,y1,z1)), pattribs);

but this does not work because

attribs.m_pDisplayAttrs

is not recognized.

I need a thicker line that will stand out from the wireframe of my mesh otherwise it gets lost. I can hide the mesh and then they show up fine but that defeats my purpose. For example, the green naked edges are hard to see on this mesh (drawn without offending line of code above):

I added

attribs.m_display_order = 1;

and that helps some:

but the green lines are still not all that obvious.

I added:

attribs.m_plot_weight_mm = -3;

based upon the comments in opennurbs_3dm_attributes.h

// Plot weight in millimeters.
// =0.0 means use the default width
// <0.0 means don’t plot (visible for screen display, but does not show on plot)

but this seems to make no difference.

Can you suggest something that will work? I have combed thru many pages of the Rhino C++ API and searched the internet without success.

Regards,
Terry.
@stevebaer

When adding an object to the document there are no display attributes as those are used during an actual drawing of a frame. You can change the thickness for your object by changing the linetype that the new object references. Here’s a way to set a custom linetype per object.

ON_Linetype lt;
lt.SetWidth(6);
attribs.SetLinetypeSource(ON::object_linetype_source::linetype_from_object);
attribs.SetCustomLinetype(lt);
1 Like

Steve :man_lifting_weights:,

Your suggestion works perfectly :high_brightness:

Thanks for the :rocket:fast solve!

Regards,
Terry :grinning:

Steve,

Here is a related question.

I have a mesh:


I have a mesh containing only the non-planar quads of the mesh above:

These show up fine. But when I combine them, the non-planar quads start to get lost:

I tried this for the mesh’s attributes:

ON_Linetype lt;
lt.SetWidth(12);
attribs.SetLinetypeSource(ON::object_linetype_source::linetype_from_object);
attribs.SetCustomLinetype(lt);
attribs.m_display_order = 100;
CRhinoMeshObject* meshObject = new CRhinoMeshObject(attribs);

But this made no difference. I looked on the Web but have not yet discovered how to do this.

Can you suggest a way to get the non-planar quad mesh to stand out when it is displayed with the full mesh? I do not want to adjust the mesh width using the Document Properties panel as this will affect all meshes.

A brute force way would be to draw all the edges of the non-planar faces using a thick custom linetype and put only these on a layer. This seems primitive but it does work as shown below:

Regards,
Terry.