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...
}
}
}