Snap with dynamo

Hello ,
i have a direct shape elements in Revit which i cannot snap to or put dimensions on them , is there a way with dynamo to resolve this issue ? so i can maybe recreate those elements to dimension them
Thank you for any help

Likely, yes you can find a way to do this. How will depend on the direct shape itself, and a number of other contextual factors which you haven’t provided so I can’t help with specifics.

I do recommend revisiting the workflow which created the direct shapes in the first place though, as that is likely going to continue to cause more and more issues over time.

1 Like

hello Jacob,
Thanks for your reply , i attached the revit file .as you will see in the revit file i cannot snap to any element and they are all imported as generic model, i want to become able to snap to them or recreate them as revit native element . is it possible to recreate them or at least be able to snap to them? Thank you

How did you make the direct shapes to begin with?

I would say as Jacob…becourse i guess if it direct shape the geometry will be mesh…probably spring mesh tools can help…havent tried :wink: know it isnt dynamo but probably speckle could help

but you could try something here and you should be able to create dimension…but keep in mind the run will take some time, so take a cup coffee and will probably sometimes crash as well…so not the best :wink:

3 Likes

it was exported from navisworks to speckle and then from speckle to Revit , is there a way if i have an ifc in navisworks that i convert it to native revit elements? through dynamo or rhino

Hello Søren you are always the master thanks alot it works

1 Like

Anything is possible, but the root cause of the workflow is the IFC in Navisworks. Instead of IFC > Navis go from IFC into Revit directly, as it’s own model and link into your design model.

2 Likes

Hi,
for info, there are some API methods to add References geometries to DirectShape

Here an example with AddReferenceCurve ,

the process takes a little while because I’ve merged some MeshTriangles to remove the diagonal lines from the Mesh. with PolySurfaces.UnconnectedBoundaries()

import clr
import sys
import System
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS

clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)

#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB

#import transactionManager and DocumentManager (RevitServices is specific to Dynamo)
clr.AddReference('RevitServices')
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument

import itertools

def normalTriangle(tri):
    pt0, pt1, pt2 = [tri.get_Vertex(i) for i in range(3)]
    vec1 = pt1.Subtract(pt0) #XYZ.Subtract
    vec2 = pt2.Subtract(pt0)
    normal = vec1.CrossProduct( vec2 )
    return normal.Normalize()
    
def group_coplanar_triangles(lst_tri, n=0):
    if n == 2000 or len(lst_tri) == 0: 
        return []
    group = [lst_tri.pop(0)]
    group_normal = normalTriangle(group[0])
    while True:
        init_len = len(group)
        for idx, tri in enumerate(lst_tri):
            if group_normal.IsAlmostEqualTo(normalTriangle(tri)):
                group.append(lst_tri.pop(idx))
                break
        if len(group) == init_len:
            break
    return [group] + group_coplanar_triangles(lst_tri, n + 1 )

def get_geometry_curve(elem):
    global opts
    curves = []
    for geo in elem.get_Geometry(opts):
        if isinstance(geo, DB.Mesh) :
            lst_triangles = []
            for idxA in range(geo.NumTriangles):
                tri = geo.get_Triangle(idxA)
                lst_triangles.append(tri)
            # group coplanar triangles 
            for grp_tri in group_coplanar_triangles(lst_triangles):
                lst_surfaces = []
                for sub_tri in grp_tri:
                    lst_ds_pts = [sub_tri.get_Vertex(i).ToPoint() for i in range(3)]
                    ds_surface = DS.Surface.ByPerimeterPoints(lst_ds_pts)
                    lst_surfaces.append(ds_surface)
                polysurface = DS.PolySurface.ByJoinedSurfaces(lst_surfaces)
                try:
                    boundaries = polysurface.UnconnectedBoundaries()
                except:
                    boundaries = []
                curves.extend(boundaries)
                # dispose geometries
                polysurface.Dispose()
                for x in lst_surfaces : x.Dispose()
        elif isinstance(geo, DB.Curve):
            return []
    return curves
    

def toList(x):
    if isinstance(x, (list, dict)) or \
            (hasattr(x, "GetType") and x.GetType().GetInterface("ICollection") is not None):
        return x
    else : return [x]

#Preparing input from dynamo to revit
lstelems = toList(UnwrapElement(IN[0]))
opts = Options()
geometries = []
errors = []
#Do some action in a Transaction
TransactionManager.Instance.EnsureInTransaction(doc)

for e in lstelems:
    if isinstance(e, DB.DirectShape):
        for ds_polycurve in get_geometry_curve(e):
            for ds_curve in ds_polycurve.Curves():
                try:
                    e.AddReferenceCurve(ds_curve.ToRevitType())
                    geometries.append(ds_curve)
                except Exception as ex:
                    errors.append(ex)

TransactionManager.Instance.TransactionTaskDone()
    
OUT = geometries
2 Likes

so cool as always :wink: I would bassicly try avoid that situaton, if it ifc just import :slight_smile:

1 Like