I’ve gotten the intersections between the planes created by my levels and the walls as surfaces . I’ve gotten the points to split at ! but whet i run the genius loci split by points node my wals dont split ! Am i doing something wrong ?
What’s happend when you set your lacing on longest?
I’m not sure but I think the split node need a transaction start before split the walls. (by DynaTools is it necessary)
Ok, so it appears in order for this graph to work, you need to make sure the Top Constraint is set to a level. If it is Unconnected, that is what makes it fail from my testing.
For the genius loci node the condition of having equal points and walls cant be satisfied in my project for the simple reason that i have walls that are created across 3 or 4 leves so 1 wall could generate 4 points . But this same node worked for me when splitting pipes by level and i had more points than pipes so i don’t understand the logic behind it
I did modify the Python to check for a null result on the Top Offset of UnConnected walls to skip them so there wouldn’t be an error/ warning.
import clr
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
doc = DocumentManager.Instance.CurrentDBDocument
clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitAPI")
from Autodesk.Revit.DB import *
import System
from System.Collections.Generic import *
############## Definitions Start ##############
# Convert to List if singleton...
def tolist(obj1):
if hasattr(obj1,"__iter__"): return obj1
else: return [obj1]
# Returns the index of the found level given a Level and a list of Levels...
def FindLevelIndex(levels, lev):
ind = None
i = 0
for l in levels:
if l.Id.ToString() == lev.Id.ToString():
ind = i
i = i+1
return ind
# Copy the original wall and set it's levels using the Built-In Parameters for the Base and Top Constraints...
def CopyWallByLevel(wall, b, t):
wallOut = None
try:
# Copy the Original Wall with a transformation vector of 0,0,0...
w = ElementTransformUtils.CopyElement(doc,wall.Id,XYZ(0,0,0))
# Since the CopyElements method returns the ElementId of the new wall we need to get this Element from the Document...
w = doc.GetElement(w[0])
# Update the Base and Top constraints Parameters using the Built-In Parameters.
# Note: I have explicitly chosen the Overload as I was getting flaky behaviour where the wrong overload was being used...
p = w.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT)
p.Set.Overloads.Functions[2](b.Id)
p = w.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE)
p.Set.Overloads.Functions[2](t.Id)
wallOut = w.ToDSType(True)
# Write out any exceptions...
except Exception, e:
wallOut = e.message
# Return new wall..
return wallOut
############## Definitions End ##############
# IN-Variables...
run = tolist(IN[0])[0]
walls = tolist(UnwrapElement(IN[1]))
# OUT-Variables...
outList = []
# Main Script...
# Test if user has selected Run as True...
if run:
# Get All Levels in the Document and cast to .net List...
levels = list([l for l in FilteredElementCollector(doc).OfClass(Level).ToElements()])
# Sort Levels by Elevation using a lamda expression...
levels.sort(key=lambda x: x.Elevation, reverse=False)
# Start a new Transaction ready for modifying the Document...
TransactionManager.Instance.EnsureInTransaction(doc)
for w in walls:
arr = []
# Check if the Element is a Wall...
if w.GetType() == Wall:
# Get Base and Top Constraints as Levels...
p = w.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT)
base = doc.GetElement(p.AsElementId())
p = w.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE)
top = doc.GetElement(p.AsElementId())
#This test will make sure the wall is cosmtrained to a level
if not top == None:
# Test whether walls Base and Top levels are NOT the same, if they are we will skip this wall, if they are not then we will get the Index of the Level in the sorted list of Levels we collected earlier for both the Base and Top of the wall...
if not base.Id.IntegerValue == top.Id.IntegerValue:
# Note: we are setting the bounds of the Loop below with the Indices of the found Levels so we will only loop through the Levels in between the Base and Top Levels...
i = FindLevelIndex(levels,base)
j = FindLevelIndex(levels,top)
# Loop through the Levels between the Base and Top Levels copying the original wall for each iteration and stepping up one Level...
while i < j:
wCopy = CopyWallByLevel(w,levels[i], levels[i+1])
arr.append(wCopy)
i = i+1
outList.append(arr)
# Delete original Wall as this has now been split by Level...
doc.Delete(w.Id)
# End the Transaction...
TransactionManager.Instance.TransactionTaskDone()
# Return the new Walls...
OUT = outList
# Return if user has not set input Run to True...
else:
OUT = "Please Set Run to True"
Well that one wall slipped my check Thanks for your help ! I’ll Check for the other walls ! I have another issue when the script duplicates the original wall instead of splitting it ! Like shown below .
I believe that is because that wall has a modified profile. If you do that the top constraint or constraints in general are not really followed. If you reset the profile there I would imagine you would see them all fall where you would expect them to be. In short, not really an issue with the graph per say, but more how Revit handles modified walls.
FYI - This graph is not SPLITTING the wall, it is actually duplicating the wall and then adjusting the Top and Base constraints and then deleting the original wall. Splitting Walls is not accessible via the Revit API and therefore we need this workaround to do what you are after.
Thank you for yout time @SeanP
I guess i’ll split the modified walls manually for the time being untill autodesk implements splitting in the revit API !