Testing for Object Visibility
Question
I have created a sample model this has a parent layer and a sublayer. If I add objects to each of these two layer and then turn off the parent layer in Rhino, the objects on both layers do not appear. But, when I read the .3dm file using openNURBS, the objects on the sublayer report as being visible. How can I correctly detect the visibility of an object?
Answer
A Rhino object is considered visible if:
- The object’s mode is not set to hidden.
- If the object’s layer is not hidden.
- If the object’s layer does not have a parent layer that is hidden.
Example
The following example code can be used to detect an object’s true visibility when using the openNURBS toolkit:
static bool IsLayerVisible(const ONX_Model& model, ON_UUID layer_id) { bool rc = false; const ON_ModelComponentReference& model_component_ref = model.ComponentFromId(ON_ModelComponent::Type::Layer, layer_id); if (!model_component_ref.IsEmpty()) { const ON_Layer* layer = ON_Layer::Cast(model_component_ref.ModelComponent()); if (nullptr != layer) { rc = layer->IsVisible(); if (rc && layer->ParentIdIsNotNil()) return IsLayerVisible(model, layer->ParentId()); } } return rc; } static bool IsLayerVisible(const ONX_Model& model, int layer_index) { bool rc = false; const ON_ModelComponentReference& model_component_ref = model.ComponentFromIndex(ON_ModelComponent::Type::Layer, layer_index); if (!model_component_ref.IsEmpty()) { const ON_Layer* layer = ON_Layer::Cast(model_component_ref.ModelComponent()); if (nullptr != layer) { rc = layer->IsVisible(); if (rc && layer->ParentIdIsNotNil()) return IsLayerVisible(model, layer->ParentId()); } } return rc; } static bool IsModelGeometryVisible(const ONX_Model& model, const ON_ModelGeometryComponent* model_geometry) { bool rc = false; if (nullptr != model_geometry) { const ON_3dmObjectAttributes* attributes = model_geometry->Attributes(nullptr); if (nullptr != attributes) { switch (attributes->Mode()) { case ON::normal_object: case ON::idef_object: case ON::locked_object: rc = IsLayerVisible(model, attributes->m_layer_index); break; } } } return rc; }
You can test the above static functions by adding the following sample code to the Example_Read project included with the openNURBS toolkit:
ONX_Model model = ...; ONX_ModelComponentIterator it(model, ON_ModelComponent::Type::ModelGeometry); const ON_ModelComponent* model_component = nullptr; for (model_component = it.FirstComponent(); nullptr != model_component; model_component = it.NextComponent()) { const ON_ModelGeometryComponent* model_geometry = ON_ModelGeometryComponent::Cast(model_component); if (nullptr != model_geometry) { bool bVisible = IsModelGeometryVisible(model, model_geometry); if (bVisible) { // TODO... } } }