Liu2
(Liu)
March 26, 2024, 9:35am
1
Hi.
I want to store a bunch of user selected object. but those properties confused me.
What’s the difference between them?
CRhinoGetObject getObjs;
getCrvs.GetObjects(1, 0);
if (getCrvs.CommandResult() != CRhinoCommand::success)
return;
for (int i = 0; i < getCrvs.ObjectCount(); i++) {
const CRhinoObject* pObj = getCrvs.Object(0).Object();
pObj->Id();
pObj->ModelObjectId();
pObj->RuntimeSerialNumber();
// store selected object
// ...
}
dale
(Dale Fugier)
March 26, 2024, 4:14pm
2
Hi @Liu2 ,
It is best to track Rhino objects by their unique GUID, which is persistent for the life of the object.
An object’s runtime serial number is used to identify instance of an object. For example, when you move an object, the old one is pushed onto the undo stack and a new one added to the document. In this case, the GUID is the same for both objects, but the runtime serial numbers will be different.
Note, there are several way to get an object’s GUID. Choose the one that best works for you.
To retrieve a Rhino object by it’s GUID, use CRhinoDoc::LookupObject
.
CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
CRhinoGetObject go;
go.SetCommandPrompt(L"Select object");
go.EnableSubObjectSelect(false);
go.GetObjects(1, 1);
if (go.CommandResult() != CRhinoCommand::success)
return go.CommandResult();
const CRhinoObjRef& objref = go.Object(0);
const CRhinoObject* pObj = objref.Object();
if (nullptr == pObj)
return CRhinoCommand::failure;
ON_wString str;
ON_UUID uuid;
uuid = pObj->Id();
ON_UuidToString(uuid, str);
RhinoApp().Print(L"CRhinoObject::Id: %ls\n", static_cast<const wchar_t*>(str));
uuid = pObj->ModelObjectId();
ON_UuidToString(uuid, str);
RhinoApp().Print(L"CRhinoObject::ModelObjectId: %ls\n", static_cast<const wchar_t*>(str));
uuid = pObj->Attributes().m_uuid;
ON_UuidToString(uuid, str);
RhinoApp().Print(L"CRhinoObject::Attributes::m_uuid: %ls\n", static_cast<const wchar_t*>(str));
unsigned int sn = pObj->RuntimeSerialNumber();
RhinoApp().Print(L"CRhinoObject::RuntimeSerialNumber: %u\n", sn);
const CRhinoObject* pLookup = context.m_doc.LookupObject(uuid);
if (nullptr != pLookup)
{
// TODO...
}
return CRhinoCommand::success;
}
– Dale
Liu2
(Liu)
March 27, 2024, 8:29am
3
Thanks Dale, It helps a lot
Liu2
(Liu)
March 28, 2024, 8:57am
4
Hi Dale.
I use uuid to track objects now.
but It failed when I want to cast the objects to origin.
const CRhinoObject* pLookup = CRhinoCurveObject::FromId(RhinoApp().ActiveDoc()->RuntimeSerialNumber(), uuid);
if(nullptr != pLookup){
// cast failed
const ON_Curve* curve = ON_Curve::Cast(pLookup->Geometry());
}
Liu2
(Liu)
March 28, 2024, 2:57pm
5
Hi @dale ,
After a testing,
I found that when I set curve_object
filter, the surface boundary still could be selected, which leads to the ON_Curve
casting failed.
CRhinoGetObject go;
go.SetGeometryFilter(CRhinoGetObject::curve_object);
// selected ...
// ...
const CRhinoObject* pLookup = CRhinoCurveObject::FromId(RhinoApp().ActiveDoc()->RuntimeSerialNumber(), m_SelectedCurves[i].m_ID);
if (nullptr != pLookup) {
CRhinoObjRef objRef(pLookup);
// casting failed
const ON_Curve* curve = objRef.Curve();
}
and those curves(top circle, bottom circle, vertical curve. see picture below) shared a common uuid.
// result returns 0
int result = ON_UuidCompare(topCircleID, bottomCircleID);
dale
(Dale Fugier)
March 28, 2024, 3:33pm
6
Hi @Liu2 ,
Please review the attached and let me know if you have any questions.
cmdTestLiu.cpp (3.7 KB)
– Dale
Liu2
(Liu)
March 29, 2024, 2:32am
7
Thank you @dale .
Through your code example, I can correctly store UUID of the curves.
// select curves
CRhinoGetObject go;
go.SetCommandPrompt(L"Select curves");
go.EnablePreSelect(FALSE);
go.SetGeometryFilter(CRhinoGetObject::curve_object);
go.GetObjects(1, 0);
if (go.CommandResult() != CRhinoCommand::success)
return;
std::vector<UUID> uuidList;
for (int i = 0; i < go.ObjectCount(); i++) {
const CRhinoObject* pObj = go.Object(i).Object();
// Dealing with non-curve situation
const CRhinoCurveObject* pCurveObj = CRhinoCurveObject::Cast(pObj);
if (nullptr == pCurveObj)
{
RhinoApp().Print(L"Selected object %d is not a curve but a %ls\n", i, pObj->ShortDescription(false));
continue;
}
uuidList.push_back(pObj->Id());
}
But I still have a question:
Why can I select the boundary of the surface even after setting go.SetGeometryFilter(CRhinoGetObject::curve_object)
?
The code below shows the selected object of the picture above is a surface.
RhinoApp().Print(L"CRhinoObject::ObjectType: %ls\n", pRhinoObj->ShortDescription(false));
dale
(Dale Fugier)
March 29, 2024, 2:56pm
8
Hi @Liu2 ,
If you do not want to select edge curves, then add this line of code to your getter:
go.EnableSubObjectSelect(false);
– Dale
dale
(Dale Fugier)
Split this topic
April 3, 2024, 3:09pm
9
2 posts were split to a new topic: Persistent GUID of ON_Brep objects