Turning off layers in detail with Rhinocommon

Hi, I am trying to turn off (hide) layers in a detail viewport using Rhinocommon. I though this would be simply a matter of activating the detail view, then setting Layer.IsVisible = False, then Layer.CommitChanges().

This does not seem to be the case. It seems Layer.IsVisible always refers to the layer’s main visibility settings, never its per-view visibility setting.

How does one do the equivalent of HideLayersInDetail using Rhinocommon?

Thank you!

Hi @carlRTC,

This should do the trick:

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  var view = doc.Views.ActiveView;
  if (null == view)
    return Result.Failure;

  if (!(view is RhinoPageView page_view))
  {
    RhinoApp.WriteLine("The active view is neither a layout nor a detail view.");
    return Result.Failure;
  }

  var layer_index = doc.Layers.FindByFullPath("Default", -1);
  if (layer_index >= 0 && layer_index < doc.Layers.Count && layer_index != doc.Layers.CurrentLayerIndex)
  {
    var layer = doc.Layers[layer_index];
    if (null != layer && layer.IsVisible)
    {
      layer.SetPerViewportVisible(view.ActiveViewportID, false);
      doc.Views.RedrawEnabled = true;
      view.Redraw();
    }
  }

  doc.Views.Redraw();

  return Result.Success;
}

Note, this line, which redraws the Layers pane,

doc.Views.RedrawEnabled = true;

is only needed until this fix is included in an service release.

https://mcneel.myjetbrains.com/youtrack/issue/RH-48584

– Dale

Dale, thank you very much. I failed to mention that, for the time being, we’re still in Rhino 5. So I guess this is not exposed in R5? Would the following be the only way to do it in R5? (I’m using the GH C# component.)

Rhino.RhinoApp.RunScript(“!-_HideLayersInDetail _Layer \”" + layerOff + “\”", false)

… where layerOff is a string containing the layer path.

Thank you!

Correct.

As far as I know, yes.

– Dale

Really we should just get ourselves going on R6! :grinning: Thank you!

Hi @dale ,

I have been referring to your sample code here, but am still having trouble implementing SetPerViewportVisible for multiple detail views on a single page view. I find that only the last detail view activated appears to retain the visibility settings; the previous detail views seem to get reset. Also, confusingly, when I print the PerViewportIsVisible status as a test, everything still appears to be set to True.

I’m using the GH C# component for now; my code is below:

Layer rlayer = doc.Layers.FindName("TO-DRAW");
Layer[] rlayers = rlayer.GetChildren();
RhinoPageView pview = doc.Views.Find("PANEL_01", true) as RhinoPageView;
if(pview == null)
  Print("Error: PageView not found.");

DetailViewObject[] dviews = pview.GetDetailViews();
for(int j = 0; j < dviews.Length; j++)
{
  DetailViewObject dview = dviews[j];
  pview.SetActiveDetail(dview.Id);
  var view = doc.Views.ActiveView;
  Print(view.ActiveViewportID.ToString());

  for(int i = 0; i < rlayers.Length; i++)
  {
    Layer panellayer = rlayers[i];
    if(panellayer.Name == pview.PageName){
      panellayer.SetPerViewportVisible(dview.Id, true);
      doc.Views.RedrawEnabled = true;
      view.Redraw();
      Print("Show: " + panellayer.Name + ": " + panellayer.PerViewportIsVisible(dview.Id));
    }
    else
    {
      panellayer.SetPerViewportVisible(dview.Id, false);
      doc.Views.RedrawEnabled = true;
      view.Redraw();
      Print("Hide: " + panellayer.Name + ": " + panellayer.PerViewportIsVisible(dview.Id));
    }
  }
}

Do you have any recommendations for what I am doing wrong? Thank you!

Hi @gcmartinb,

Here is an equivalent plug-in command that should work.

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  // Find the layer index by full path name
  var layer_index = doc.Layers.FindByFullPath("TO-DRAW", -1);
  if (-1 == layer_index)
    return Result.Cancel;

  // Get the layer object
  var layer = doc.Layers[layer_index];
  if (null == layer)
    return Result.Failure;

  // If the layer is off globally, then there is nothing to do
  if (!layer.IsVisible)
    return Result.Cancel;

  // Find the page view
  var page_view = doc.Views.GetPageViews().First(
    item => item.PageName.Equals("PANEL_01", System.StringComparison.OrdinalIgnoreCase)
    );

  if (null == page_view)
    return Result.Cancel;

  // Process each detail
  foreach (var detail in page_view.GetDetailViews())
  {
    var viewport_id = detail.Viewport.Id;

    // Re-acquire the layer object, as the underlying
    // object may have been modified
    layer = doc.Layers[layer_index];
    if (null != layer)
    {
      // If the layer is visible on the detail, turn it off
      if (layer.PerViewportIsVisible(viewport_id))
      {
        layer.SetPerViewportVisible(viewport_id, false);
        layer.SetPerViewportPersistentVisibility(viewport_id, false);
      }
    }
  }

  // Redraw if needed
  var view = doc.Views.ActiveView;
  if (null != view && view.ActiveViewportID == page_view.ActiveViewportID)
    doc.Views.Redraw();

  return Result.Success;
}

– Dale

1 Like

Hi,

I implemented the script above and it works well for layers that are visible. However, when I try it for a layer which is off in the model view, the per-viewport visibility turns on again once the layer is turned on in the model view.

In other words it seems that “SetPerViewportVisible” and “SetPerViewportPersistentVisibility” do not affect layers which are not visible.

This is quite problematic, because it would be good to set the per-viewport visibility of layers regardless their current state in the model view.

@dale do you have a clue how to solve this ?

Hi @Ludovic,

This is correct.

If you are new to Rhino 8, you might want to review this topic:

If you are using layouts, its best to leave layers visible (Layer.IsVislble) and control their visibility using Layer.ModelIsVisible (for model) and Layer.SetPerViewportVisible (for layouts and details).

– Dale

Hi @Dale, thanks, I didn’t notice that layers can be turned off in model space only.
We will all change our behaviour in our studio, using this new feature and always leaving the global visibility “On”.