C++ Selecting multiple curve, some of them are not valid

Hi,

I would like to ask how to retrieve multiple curves, and append to C++ collection only valid ones.
Essentially my simple question is what Collection type I should use to add valid curves when I do not know the fixed length of collection?

Second question: to retrieve all selected objects I have to write:
go.GetObjects(0, -1); ?

For example here I retrieve curve objects from rhino and if they are valid I would like to add them to a collection.

CRhinoGetObject go;
go.SetCommandPrompt(L"Select Curves");
go.SetGeometryFilter(CRhinoGetObject::curve_object);
go.GetObjects(0, -1);


if (go.CommandResult() != CRhinoCommand::success)
	return go.CommandResult();

//What kind of collection I should declare here <---------
   
for (int i = 0; i < go.ObjectCount(); i++) {

	//Get first object + validate
	const ON_Curve* crv = go.Object(0).Curve();
	if (crv == 0) {
		return CRhinoCommand::failure;
	}
	else {
		//Question---------> add to curve list;
	}
}

Hi @Petras_Vestartas,

Something like this?

CRhinoGetObject go;
go.SetCommandPrompt(L"Select curves");
go.SetGeometryFilter(CRhinoGetObject::curve_object);
go.EnableSubObjectSelect(FALSE);
go.GetObjects(1, 0);
if (go.CommandResult() != CRhinoCommand::success)
  return go.CommandResult();

const int object_count = go.ObjectCount();
ON_SimpleArray<const ON_Curve*> curve_list(object_count);

for (int i = 0; i < object_count; i++)
{
  const ON_Curve* crv = go.Object(i).Curve();
  if (nullptr == crv)
    return CRhinoCommand::failure;

  if (crv->IsValid())
    curve_list.Append(crv);
}

const int curve_count = curve_list.Count();
for (int i = 0; i < curve_count; i++)
{
  const ON_Curve* crv = curve_list[i];
  if (nullptr == crv)
    continue; // should never get here...

  // TODO...
}

– Dale

Dear Dale,

Thank you very much. I see in most examples using this ON_SimpleArray
What is normally used in C++ (in wider context without Rhino) when you do not know exactly the length of collection?

Hi @Petras_Vestartas,

The Rhino SDK had three different dynamic, template array classes:

1.) ON_SimpleArray<> - For use with simple data types (e.g. bool, int, double, etc.), pointers, and classes that do not have explicit construction, destruction, and copy operators.

For example:

ON_SimpleArray<double> parameters;
ON_SimpleArray<const ON_Curve*> curves;
ON_SimpleArray<ON_3dPoint> points;

2.) ON_ClassArray<> - For use with classes that require non-trivial construction or destruction. Any class used with the ON_ClassArray<> template must have a robust operator=().

For example:

ON_ClassArray<ON_wString> strings;
ON_ClassArray<CRhinoObjRef> objects;

3.) ON_ObjectArrray<> - For use with class that are derived from ON_Object.

For example:

ON_ObjectArray<ON_NurbsCurve> nurbs_curves;
ON_ObjectArray<ON_Layer> layers;

– Dale

1 Like

What is normally used in C++ (in wider context without Rhino) when you do not know exactly the length of collection?

Take a look at the Standard Template Library (STL), that is included with every C++ compiler. It contains a list-like collection called vector<T>, but also more complex collections like set, map etc.

https://en.cppreference.com/w/cpp/container

These also define so-called iterator objects, so you can easily iterate their contents:

std::vector<int> numbers;
numbers.push_back(1);
numbers.push_back(2);
for(std::vector<int>::const_iterator it = numbers.begin(); it != numbers.end(); ++it)
{
  const int& number = *it;
}

//modern cpp also has range-for loop syntax:
for (auto& number : numbers)
{

}
1 Like