Split walls by level

Hello again everybody !
So i’m trying to Split the walls in my project by levels ! This is what i’ve done so far !


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 ?

Hi Deejaypein,

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)

Kg,

Jan Willem

1 Like
1 Like

Thanks for your suggestion ! i’ve found this script before but i couldn’t get it to work as i get the following error on every run !

When i change to longest lacing i keep getting null values on the node

May need to be some tweaks since that graph is 4 years old. I’ll see if I can take a look today.

It would be a great help ! Thanks a lot !

Hi,

The description of the inputs is important for this node. :

With this custom node, you must use as many points as elements :

Split walls.dyn (14.6 KB)

EDIT : After checking the subject, this is not the appropriate node to split walls vertically.
You will have better luck using the script from post 2.

2 Likes

heheh i find out too…always read the topic first… :wink: :wink:

3 Likes

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.

1 Like

Thank you @Alban_de_Chasteigner

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

Thank you @SeanP

The top constraint is already set for all the walls in the project ! the script worked for some regular walls But it didint for some like this one

With the Error being the following

It looks like the Top Constraint is the issue. Also, with that wall having a modified profile it may also break 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"
1 Like

Well that one wall slipped my check :blush: 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’ve checked the top constraint)

1 Like

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.

2 Likes

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 !