Get Actual Location

PS.: this is a repost from the dyamo forum since i realise that this is prob the betre place for this topic since its more python related then dynamo.

Hi,

I’m looking to use the functionality of this node in a python script.
i have been looking with the the revit.lookup tool for a properties or methode of some kind but i’m unable to find anything that resambels this.

To be precise i’m want to find adjucent walls to each other.
And match them togheter in a list.

Basically what I think you are after is:

#Inspiration from Alban Chastegnier code in the Get Joined Elements node in the Genius Loci package
from pyrevit import revit, DB
doc = revit.doc

# get selected elements
items = revit.get_selection()
if not hasattr(items, '__iter__'):
    items = [items]
    
# get connected elements
connected_elems_at_join = []
for item in items:
    # get location curve in case of a wall
    loc = item.Location
    for ip in range(0, 2): # 0 = start, 1 = end
        # get all elements at join (for walls, this will give you the walls at each end of the wall)
        connected_elems_at_join.extend(loc.ElementsAtJoin[ip])
    # if the element is not the same as the one we are looking at, add it to the list
    connected_elems_at_join = [elem for elem in connected_elems_at_join if elem.Id != item.Id] 
    
# get joined elements
joined_elemens = []
for item in items:
    # get all elements joined to the element (in all dimensions (floors, ceilings, slabs, walls, etc.))
    joined = DB.JoinGeometryUtils.GetJoinedElements(doc, item)
    joined_elemens.extend(doc.GetElement(join) for join in joined)

print(connected_elems_at_join)
print(joined_elemens)

hi @Jean-Marc,

These commands give me the walls ‘touching’ at the ends.
If would use the location line then i won’t get overlaps of waal wich have been correct with a edit sketch.
Also walls starting above a surtain level or below it would trigger wrong contacts with walls next to it.

What i want to achieve is the folowing:
i’m looking for sets of walls wich resamble a combined walls.
For example:
a brick wall, insulation and stone innerwall.
these can be modeld as 3 seperate wall next to each other or as a combined wall with 3 layers init.

my idea was to look for the ‘actuallocation’ of the walls and via uv-position on them raytrace points away from the wall. if it hits a wall a 0 distance (or in case of the ‘actuallocation’ half the width of the wall). then i know that 2/3/… walls can be consired a set.

I could then control how many uv-point per location surface i want to check, controlig the speed of the script.

Maybe i’m completly on the wrong path to solving this but that was the idea in my head.

i have continued work on my script and i am almost achieving the desired output.
But at the final strech somethign wierd seems to happen.

I managed to get the interior and exterior faces of walls and intersect these with the other faces but the output i get are walls wich are perpendicular to the checking wall:
for example the red walls clash with the green (atleast by the output of my code)
while i would only expect the blue and yellow one to trigger an intersect.

below my code and pyrevit results:

code:

# imports
import clr
clr.AddReference('RevitAPI')
clr.AddReference('RevitAPIUI')
from Autodesk.Revit.DB import *

from pyrevit import revit

# doc & appplication
doc = revit.doc
uidoc = revit.uidoc

# collect walls in model
walls = FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToElements()

faces = []
valid_walls = {}

# Iterate through all walls to find intersections
opt = Options()
opt.ComputeReferences = True
opt.IncludeNonVisibleObjects = True

for wall in walls:
    wall_faces = []
    
    # get interiorface
    extSide = HostObjectUtils.GetSideFaces(wall,ShellLayerType.Exterior)
    for e in extSide:
        extface = wall.GetGeometryObjectFromReference(e)
        if extface == None:
            continue
        else:
            wall_faces.append(extface)
            print(extface)
        
    # get exteriorface
    intSide = HostObjectUtils.GetSideFaces(wall,ShellLayerType.Interior)
    for i in intSide:
        intface = wall.GetGeometryObjectFromReference(i)
        if intface == None:
            continue
        else:
            print(intface)
            wall_faces.append(intface)
            print('---------------------')
            
    # Add wall_faces to general faces list
    if len(wall_faces) > 0:
        valid_walls[wall] = wall_faces

for wall in valid_walls:
    print("Wall {}: {}".format(wall.Id, valid_walls[wall]))

print('INTERSECTING')    
print('-------------------------------------')

intersecting_walls_dict = {}

for wall1, faces1 in valid_walls.items():
    for wall2, faces2 in valid_walls.items():
        if wall1.Id != wall2.Id:
            for face1 in faces1:
                for face2 in faces2:
                    intersection_result = face1.Intersect(face2)
                    if intersection_result == FaceIntersectionFaceResult.Intersecting:
                        if wall1 not in intersecting_walls_dict:
                            intersecting_walls_dict[wall1] = []
                        if wall2 not in intersecting_walls_dict[wall1]:
                            intersecting_walls_dict[wall1].append(wall2)

for wall, intersecting_walls in intersecting_walls_dict.items():
    print("Wall ID: {} intersects with:".format(wall.Id))
    for intersecting_wall in intersecting_walls:
        print(" - Wall ID: {}".format(intersecting_wall.Id))
    print()

i based my script on this node(Wall edges references) from @Alban_de_Chasteigner (genius_loci):

#Alban de Chasteigner 2019
#twitter : @geniusloci_bim
#geniusloci.bim@gmail.com

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

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

def isAlmostEqualTo(v1, v2):
    return v1.IsAlmostEqualTo(v2)

def isParallel(v1,v2):
  return v1.CrossProduct(v2).IsAlmostEqualTo(XYZ(0,0,0))

items = UnwrapElement(IN[0])
if not hasattr(items, '__iter__'):
	items = [items]

extFaces,intFaces,allExtEdges,allIntEdges,allExtReferences,allIntReferences,allextHEdges,allextHReferences,allintHEdges,allintHReferences=[],[],[],[],[],[],[],[],[],[]

opt = Options()
opt.ComputeReferences = True
opt.IncludeNonVisibleObjects = True
for item in items:
	extSide = HostObjectUtils.GetSideFaces(item,ShellLayerType.Exterior)
	for e in extSide:
		extFace = item.GetGeometryObjectFromReference(e)
		extFaces.append(extFace)
	intSide = HostObjectUtils.GetSideFaces(item,ShellLayerType.Interior)
	for i in intSide:
		intFace = item.GetGeometryObjectFromReference(i)
		intFaces.append(intFace)
	for obj in item.get_Geometry(opt):
		extEdges,intEdges,extReferences,intReferences,extHEdges,extHReferences,intHEdges,intHReferences=[],[],[],[],[],[],[],[]
		if isinstance(obj, Solid):	
			for edges in obj.Edges:
				if round(edges.AsCurve().GetEndPoint(0).ToPoint().Z,10) != round(edges.AsCurve().GetEndPoint(1).ToPoint().Z,10):
					if edges.GetFace(0) in extFaces :
						extEdges.append(edges.AsCurve().ToProtoType())
						extReferences.append(edges.Reference)
					if edges.GetFace(0) in intFaces :
						intEdges.append(edges.AsCurve().ToProtoType())
						intReferences.append(edges.Reference)
				else :
					line = item.Location.Curve
					lineDir = line.GetEndPoint(1) - line.GetEndPoint(0)
					if not isinstance(edges.AsCurve(), Arc):
						faceNormal = edges.AsCurve().Direction.Normalize()
						if isParallel(faceNormal,lineDir):
							if edges.GetFace(0) in extFaces :
								extHEdges.append(edges.AsCurve().ToProtoType())
								extHReferences.append(edges.Reference)
							if edges.GetFace(0) in intFaces :
								intHEdges.append(edges.AsCurve().ToProtoType())
								intHReferences.append(edges.Reference)					
			allExtEdges.append(extEdges)
			allIntEdges.append(intEdges)
			allExtReferences.append(extReferences)
			allIntReferences.append(intReferences)
			allextHEdges.append(extHEdges)
			allextHReferences.append(extHReferences)
			allintHEdges.append(intHEdges)
			allintHReferences.append(intHReferences)
if isinstance(IN[0], (list)): OUT = filter(None, allExtEdges),filter(None,allExtReferences),filter(None,allIntEdges),filter(None,allIntReferences),filter(None,allextHEdges),filter(None,allextHReferences),filter(None,allintHEdges),filter(None,allintHReferences)
else: OUT = filter(None, allExtEdges)[0],filter(None,allExtReferences)[0],filter(None,allIntEdges)[0],filter(None,allIntReferences)[0],filter(None,allextHEdges)[0],filter(None,allextHReferences)[0],filter(None,allintHEdges)[0],filter(None,allintHReferences)[0]

Wich give the following dynamo, but i shortend it to just retrieve te faces and let those intersect to find the adjecent walls: