HiddenLineDrawing.Compute with Blocks

@rajaa I am working along the below example to implement a custom version of HiddenLineDrawing.Compute.

Relevant part of example code:

    //add objects to hld_param
    foreach (var obj_ref in _obj_refs)
    {
      var obj = obj_ref.Object();
      _hld_params.AddGeometry(obj.Geometry, Transform.Identity, obj.Id);
    }

I am not able to add blocks or any other custom objects (VisualArq objects) to the HDL parameters. AddGeometry() returns null when trying to do so. How would I go about to add those? I assume I have to get to their geometry or is there a faster way?

Please find a demo script and test file below.

import Rhino.Geometry as rhg
import scriptcontext as sc
import rhinoscriptsyntax as rs


def test_hidden_line():
    viewport = sc.doc.Views.ActiveView.ActiveViewport
    
    # Setup HLD parameters
    parameters = rhg.HiddenLineDrawingParameters()
    parameters.AbsoluteTolerance = sc.doc.ModelAbsoluteTolerance
    parameters.IncludeHiddenCurves = False
    parameters.IncludeTangentEdges = False
    parameters.IncludeTangentSeams = False
    parameters.SetViewport(viewport)
    
    # Process all of the document objects
    rh_obj_guids  = rs.AllObjects(include_references=True)
    not_added = []
    added = []
    for obj_guid in rh_obj_guids:
        rh_obj = rs.coercerhinoobject(obj_guid)
        res = parameters.AddGeometry(rh_obj.Geometry, rh_obj.Id)
        if res:
            added.append(obj_guid)
        else:
            not_added.append(obj_guid)
    
    # DEBUG: Objects not added are selected <--------------- Blocks are ignored
    rs.UnselectAllObjects()
    rs.SelectObjects(not_added)
    
    # Create the hidden line drawing geometry
    hld = rhg.HiddenLineDrawing.Compute(parameters, True)
    
    # Add hidden line drawing to doc
    flatten = rhg.Transform.PlanarProjection(rhg.Plane.WorldXY)
    page_box = hld.BoundingBox(True)
    delta2D = rhg.Vector2d(0, 0)
    delta2D = delta2D - rhg.Vector2d(page_box.Min.X, page_box.Min.Y)
    delta3D = rhg.Transform.Translation(rhg.Vector3d(delta2D.X, delta2D.Y, 0.0))
    flatten = delta3D * flatten
    
    attributes = sc.doc.CreateDefaultAttributes()
    crvs = []
    for hld_curve in hld.Segments:
        if (hld_curve is None 
            or hld_curve.ParentCurve is None 
            or hld_curve.ParentCurve.SilhouetteType == rhg.SilhouetteType.None):
            continue
        crv = hld_curve.CurveGeometry.DuplicateCurve()
        if crv:
            crv.Transform(flatten)
            if hld_curve.SegmentVisibility == rhg.HiddenLineDrawingSegment.Visibility.Visible:
                if hld_curve.ParentCurve.SilhouetteType == rhg.SilhouetteType.SectionCut:
                    sc.doc.Objects.AddCurve(crv, attributes)
                else:
                    sc.doc.Objects.AddCurve(crv, attributes)
            elif hld_curve.SegmentVisibility == rhg.HiddenLineDrawingSegment.Visibility.Hidden:
                if hld_curve.ParentCurve.SilhouetteType == rhg.SilhouetteType.SectionCut:
                    sc.doc.Objects.AddCurve(crv, attributes)
                else:
                    sc.doc.Objects.AddCurve(crv, attributes);


test_hidden_line()

HiddenLineTest.3dm (5.4 MB)

Thanks for your help!

@rajaa - can you have a look at this?

@dale @rajaa Dear both, we started to process objects according to their type.

    # Process all of the document objects
    for obj_guid in rh_obj_guids:
        rh_obj = rs.coercerhinoobject(obj_guid)
        if rh_obj.Geometry.HasBrepForm:
            parameters.AddGeometry(rhg.Brep.TryConvertBrep(rh_obj.Geometry), rh_obj.Id)
        elif type(rh_obj) is rhc.DocObjects.CurveObject:
            parameters.AddGeometry(rh_obj.CurveGeometry, rh_obj.Id)
        elif type(rh_obj) is rhc.DocObjects.MeshObject:
            parameters.AddGeometry(rh_obj.MeshGeometry, rh_obj.Id)
        elif type(rh_obj) is rhc.DocObjects.InstanceObject:
            instance_geo = deconstruct_instance(rh_obj) 
            for g in instance_geo:
                # sc.doc.Objects.Add(g, sc.doc.CreateDefaultAttributes()) # DEBUG: Add ref objs to doc
                parameters.AddGeometry(g, rh_obj.Id)
        else:
            print('Type {0} not supported'.format(type(rh_obj)))

The function deconstruct_instance(rh_obj) is a Python implementation of Dale’s example here: rhino-developer-samples/rhinocommon/cs/SampleCsCommands/SampleCsExplodeBlock.cs at 7 · mcneel/rhino-developer-samples · GitHub

I am wondering if the SDK already contains functionality for what we would like to achieve or if the Make2D C# code is available on Github and could be forked?

What we eventually would like to achieve:

  1. Assign hidden lines derived from blocks according to the block’s instance layer (not the objects’ layer). Because we have many blocks where the block geometry is on layer “0” and the object’s properties are set to “ByParent” for them to change according to the instance’s layer.
  2. Transfer Attribute User Text from objects and block instances to the hidden lines.
  3. Apply custom post processing to HLD curves.
  4. Store a Guid reference to the original object (Register with previous is not working correctly, stores Guids that do not exist in the document).
  5. Fix some bugs with nested blocks. Please see: Bug Make2D Nested Blocks Text with Text Field Formula and Make2D layer Panel Refresh Loop

You will need to explode the block instance and add its objects to the HLD parameter. You can do something like the following:

          //Explode the block
          RhinoObject[] pieces;
          ObjectAttributes[] piece_attributes;
          Transform[] piece_transforms;
          instance.Explode(true, out pieces, out piece_attributes, out piece_transforms);

          //add exploded piece to list of objects
          for (var j = 0; j < pieces.Length; j++)
          ...

@rajaa Thanks for your reply. We resolved the block question already with the adaption of Dale’s function.

May I add a wish. It would be great if parameters.AddGeometry() would accept any type of object including blocks.

Thanks