Hi all!
I created a script where you select the column and the grid and it is supposed to create a dimension line between them. Problem is: dimension element is created but does not show in the screen.
project - AutoDimension.rvt (6.8 MB)
I created a python script that gets the columns center lines (right/left and front/back), selects the reference that is parallel to the grid and then creates the dimension between them. The line for creating the dimension in the NewDimension is created as part of the script.
the IsParallel node shows that the grid and the selected reference are parallel, that is how the reference line was selected but when I make a dot product between their vectors it isn’t a round 0 (there is a e to the power of -8)
I am adding the revit file which is a simple plan with a few columns and a few grid lines, and adding the dynamo script.
I’ll appreciate any take on the issue!
Reference - Family Instance For Dynamo_Forum.dyn (98.7 KB)
Python node named ‘Get Center Reference And Matching Reference Direction’ requires these imports
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
I would check your references are parallel
Useful resource from Aussie BIM Guru here → Automated Revit dimensioning using Dynamo!
I get the column’s center line references in both directions. Below is the folowing code for it.
I just used the script to select two columns, find their parallel references and it created a dimension between them. Therefore, my assumption is that the issue is that the angle between the grid and the column isn’t exact to the dot despite the node “IsParallel” being true but would like to hear if anyone finds a different issue and a work around for it.
Also no issue with same script when selecting two parallel grid lines - it creates a dimension line between them.
Here is the code for getting the center references:
import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import Reference
# Unwrap the FamilyInstance (input from Dynamo)
fam = UnwrapElement(IN[0])
# Initialize lists to store the references and directions
references = []
directions = []
# Get the center reference for "Center (Left/Right)" and "Center (Front/Back)"
left_right_ref = fam.GetReferenceByName("Center (Left/Right)")
front_back_ref = fam.GetReferenceByName("Center (Front/Back)")
if left_right_ref and front_back_ref:
# Get the transform matrix of the FamilyInstance
transform = fam.GetTransform()
# Left/Right direction (BasisX for Left/Right)
left_right_direction = transform.BasisX # BasisX for left/right axis
# Front/Back direction (BasisY for Front/Back)
front_back_direction = transform.BasisY # BasisY for front/back axis
# Append the references and their corresponding directions to the lists
references.append(left_right_ref)
references.append(front_back_ref)
directions.append(left_right_direction.ToVector())
directions.append(front_back_direction.ToVector())
# Output the references and directions as separate lists
OUT = (references, directions)
It is selecting the reference based on the returned bool of the IsParallel node.
Hi,
try to reduce the number of nodes if possible, here is a solution for only one column at input, based on intersection of grids
import clr
import sys
import System
#
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *
import Autodesk.DesignScript.Geometry as DS
#import Revit API
clr.AddReference('RevitAPI')
import Autodesk
from Autodesk.Revit.DB import *
import Autodesk.Revit.DB as DB
clr.AddReference('RevitNodes')
import Revit
clr.ImportExtensions(Revit.GeometryConversion)
#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 get_grids_intersections():
"""find all intersection of grids"""
data = []
grids = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Grids).WhereElementIsNotElementType().ToElements()
for gd_a, gd_b in itertools.combinations_with_replacement(grids, 2):
resultArray = IntersectionResultArray()
setComparisonResult, resultArray = gd_a.Curve.Intersect(gd_b.Curve, resultArray)
if setComparisonResult == SetComparisonResult.Overlap:
data.append([gd_a, gd_b, resultArray.get_Item(0).XYZPoint ])
return data
def create_dimension(column, grid, offset=3):
"""create dimension beetween column Reference and the nearest grid"""
loc_column = column.Location.Point
grid_direction = grid.Curve.Direction.Normalize()
# grid_ref = Reference.ParseFromStableRepresentation(doc, grid.UniqueId)
# OR
grid_ref = Reference(grid)
#
base_line = DB.Line.CreateUnbound(loc_column, grid_direction.CrossProduct(XYZ.BasisZ))
# select the good reference plane
for referenceType in [FamilyInstanceReferenceType.CenterLeftRight, FamilyInstanceReferenceType.CenterFrontBack]:
for ref in column.GetReferences(referenceType):
ref_array = ReferenceArray()
ref_array.Append(ref)
ref_array.Append(grid_ref)
#
dim = doc.Create.NewDimension(doc.ActiveView, base_line, ref_array)
doc.Regenerate()
if dim.Value > 0.01:
# apply offset
if abs(grid_direction.CrossProduct(XYZ.BasisX).GetLength()) < 0.1:
dim.Location.Move(XYZ.BasisX.Multiply(offset * -1))
else:
dim.Location.Move(XYZ.BasisY.Multiply(offset))
return dim
else:
# delete the bad dimension and continue
doc.Delete(dim.Id)
return None
column = UnwrapElement(IN[0])
data_interSect_grid = get_grids_intersections()
# get the nearest grid intersection and unpack the result
gridA, gridB, intersectPt = sorted(data_interSect_grid, key=lambda tupl_data : tupl_data[2].DistanceTo(column.Location.Point))[0]
TransactionManager.Instance.EnsureInTransaction(doc)
outdims = [create_dimension(column, g) for g in [gridA, gridB,]]
TransactionManager.Instance.TransactionTaskDone()
OUT = outdims
2 Likes