Set Detail Curve Visibility

Mostly, the Revit API limits an add-in to pretty high-level operations, encapsulating and protecting the parametric BIM from reckless modifications. For the nonce, here is a little bit of nitty-gritty bit manipulation anyway, in a utility method provided by Scott Conover:

Question: Why is there no DetailCurve.SetVisibility method exposed, similar to ModelCurves.SetVisibility?

The UI has this functionality, and I would find very good use for it in reinforcement detailing.

I want to programmatically create a detail family representing a certain rebar shape. The family instance should reflect the visibility states, single line in coarse, double line in fine.

Answer: The ModelCurve.SetVisibility method taking a FamilyElementVisibility argument is available for visibility of curve elements in families when the families are placed. Similarly we have a SymbolicCurve.SetVisibility method. Detail curves don't have the exact same functionality in the UI. Generally, detail curves are visible only in a single view in which they are placed. The access you describe is partially enabled for detail families, however.

Here is a workaround to access this functionality: the visibility settings for the curve are stored in the integer GEOM_VISIBILITY_PARAM built-in parameter as bit flags. You can therefore request the desired display by setting the appropriate bits in that parameter value.

The SetFamilyVisibility method presented below turns off the modes you do not want for visibility. It can be called either from an external command or a macro.

It makes use of a simple selection filter to restrict the user selection to detail curves:

class DetailCurveSelectionFilter : ISelectionFilter
{
  public bool AllowElement( Element e )
  {
    CurveElementFilter filter
      = new CurveElementFilter(
        CurveElementType.DetailCurve );
 
    return filter.PassesFilter( e );
  }
 
  public bool AllowReference( Reference r, XYZ p )
  {
    return false;
  }
}

Here is the method implementation itself:

public void SetFamilyVisibility( UIDocument uidoc )
{
  Document doc = uidoc.Document;
 
  Reference r = uidoc.Selection.PickObject(
    ObjectType.Element,
    new DetailCurveSelectionFilter(),
    "Select detail curve" );
 
  Element elem = doc.GetElement( r );
 
  Parameter visParam = elem.get_Parameter(
    BuiltInParameter.GEOM_VISIBILITY_PARAM );
 
  int vis = visParam.AsInteger();
 
  using( Transaction t = new Transaction( doc ) )
  {
    t.Start( "Set curve visibility" );
 
    // Turn off the bit corresponding
    // to the unwanted modes
 
    vis = vis & ~( 1 << 13 ); // Coarse
    //vis = vis & ~(1 << 14); // Medium
    //vis = vis & ~(1 << 15); // Fine
 
    visParam.Set( vis );
 
    t.Commit();
  }
}

Remember that all three modes cannot be turned off simultaneously – a posted error will result.

Here is SetDetailCurveVisibility.zip containing the complete source code, Visual Studio solution and add-in manifest for an external command implementation of this.

Many thanks to Scott for this tricky hint!