Is it possible to change the unit of measure to meters?
Is there a way for this python version to generate a single dimension line, instead of the chopped up version?
Thanks in advance
Apologies, this thread is so long I can’t even remember where it got to
I think it is about list management… You need to group all the references for each dimension into a sub-list, if you are getting chopped dimensions you are getting a pair of references for each dimension.
If you are unsure, I would start with creating what you want using nodes and then translate to Python, I believe Genius Loci has lots of useful nodes.
I hope that helps,
I was talking about the script where there’s basically only a python node (code is below).
The rest of the script works like a charm by the way, amazing work.
I’ve narrowed it down to this area (I think) but no amount of tinkering works (it doesn’t help that I don’t understand python much)
Here’s the code you’ve provided
#thanks for all the help everyone import clr # Import RevitAPI clr.AddReference("RevitAPI") import Autodesk from Autodesk.Revit.DB import * import System clr.AddReference("ProtoGeometry") from Autodesk.DesignScript import Geometry as geom # Import Element wrapper extension methods clr.AddReference("RevitNodes") import Revit from Autodesk.Revit.DB import * # Import ToProtoType, ToRevitType geometry conversion extension methods clr.ImportExtensions(Revit.GeometryConversion) clr.AddReference("RevitAPIUI") from Autodesk.Revit.UI.Selection import ObjectType clr.AddReference("ProtoGeometry") from Autodesk.DesignScript import Geometry as geom # Import DocumentManager and TransactionManager clr.AddReference("RevitServices") import RevitServices from RevitServices.Persistence import DocumentManager from RevitServices.Transactions import TransactionManager doc = DocumentManager.Instance.CurrentDBDocument uidoc = DocumentManager.Instance.CurrentUIApplication.ActiveUIDocument def isParallel(v1, v2): #it needs two vectors return v1.CrossProduct(v2).IsAlmostEqualTo(XYZ(0, 0, 0)) def isAlmostEqualTo(v1, v2): return v1.IsAlmostEqualTo(v2) def isPerpendicular(v1, v2): if v1.DotProduct(v2)== 0: return True else: return False def tolist(obj1): if hasattr(obj1,"__iter__"): return obj1 else: return [obj1] def CurveToVector(crv): vec = geom.Vector.ByTwoPoints(crv.StartPoint,crv.EndPoint) return vec #set the wall orientation, depending on whether exterior or interior is selected def wallNormal(wall, extOrint): if extOrint: wallNormal = wall.Orientation.ToVector() else: wallNormal = wall.Orientation.Negate().ToVector() return wallNormal #this takes the wall location line, shifts it up the to the view cut plane #and moves it out to the external edge of the wall def locToCutCrv(wall, wallNormal, lineEndExtend): wallLn = wall.Location.Curve wallCrv = wallLn.ToProtoType() #take the level height, subtract the height of the wall base zOf = doc.ActiveView.GenLevel.Elevation-wallCrv.StartPoint.Z #get the cut plane offset of the view cPlaneH = doc.ActiveView.GetViewRange().GetOffset(PlanViewPlane.CutPlane) #the CutPlane enumeration is like a property of PBP? cPlaneHiMM = UnitUtils.ConvertFromInternalUnits(cPlaneH, DisplayUnitType.DUT_MILLIMETERS) wallCrv = geom.Geometry.Translate(wallCrv, geom.Vector.ByCoordinates(0,0, zOf+cPlaneHiMM)) wallwidthMM = UnitUtils.ConvertFromInternalUnits(wall.Width, DisplayUnitType.DUT_MILLIMETERS) wallCrv = geom.Geometry.Translate(wallCrv, wallNormal, (wallwidthMM/2)) #get wall curve info wallvec = CurveToVector(wallCrv) wallorig = geom.Curve.PointAtParameter(wallCrv,0.5) walldir1 = geom.Vector.ByTwoPoints(wallorig, wallCrv.StartPoint) walldir2 = geom.Vector.ByTwoPoints(wallorig, wallCrv.EndPoint) #move points ptMvSt = geom.Geometry.Translate(wallCrv.StartPoint, walldir1, lineEndExtend) ptMvEnd = geom.Geometry.Translate(wallCrv.EndPoint, walldir2, lineEndExtend) #create new line based on extended points #this is not a model line! that requires another method lineAtExternalEdgeAtCutPlaneHeight = geom.Line.ByStartPointEndPoint(ptMvSt, ptMvEnd).ToRevitType() return lineAtExternalEdgeAtCutPlaneHeight offDist = IN extOrInt = IN #if the wall is exterior we need to extend the intersect line #beyond the exterior face to pick up the intersecting walls #if the wall is interior, we don't want to extend as far if extOrInt: intersectLineEndExtend = 500 else: intersectLineEndExtend = 0 #User Input ref = uidoc.Selection.PickObject(ObjectType.Element, 'Select A Wall') #define Targe Wall targetWall = doc.GetElement(ref) #let's go get the walls for finding references intersectedWalls =  #start by adding our target wall intersectedWalls.append(targetWall) #then get all the other walls in the view and test if they intersect the Target Wall collectedWalls = FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(Wall).ToElements() for collectedWall in collectedWalls: if targetWall.Location.Curve.Intersect(collectedWall.Location.Curve) == SetComparisonResult.Overlap: intersectedWalls.append(collectedWall) #Target Wall external line for intersect check exLi = locToCutCrv(targetWall, wallNormal(targetWall, extOrInt), intersectLineEndExtend) #Curve where the dimension will be located offCrv = geom.Geometry.Translate(exLi.ToProtoType(), wallNormal(targetWall, extOrInt), (offDist)) #lets get the wall edges we want #only get edges intersecting target side? no this is misleading... we want any reference hitting our external wall #the problem is actually that the face itsetlf is registering the intersections we don't want e.g. the wrapping ends frontFaceIW =  vertEdges =  opts = Options() #without compute references, none of this works opts.ComputeReferences = True opts.IncludeNonVisibleObjects = True opts.View = doc.ActiveView for wallInt in intersectedWalls: for obj in wallInt.get_Geometry(opts): #walls also contain line geometry if isinstance(obj, Solid): for face in obj.Faces: #if face is normal is equal to wall normal it is the external face if isAlmostEqualTo(wallInt.Orientation, face.ComputeNormal(UV(0.5,0.5))): frontFaceIW.append(face) for edge in obj.Edges: #get edges which intersect edgeC = edge.AsCurve() edgeCNorm = edgeC.Direction.Normalize() #if front face edge and edge intersects line and edge is vertical up or vertical down add to list if edgeC.Intersect(exLi) != SetComparisonResult.Disjoint and (edgeCNorm.IsAlmostEqualTo(XYZ(0,0,1)) or edgeCNorm.IsAlmostEqualTo(XYZ(0,0,-1))): vertEdges.append(edge) #so we use the X+Y values as a unique identifier of location (we're less interested in #the actual unique reference, there may be 2 in the same place) #we will use these as filtering and sorting values #if we wanted to use this on sections we'd want to use z value? vertEdgesLoc =  for v in vertEdges: vLoc = v.AsCurve().GetEndPoint(0).X + v.AsCurve().GetEndPoint(0).Y #getting some revit rounding errors, 7dp should be enough! vertEdgesLoc.append(round(vLoc,7)) #trying to remove stray intersect edges from adjoining walls #to identify them, they are not on an intersecting wall front face #their faces are not both on the target wall #so we need all the target wall faces for obj in targetWall.get_Geometry(opts): #walls also contain line geometry if isinstance(obj, Solid): faceTW = obj.Faces #create a holding list containing everything in vertEdges strayEdges =  for v in vertEdges: strayEdges.append(v) #start removing things from holding list to leave only the stray ones for faIW in frontFaceIW: #if edge face 0&1 are both target wall faces we don't want to remove them i = 0 length = len(strayEdges) while (i < length): if strayEdges[i].GetFace(0) in faceTW: strayEdges.Remove(strayEdges[i]) length = length - 1 elif strayEdges[i].GetFace(1) in faceTW: strayEdges.Remove(strayEdges[i]) length = length - 1 #if our wall is external.... #if edge face is an intersecting wall's front face, we don't want it elif strayEdges[i].GetFace(0) == faIW and extOrInt == True: strayEdges.Remove(strayEdges[i]) length = length - 1 elif strayEdges[i].GetFace(1) == faIW and extOrInt == True: strayEdges.Remove(strayEdges[i]) length = length - 1 # strayEdges.Remove(ed) #or if the edge reference is to a non-wall continue i = i+1 #if the wall is exterior, we want to remove references to internal wall edge if extOrInt == True: i=0 length = len(vertEdgesLoc) strayCLoc2 =  while (i < length): for stray in strayEdges: stLoc = stray.AsCurve().GetEndPoint(0).X + stray.AsCurve().GetEndPoint(0).Y #getting eroneous values, Revit accuracy not good enough? round is built in method if round(vertEdgesLoc[i],7) == round(stLoc,7): vertEdges.Remove(vertEdges[i]) vertEdgesLoc.Remove(vertEdgesLoc[i]) length = length - 1 continue i = i+1 #sort the edges using the combined XY location value vertEdgesSorted = [x for _,x in sorted(zip(vertEdgesLoc,vertEdges))] vertEdgesLocSorted = sorted(vertEdgesLoc) #only add uniquely located references #this is awkward because we test 1 list, then add to the other list #we need the Temp list, so we know what should be added to the Sub list vertEdgeUniLocTemp =  vertEdgeSub = ReferenceArray() for eL, e in zip(vertEdgesLocSorted, vertEdgesSorted): if eL not in vertEdgeUniLocTemp: vertEdgeUniLocTemp.append(eL) vertEdgeSub.Append(e.Reference) #we want to pair up the references to create unique dims for the brick dim checker #convoluted code, ref arrays seem their own beast! outRefs =  #define the overall list length for i in range(vertEdgeSub.Size-1): #create the array here so the list nesting is correct vertEdgeAr = ReferenceArray() #define the sub list length while vertEdgeAr.Size < 2: #only get add 2 indices for each sub list vertEdgeAr.Append(vertEdgeSub[i]) vertEdgeAr.Append(vertEdgeSub[i+1]) outRefs.append(vertEdgeAr) #OUT = len(strayEdges) #start transaction TransactionManager.Instance.EnsureInTransaction(doc) #create dimensions for each pair of referenes for ref in outRefs: dim = doc.Create.NewDimension(doc.ActiveView, offCrv.ToRevitType(), ref), outRefs, #finish transaction TransactionManager.Instance.TransactionTaskDone()
Hey, so first off, if you look here:
You will see that for every dimension we need a View, Line and Reference Array.
My code happens to have a Reference Array called vertEdgeSub, and you don’t need to break it down and pair it up, so I think you can just use that…
(delete ‘for ref in outRefs:’ and delete any spaces before ‘dim’ so it sits at the beginning of the line)
dim = doc.Create.NewDimension(doc.ActiveView, offCrv.ToRevitType(),vertEdgeSub)
If that doesn’t work, if you could post a screen grab of your code and the warning message above the Python node we can see what is going wrong.
Hope that helps,
Oh wow that is a usefull site.
When I start coding for real that is gonna be a huge help, thanks!
It didn’t work at first, said there was an inconsistency of references, but this did work so thank you!
dim = doc.Create.NewDimension(doc.ActiveView, offCrv.ToRevitType(), vertEdgeSub), outRefs,
someone resolves it? i need help :C
Change the following in the code (lines 76 & 78)
cPlaneHiMM = UnitUtils.ConvertFromInternalUnits(cPlaneH, DisplayUnitType.DUT_MILLIMETERS)
cPlaneHiMM = UnitUtils.ConvertFromInternalUnits(cPlaneH, UnitTypeId.Millimeters)
locPositionMM = UnitUtils.ConvertFromInternalUnits(locPos, DisplayUnitType.DUT_MILLIMETERS)
locPositionMM = UnitUtils.ConvertFromInternalUnits(locPos, UnitTypeId.Millimeters)