Turning off layers in detail with Rhinocommon

layout
rhinocommon
layers
visibility
#1

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!

Hide layers in detail with rhinocommon
(Dale Fugier) #2

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

#3

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!

(Dale Fugier) #4

Correct.

As far as I know, yes.

– Dale

#5

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

(gcmartinb) #7

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!

(Dale Fugier) #8

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