Question: I’ve written the following function, which appends a point to an existing Rhino point cloud object:
bool AppendToRhinoPointCloudObject(
unsigned int doc_runtime_sn,
unsigned int obj_runtime_sn,
double x, double y, double z
)
{
bool rc = false;
const CRhinoObject* obj = CRhinoObject::FromRuntimeSerialNumber(doc_runtime_sn, obj_runtime_sn);
if (nullptr != obj)
{
const CRhinoPointCloudObject* pcObject = CRhinoPointCloudObject::Cast(obj);
if (nullptr != pcObject)
{
const ON_PointCloud& pc = pcObject->PointCloud();
pc.m_P.Append(ON_3dPoint(x, y, z)); // Add
rc = true;
}
}
return rc;
}
However, when I build the project, I am getting the following compiler error:
error C2663: 'ON_SimpleArray<ON_3dPoint>::Append': 2 overloads have no legal conversion for 'this' pointer
Answer: Rhino documents are constant. That is, they cannot be directly modified.
The process for modifying a document object is:
1.) Get the Rhino object.
2.) Make a copy of the Rhino object’s geometry.
3.) Modify the copy of the geometry.
4.) Modify the Rhino object, to use the new geometry, by calling CRhinoDoc::ReplaceObject
.
Here is how you might consider modifying the above function:
unsigned int AppendToRhinoPointCloudObject(
unsigned int doc_runtime_sn,
unsigned int obj_runtime_sn,
double x, double y, double z
)
{
unsigned int rc = 0;
ON_3dPoint point(x, y, z);
if (!point.IsValid())
return rc;
CRhinoDoc* doc = CRhinoDoc::FromRuntimeSerialNumber(doc_runtime_sn);
if (nullptr == doc)
return rc;
const CRhinoObject* obj = doc->LookupObjectByRuntimeSerialNumber(obj_runtime_sn);
if (nullptr == obj)
return rc;
const ON_PointCloud* pc_old = ON_PointCloud::Cast(obj->Geometry());
if (nullptr == pc_old)
return rc;
const bool bHasPointColors = pc_old->HasPointColors();
const bool bHasPointNormals = pc_old->HasPointNormals();
ON_PointCloud pc_new(*pc_old); // Copy
pc_new.m_P.Append(point); // Add
if (bHasPointColors)
{
if (obj->Attributes().ColorSource() == ON::color_from_object)
{
pc_new.m_C.Append(obj->Attributes().m_color);
}
else
{
ON_3dmObjectAttributes def_attr;
doc->GetDefaultObjectAttributes(def_attr);
pc_new.m_C.Append(def_attr.m_color);
}
}
if (bHasPointNormals)
pc_new.m_N.Append(ON_3dVector::UnsetVector);
CRhinoPointCloudObject* pc_new_obj = new CRhinoPointCloudObject();
pc_new_obj->SetPointCloud(pc_new);
bool res = doc->ReplaceObject(CRhinoObjRef(obj), pc_new_obj);
if (res)
rc = pc_new_obj->RuntimeSerialNumber(); // Return replacement object runtime serial number
else
delete pc_new_obj; // Don't leak
return rc;
}
Hope this helps.
– Dale