Hi @dale ,
Your code works great.
If I want to change the CRhinoObject in segments list to ON_NurbsCurve but don’t want to use context.m_doc.AddObject(), how can I do?
for (int i = 0; i < segment_count; i++)
{
if (nullptr != segments[i])
{
CRhinoObjRef ref1(segments[i]->Id());
ON_NurbsCurve* nurbs = ref1.Curve()->NurbsCurve();
}
}
/// <summary>
/// Gets the sub-curves of a Rhino curve object.
/// </summary>
/// <param name="curve_obj">The curve object.</param>
/// <param name="bIncludeSingle">
/// If true and the curve does not have sub-curves, then
/// add a copy of the input curve to the output array.
/// If false and the curve does not have sub-curves, the
/// do nothing.
/// </param>
/// <param name="sub_curves">The output curve array.</param>
/// <returns>The number of curves added to the output curve array.</returns>
/// <remarks>
/// CRITICAL: Memory for the curves in the output array is allocated and
/// becomes the responsibility of the caller.
/// </remarks>
int RhinoGetSubCurves(
const CRhinoCurveObject* curve_obj,
bool bIncludeSingle,
ON_SimpleArray<ON_Curve*>& sub_curves
)
{
const int sub_curve_count = sub_curves.Count();
if (nullptr != curve_obj)
{
ON_SimpleArray<CRhinoObject*> sub_objects;
const int sub_object_count = curve_obj->GetSubObjects(sub_objects);
if (sub_object_count > 0)
{
for (int i = 0; i < sub_object_count; i++)
{
CRhinoCurveObject* sub_curve_obj = CRhinoCurveObject::Cast(sub_objects[i]);
if (nullptr == sub_curve_obj)
continue;
const ON_Curve* sub_curve = sub_curve_obj->Curve();
if (nullptr != sub_curve)
{
ON_Curve* duplicate = sub_curve->DuplicateCurve();
if (nullptr != duplicate)
sub_curves.Append(duplicate);
}
delete sub_objects[i]; // Don't leak...
sub_objects[i] = nullptr;
}
}
else if (bIncludeSingle)
{
const ON_Curve* curve = curve_obj->Curve();
if (nullptr != curve)
{
ON_Curve* duplicate = curve->DuplicateCurve();
if (nullptr != duplicate)
sub_curves.Append(duplicate);
}
}
}
// Return number added
return sub_curves.Count() - sub_curve_count;
}
You can use it like this:
CRhinoCommand::result CCommandTest::RunCommand(const CRhinoCommandContext& context)
{
CRhinoGetObject go;
go.SetCommandPrompt(L"Select curve to explode");
go.SetGeometryFilter(CRhinoGetObject::curve_object);
go.EnableSubObjectSelect(FALSE);
go.EnableGroupSelect(FALSE);
go.GetObjects(1, 1);
if (go.CommandResult() != CRhinoCommand::success)
return CRhinoCommand::success;
const CRhinoObjRef& objref = go.Object(0);
const CRhinoCurveObject* curve_obj = CRhinoCurveObject::Cast(objref.Object());
if (nullptr == curve_obj)
return CRhinoCommand::failure;
ON_SimpleArray<ON_Curve*> sub_curves;
const int sub_curve_count = RhinoGetSubCurves(curve_obj, false, sub_curves);
if (sub_curve_count > 0)
{
for (int i = 0; i < sub_curve_count; i++)
{
ON_Curve* sub_curve = sub_curves[i];
if (nullptr != sub_curve)
{
CRhinoCurveObject* sub_curve_obj = new CRhinoCurveObject();
sub_curve_obj->SetCurve(sub_curve);
sub_curves[i] = nullptr;
context.m_doc.AddObject(sub_curve_obj);
}
}
context.m_doc.DeleteObject(objref);
RhinoApp().Print("Exploded curve into %d segments.\n", sub_curve_count);
}
else
{
RhinoApp().Print("Cannot explode curve.\n");
}
context.m_doc.Redraw();
return CRhinoCommand::success;
}