Toposolid by toposolid sub-division

Hi all,
Revit developers finaly gave us in Revit 2024 an option to work with layered terrain, even with 3D subregions. At first glance it sounds amazing. But after you play with it for a bit you notice that there is a big problem. Subdivision can only folow phase of toposolid. So its unusable. So what now? We can go and split the Toposolid then we can do phasing of different parts as we want … but we can’t merge them, so we can get stuck again.

I was thinking a bit and found a solution. Subdivisions are great for getting the points to morph the topology. So we can can points from subdivision, get boundary lines from subdisivion and based on those create a new Toposolid. This way we can get phasing as we want, we can update the boundaries of subdivision and update Toposolid and we even get “Subdivision” which has layers.

Hope this will help somebody.
You can see the simple version of .dyn, and python script below.

import clr

clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import *
from Autodesk.Revit.DB.Architecture import *
import System.Collections.Generic
from System.Collections.Generic import List

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

clr.AddReference('RevitServices')
from RevitServices.Transactions import TransactionManager
from RevitServices.Persistence import DocumentManager

doc = DocumentManager.Instance.CurrentDBDocument

# The inputs to this node will be stored as a list in the IN variables.
dataEnteringNode = IN
# Get input variables
toposo = UnwrapElement(IN[0])
lvl = UnwrapElement(IN[1])
topotype = UnwrapElement(IN[2])
points = IN[3]

# Place your code below this line

pts = []
for i in points:
    pts.append(i.ToRevitType())
    
skid=toposo.SketchId
skt = doc.GetElement(skid)
skp = skt.Profile

cloop = CurveLoop()
for c in skp:
    for cc in c:
        cloop.Append(cc)
    
TransactionManager.Instance.EnsureInTransaction(doc)

loops = [cloop]
topo = Toposolid.Create(doc,loops,pts,topotype.Id,lvl.Id)


	
TransactionManager.Instance.TransactionTaskDone()


# Assign your output to the OUT variable.
OUT = topo
5 Likes

I got this error from the code, how may I correct it?

AttributeError : ‘lista object has no
attribute ‘Id’ File line 45, in
\n’]

Hi,
it’s a problem of inputs - you are feeding “Toposolid type” or “Level” as list instead of item. The code is not prepared to generate multiple types and multiple toposolids at once. In case you are looking for that you have to change the code a bit.

I would recomend to start with one toposolid + toposolid type + level to try if the code works and it’s doing what you are looking for. And after that modify the line 45 of code to accept lists.

hmmm, I don’t think so,
I have a toposolid and a subregion, i select the topo and the subregion and have used the same nodes as you suggested but the error keep showing.

Hi,
sorry for late response. Did you solve it? If not, could you send me a picture of your code with Watch nodes on inputs to my python script node?

Hello, Has anyone tried using this method yet (toposolid.CreateSubDivision). I cannot get it to work.

Here is mine,

import clr
clr.AddReference('RevitAPI')
from Autodesk.Revit.DB import Toposolid, CurveLoop
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager

doc = DocumentManager.Instance.CurrentDBDocument

# Get the toposolid from the input
toposolid = UnwrapElement(IN[0])

# Get the profiles from the input
profiles = IN[1]

# Start a transaction
TransactionManager.Instance.EnsureInTransaction(doc)

# Create a new subdivision within the toposolid
subdivision = toposolid.CreateSubDivision(profiles)

# Commit the transaction
TransactionManager.Instance.TransactionTaskDone()

# Set the output variable
OUT = subdivision

image
I get this error, I’m very new to dynamo and don’t fully understand what is going on

for this you are using the same nodes showed in the definition of the post?