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:

  1. The object’s mode is not set to hidden.
  2. If the object’s layer is not hidden.
  3. 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...
}
}
}