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
4 Likes
It took some time but I finally got to this.
Your script creates a reference based on the grid direction at the location point of the column? Did I understand it correctly?
For each column, we look for the nearest grid intersection, then we create dimensions in relation to the 2 grids that define this intersection (and the column).
Iâm adopting the grid intersection points distance to select the grids.
I still dont get why my script doesnât work when I select get the Reference CenterLine that is parallel to the grid and create a dimension between them. I also adopted the line creation by what you did - using the line.CreateUnbound with direction of the cross between the Z axis and the grid vector.
So given that I use the same parallel references and the same line like you created, any idea why it wouldnât work?