How to create walls from profile?

Hi guys,

I’ve been banging my head against the (incorrectly generated) wall for a while now and could really use some help.

I’m trying to create walls that follow a line that also curves in the z-direction. Wall.ByCurveAndHeight does not handle this and Wall.ByFace needs a (mass) host face instead of a surface. So I turned to Python and came up with the code below. Problem is, the resulting walls do not follow the z-values used. Sometimes I will get varying top and bottom edges, but not the same as my input.

Anyone have any ideas on whats going wrong or could point me in the direction of a better method?

Cheers,
Niklas

import clr
clr.AddReference('ProtoGeometry')
from Autodesk.DesignScript.Geometry import *


doc =  DocumentManager.Instance.CurrentDBDocument

wallpts = IN[0]

walls = []

TransactionManager.Instance.EnsureInTransaction(doc)

for loop in wallpts:
	profile = []
	for i in range(len(loop)-1):
		profile.append(Line.ByStartPointEndPoint(loop[i], loop[i+1]).ToRevitType())
	profile.append(Line.ByStartPointEndPoint(loop[-1], loop[0]).ToRevitType())
	
	wall = Wall.Create(doc, profile, True).ToDSType(False)
	walls.append(wall)

TransactionManager.Instance.TransactionTaskDone()

OUT = walls

Walls in Revit are linear extrusions hosted on a plane. Calling the Wall.Create method from the API is therefore going to create a wall following this principle regardless of the path curve. A simple rule of thumb is: if it can be done in Revit then it (in most cases) can be done using the API. Behaviour doesn’t change.

With this in mind, the question is: how is a sloping wall achieved in Revit?

  1. Using a swept wall
  2. Changing the profile of the wall once it’s created

They are the two methods you should explore and establish if they can be performed programmatically (I.e through Dynamo/Revit API). That should give you your answer!

There is a create method for wall that accepts a profile. Not for editing, though.

http://www.revitapidocs.com/2017.1/d2848332-daca-2bf1-4aca-21ea21937758.htm

And I have gotten results with non-rectangular walls, just not the right shape. But I can’t reproduce that at the moment.

I think you’re pretty close.
Here’s what I got:


It is your graph before that. I decided to construct the curves outside the python.
The tricky part is actually the last node. For some reason even though the profiles are applied correctly the wall falls on the level. So you need to apply an offset equal to the distance from the level to the lowest poist of the profile.

from System.Collections.Generic import List as Lst

doc =  DocumentManager.Instance.CurrentDBDocument

crvs = IN[0]

walls = []


TransactionManager.Instance.EnsureInTransaction(doc)

for loop in crvs:
	prf = Lst[Curve]()
	for i in loop:
		prf.Add(i.ToRevitType())
		
	wall = Wall.Create(doc, prf, False)
 	walls.append(wall)
TransactionManager.Instance.TransactionTaskDone()

OUT = walls

The wall creation method requires an Ilist of curves which is declared like this"prf = Lst[Curve]()"
You need to import it from System first.

Thanks Viktor, this looks promising.

But the line prf.Add(i.ToRevitType()) is giving me the error "TypeError: expected Curve, got Line"
Thought I could just change the collection to Line, but that resulted in the confusing TypeError: expected Line, got Line :confused:

That sounds like a confusion between DS lines and Revit Lines.
I didn’t have that problem since I created the curves in Dynamo and used the geometry conversion tools (ToRevitType)
Can you drop here your entire Python script?

Its strange. I copied your workflow and script to test and I still get that error. Tried Revit 2017 and 2018 in case it was an API related issue, but no luck.

Well I didn’t copy all the inputs in the beginning, though I don’t think I need all of them I just place it in the beginning in case I need to use something.
This is the entire code I used:
import clr
clr.AddReference(‘ProtoGeometry’)
from Autodesk.DesignScript.Geometry import *

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

clr.AddReference("RevitNodes")
import Revit
clr.ImportExtensions(Revit.Elements)
clr.ImportExtensions(Revit.GeometryConversion)
clr.AddReference("RevitServices")
import RevitServices
from RevitServices.Persistence import DocumentManager
from RevitServices.Transactions import TransactionManager
clr.AddReference("System")
from System.Collections.Generic import List as Lst

doc =  DocumentManager.Instance.CurrentDBDocument

crvs = IN[0]

walls = []


TransactionManager.Instance.EnsureInTransaction(doc)

for loop in crvs:
	prf = Lst[Curve]()
	for i in loop:
		prf.Add(i.ToRevitType())
		
	wall = Wall.Create(doc, prf, False)
 	walls.append(wall)
TransactionManager.Instance.TransactionTaskDone()

OUT = walls

and this is what goes inside:

2 Likes

That worked like a charm. Thank you for your patience, Viktor.
Imports tripped me up (again).

Need to read up on collections also :slight_smile:

1 Like

Wombat package > wall by.profile good day

3 Likes

Tested the Wombat node. Still needs a Base Offset adjustment as Viktor suggested.

Wombat’s wall by.profile saved me, Thanks!

谢谢你,[" prf = LstCurve "这段代码解决了关键问题.整个中国互联网都没有答案.

1 Like

Hi Guys,
How Can I use the wall.byprofile If I had a line with X,Y,Z coordinates , I am having trouble to use this node