Opening Edge to Wall Edge distance

Hi,
Is it possible to only get the distance from the opening edge to wall edge and opening edge to opening edge?


Opening Edge to Wall Edge distance .dyn (28.9 KB)

Yes - if you want to get the layout as you have illustrated then look into the dimensioning workflows.

If you just want to do a geometric analysis then Instead of using element.children and bounding boxes I recommend you use the geometry of the wall.

  1. The Revit API has some methods to get the inside or outside face of a wall, which you can then convert to Dynamo geometry.
  2. Edges can then be filtered by the Z component of their direction - anything primarily vertical will need a measurement for your horizontal distance study.
  3. Sort the lines by their relative parameter along the walls’s location curve to assure lines are ordered from wall start to wall end.
  4. For each line excepting the final line:
    1. Get the nearest point on the line to the next line.
    2. Get the nearest point on the next line to the line.
    3. Build a vector between the two points.
    4. Extract the XY component and get the length - this is the horizontal distance between the components.
    5. Write out the horizontal distances.

Note that you might want to group stuff by inclusion in a common vertical range between step 3 and 4. I won’t go into the logic for that as those steps won’t help if you don’t manage the base steps first.

Give it a shot and see where you get.

Hi @jacob.small, the distance is resulting 0. I’m not sure what I’m doing wrong.


Opening Edge to Wall Edge distance .dyn (37.6 KB)

Look at how many items you have at each step. For a basic wall there are at least four surfaces which have a normal with a z component of 0 - the front face, the back face, the left side, and the right side.

You need to get either the front or back face.

As a side note, you appear to be using an antique for all of this work. Revit 2022 isn’t supported, and you’re going to be spending a LOT of time maintaining the antique and the supported builds. Time to update.

Hi

a solution using a horizontal line scan to find intersections with the vertical lines of a surface

Python code with Revit 2026 ( needs to be adapted for earlier versions.)

import clr
import sys
import System
#import net library
from System import Array
from System.Collections.Generic import List, IList, Dictionary, HashSet
#
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.Elements)
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

#Preparing input from dynamo to revit
wall = UnwrapElement(IN[0])
debug = []
lines_between_opening = []

wall_int_ref = DB.HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior)[0]
face_int = wall.GetGeometryObjectFromReference(wall_int_ref)
all_vertical_curves = [curv for loop in face_int.GetEdgesAsCurveLoops() for curv in loop if abs(curv.ComputeDerivatives(0.5, True).BasisX.Z) > 0.9]
ds_face_int = face_int.ToProtoType()
# get top edge
align_ds_bbx = BoundingBox.ByMinimumVolume(ds_face_int)
ds_top_pt1 = DS.Point.ByCoordinates(align_ds_bbx.MinPoint.X, align_ds_bbx.MinPoint.Y, align_ds_bbx.MaxPoint.Z)
ds_top_pt2 = align_ds_bbx.MaxPoint
ds_top_line = DS.Line.ByStartPointEndPoint(ds_top_pt1, ds_top_pt2)
top_line = ds_top_line.ToRevitType()
# get min Z
minZ = align_ds_bbx.MinPoint.ToXyz().Z
#
i = 0 
current = top_line
offset = 0.2
while (current.GetEndPoint(0).Z - offset) > minZ and i < 10000:
    i += 1
    current = current.CreateOffset(offset, XYZ.BasisX)
    # search all intersection with vertical curves
    temp = []
    for curv in all_vertical_curves:
        #
        intersectResult = current.Intersect(curv, CurveIntersectResultOption.Detailed) 
        if intersectResult.Result == SetComparisonResult.Overlap:
            for overlap_pt in intersectResult.GetOverlaps() :
                temp.append([overlap_pt.FirstParameter , overlap_pt.Point.ToPoint()])
    # sort points by parameter
    temp.sort(key = lambda x : x[0])
    if len(temp) > 2:
        # iterate through the points two at a time.
        iter_intersect = iter(temp)
        for (para1, pt1), (para2, pt2) in zip(iter_intersect, iter_intersect):
            lines_between_opening.append(DS.Line.ByStartPointEndPoint(pt1, pt2))
        
OUT = lines_between_opening

Hi @c.poupin, Thank you for sending this. I’ve tested the script and it is resulting in a empty list. I’ve attached the Revit model for your review.
Opening Edge to Wall Edge distance_detached.rvt (2.6 MB)


hi, here is the fixed code

import clr
import sys
import System
#import net library
from System import Array
from System.Collections.Generic import List, IList, Dictionary, HashSet
#
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.Elements)
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

#Preparing input from dynamo to revit
wall = UnwrapElement(IN[0])
debug = []
lines_between_opening = []

wall_int_ref = DB.HostObjectUtils.GetSideFaces(wall, ShellLayerType.Interior)[0]
face_int = wall.GetGeometryObjectFromReference(wall_int_ref)
all_vertical_curves = [curv for loop in face_int.GetEdgesAsCurveLoops() for curv in loop if abs(curv.ComputeDerivatives(0.5, True).BasisX.Z) > 0.9]
ds_face_int = face_int.ToProtoType()
# get top edge
align_ds_bbx = BoundingBox.ByMinimumVolume(ds_face_int)
ds_top_pt1 = DS.Point.ByCoordinates(align_ds_bbx.MinPoint.X, align_ds_bbx.MinPoint.Y, align_ds_bbx.MaxPoint.Z)
ds_top_pt2 = align_ds_bbx.MaxPoint
ds_top_line = DS.Line.ByStartPointEndPoint(ds_top_pt1, ds_top_pt2)
#debug.append(ds_top_line)
#debug.append(ds_face_int)
top_line = ds_top_line.ToRevitType()
# get min Z
minZ = align_ds_bbx.MinPoint.ToXyz().Z
#
i = 0 
current = top_line
offset = -0.2
direction = top_line.Direction.CrossProduct( XYZ.BasisZ).Negate()

while (current.GetEndPoint(0).Z - offset) > minZ and i < 1000:
    i += 1
    current = current.CreateOffset(offset, direction)
    debug.append(current.ToProtoType())
    # search all intersection with vertical curves
    temp = []
    for curv in all_vertical_curves:
        #
        intersectResult = current.Intersect(curv, CurveIntersectResultOption.Detailed) 
        if intersectResult.Result == SetComparisonResult.Overlap:
            for overlap_pt in intersectResult.GetOverlaps() :
                temp.append([overlap_pt.FirstParameter , overlap_pt.Point.ToPoint()])
    #
    # sort points by parameter
    temp.sort(key = lambda x : x[0])
    
    if len(temp) > 2:
        # iter 2 by 2 on intersection points
        iter_intersect = iter(temp)
        for (para1, pt1), (para2, pt2) in zip(iter_intersect, iter_intersect):
            lines_between_opening.append(DS.Line.ByStartPointEndPoint(pt1, pt2))
        
OUT = lines_between_opening

Hi, @jacob.small, its giving the wrong horizontal distances between the components. Is there a way to find the distance between the edges only? I’ve attached the screenshots below.


Opening Edge to Wall Edge distance WIP .dyn (70.5 KB)

Missing step 3 in the proses I outlined above by the looks of it. The list.SortByKey node appears to have the wrong key.