Statically Linking C++ Libraries in Rhino C++ Template

Hi,

I would like to ask if I can statically link .lib libraries to Rhino Plugin C++ Template?

When I try to do this I get this error:

Severity Code Description Project File Line Suppression State
Error LNK2038 mismatch detected for ‘RuntimeLibrary’: value ‘MT_StaticRelease’ doesn’t match value ‘MD_DynamicRelease’ in

Hi @Petras_Vestartas,

There is a lot of info on this if you just Google. Have you tried?

– Dale

This helped to resolve issue:

It seems that every time I encouter error in C++ I am not sure if I resolve it correctly.

I have a second question SDK related.

Is there any sample to pickup a pointcloud object similar to this example?

Hi @Petras_Vestartas,

How about this?

CRhinoGetObject go;
go.SetCommandPrompt(L"Select point clouds");
go.SetGeometryFilter(CRhinoGetObject::pointset_object);
go.GetObjects(1, 0);
if (go.CommandResult() == CRhinoCommand::success)
{
  for (int i = 0; i < go.ObjectCount(); i++)
  {
    const CRhinoPointCloudObject* cloud_obj = CRhinoPointCloudObject::Cast(go.Object(i).Object());
    if (cloud_obj)
    {
      //...
    }
  }
}

– Dale

Thank you @dale this works.

However I have issue with previous question.
By changing Configuration type from dynamic library to static C++ project builds successfully.
But when loading .rhp plugin file to Rhino, Rhino cannot load the .rhp file.

Do you have any recommendations or links how to properly solve the static linking to C++ Rhino Plugin?

I compiled the library to dynamic one and it works, it seems that there is no or I do not know one way that could link static to dynamic project which is a rhino plugin.

@dale

Why this prints 0.0000?

CRhinoGetObject go;
go.SetCommandPrompt(L"Select point clouds");
go.SetGeometryFilter(CRhinoGetObject::pointset_object);
go.GetObjects(1, 1);
if (go.CommandResult() == CRhinoCommand::success) {

    const CRhinoPointCloudObject* cloud_obj =  CRhinoPointCloudObject::Cast(go.Object(0).Object());
    if (cloud_obj) {

         const ON_PointCloud* cloud =
                ON_PointCloud::Cast(cloud_obj->Geometry());

        RhinoApp().Print(L"\n Number of Points Rhino: %f", cloud->m_P.Count());

I don’t know - this seems to work:

CRhinoGetObject go;
go.SetCommandPrompt(L"Select point clouds");
go.SetGeometryFilter(CRhinoGetObject::pointset_object);
go.GetObjects(1, 1);
if (go.CommandResult() == CRhinoCommand::success)
{
  const CRhinoObject* obj = go.Object(0).Object();
  if (nullptr == obj)
    return CRhinoCommand::failure;

  const CRhinoPointCloudObject* cloud_obj = CRhinoPointCloudObject::Cast(obj);
  if (cloud_obj)
  {
    const int count = cloud_obj->PointCloud().PointCount();
    RhinoApp().Print(L"Point cloud point count: %d\n", count);
  }
}

– Dale

1 Like

Thank you this works well, I do not know why I need to declare it outside.

I have a second question @dale .

How can I bake pointcloud that has colors and normals?
The following lines of code just bake a point list without attributes. I see that AddPointCloudObject has attribute option, but I do not know how to write.

        CRhinoPointCloudObject* cloudNew_obj = new CRhinoPointCloudObject();
        cloudNew_obj->SetPointCloud(cloudNew);
        context.m_doc.AddPointCloudObject(cloudNew.m_P.Count(), cloudNew.m_P );
        context.m_doc.Redraw();

Hi @Petras_Vestartas,

Fill in the ON_PointCloud::m_C and ON_PointCloud::m_N arrays. See opennurbs_pointcloud.h for details.

– Dale

1 Like

Dear @Dale thank you for the answers.

I have the arrays m_C and m_N

How can I bake them, because this method only takes m_P input. How can I bake the bake the pointcloud instead of point list?

context.m_doc.AddPointCloudObject(cloudNew.m_P.Count(), cloudNew.m_P );

Right now I am doing it in a weird way:

  1. I add pointcloud without colors or normals

  2. then replace that pointcloud with the one with normals and colors:

     CRhinoPointCloudObject* pointcloudObjectsWithoutColors  = context.m_doc.AddPointCloudObject(cloudNew.m_P.Count(), cloudNew.m_P  );
     CRhinoPointCloudObject* cloudNew_obj = new CRhinoPointCloudObject();
     cloudNew_obj->SetPointCloud(cloudNew);
     context.m_doc.ReplaceObject(CRhinoObjRef(pointcloudObjectsWithoutColors), cloudNew_obj);
     context.m_doc.Redraw();
    

Can I do it in one step?

Hi @Petras_Vestartas,

Does this example help?

CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
  ON_SimpleArray<ON_Color> colors;
  colors.Append(ON_Color::SaturatedRed);
  colors.Append(ON_Color::SaturatedGreen);
  colors.Append(ON_Color::SaturatedBlue);
  colors.Append(ON_Color::SaturatedYellow);
  colors.Append(ON_Color::SaturatedCyan);
  colors.Append(ON_Color::SaturatedMagenta);

  const int rows = colors.Count();
  const int columns = rows;

  ON_3dVector dir = ON_3dVector::ZAxis;

  ON_PointCloud cloud;
  for (int r = 0; r < rows; r++)
  {
    for (int c = 0; c < columns; c++)
    {
      cloud.m_P.Append(ON_3dPoint(r, c, 0.0));
      cloud.m_C.Append(colors[r]);
      cloud.m_N.Append(dir);
    }
  }

  if (cloud.IsValid())
  {
    CRhinoPointCloudObject* cloud_obj = new CRhinoPointCloudObject();
    cloud_obj->SetPointCloud(cloud);
    context.m_doc.AddObject(cloud_obj);
    context.m_doc.Redraw();
  }

  return CRhinoCommand::success;
}

– Dale

Thank you this was I exactly needed.