ONX_ModelComponentIterator::NextComponent() prematurely returns nullptr

I use the equivalent of the code below to iterate through layers, and when I identify a layer of interest, then iterate through model geometry components looking for those that match the layer index, and when I find one, if it is an ON_Brep, I then create a new ON_Brep and add it to the layer.

The problem is when I add the new ON_Brep, the next call to my layer component iterator returns nullptr, and so I exit the loop prior to when I expect (that is, exit prior to iterating through all the layers). Is this a bug?

I haven’t investigated whether this also occurs for the next call to my model geometry iterator, mainly because in my layers of interest there is only one ON_Brep of interest, so only the problem with my layer component iterator is explicitly observable.

My code is effectively this:

	ONX_ModelComponentIterator it_layer(geometry_model_, ON_ModelComponent::Type::Layer);
	for (const ON_Layer* layer = ON_Layer::Cast(it_layer.FirstComponent()); nullptr != layer; layer = ON_Layer::Cast(it_layer.NextComponent()))
	{
		if (layer->IsVisible() && (isFractureBody(ON_String(layer->Name()).Array())))  // only consider visible layers that are fractures
		{
			ONX_ModelComponentIterator it_modelgeometry(geometry_model_, ON_ModelComponent::Type::ModelGeometry);
			for (const ON_ModelComponent* model_component = it_modelgeometry.FirstComponent(); nullptr != model_component; model_component = it_modelgeometry.NextComponent())
			{
				const ON_ModelGeometryComponent* model_geometry = ON_ModelGeometryComponent::Cast(model_component);
				if (model_geometry->Attributes(nullptr)->m_layer_index == layer->Index())
				{
					const ON_Brep* brep_frac = ON_Brep::Cast(model_geometry->Geometry(nullptr));
					if (brep_frac != nullptr)
					{
						// create geometry object then add it to layer using:
						ON_3dmObjectAttributes* attributes = new ON_3dmObjectAttributes();
						attributes->m_layer_index = layer->Index();
						bool rc = !geometry_model_.AddManagedModelGeometryComponent(geometry_object, attributes).IsEmpty();
					}
				}
			}
		}
	}

Iterators generally become invalid when changing the document (in pretty much any language). You need to separate the iterating and the modification by recording in say a list the layer IDs you need to add your object to, then outside your iterator usage go over the data collected and do the adding.

1 Like

Thanks, Nathan.