ExtrudeSolid from CAD layer . Dynamox3.Revit 2025 2002

Hi everyone,

I am trying to create a family from a dwg file in REvit 2025 (Dynamox3).

The routine tries to extrude as Solid from the CAD layer by the BIMmorphe node “CAD.CurvesFromCADLayers” to read the dwg, and the Spring node “Form.Bygeometry” to export the extrusion inside a Family file .

I cannot extrude it as a solid because it says the curve are not closed.

However, it partially works by “Curve.Extrude” and “Surface.Thicken” to create asolude to the “Form.Geometry” node, but some layers are not extruded properly .

Besides, I cannot generate the shape inside revit as the lists are null. I do not understand the issue, because the routine can be run in Revit 2023.

I will apreciate fi anyone can check where my mistake is. I have included the script below.
CAD.Extrusion.ToFamily.dyn (13.6 KB)

Thank you in advance.

It appears that the latest version of IronPython2.7 3.2.1 no longer has the traceback module which is causing the Springs node to fail.

Easiest solution - build the family in 2023 and open, update and save in 2025

You could open the node and update the python engine and code, however that creates more issues than it solves (like the inability to delete the SAT imports)

2 Likes

yes all what Mike say :wink: but you could try as here with ironpython 3 and should work for 2025


freeform Home.dyn (11.5 KB)

1 Like

Thanks Mike,

Actually that’s why I thought to model it 2023 and imported as dwg or sat in 2025. At least I can complete the family.

Thanks.

Thanks Soren,

Before trying in my routine, I opened your scripts.

However, I could not import the geometry into the family file. My apologies, but I am still new with all this. I have opened the Python script, but I have not clue how to proceed.

hmmm and your ironpython 3 should be 1.5.1 and you are sure you are in a familydocument…

what does the warning say ?

ps you dont need connect spring freeform node the python should do it

1 Like

Yes, I am working ian Generic Model template.
I am not sure if I am executing properly the python node.

hmmm it says the ironpython cant be find …hmmmm when you go to your packages do then see ironpython 3 version 1.5.1

1 Like

Ok, I have just installed it and reset revit just in case. I can now the python dashboard looks different, but I am not sure if I need to do anything else. I cannot see any extrusion in the family document.


hmmm not sure then, works great here and you run the python i shared ? …maybe @c.poupin could help…he the man :wink: :wink: for that kind :wink: :wink:

2 Likes

ps just i guess not sure if it could help but try remove all your packages except ironpython 3 version 1.5.1 and run the file i shared

1 Like

Hi,
here is an updated version of ꟿ Form.ByGeometry for IronPython3 and PythonNet3 (Revit2025+)

#Copyright(c) 2016, Dimitar Venkov
# @5devene, dimitar.ven@gmail.com
# code review by Cyril POUPIN for IronPython3 and PythonNet3 (Revit2025+)
import clr
import System
from System.Collections.Generic import *

clr.AddReference("System.Core")
clr.ImportExtensions(System.Linq)

from itertools import repeat
import sys
import traceback
import itertools

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

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")
import Autodesk.Revit.DB as DB
from Autodesk.Revit.DB import *

def tolist(obj1):
    if hasattr(obj1,"__iter__"): return obj1
    else: return [obj1]


def customZip3(lacing = "short", *args):
    """
    Custom Iteration's between lists: short or long or cross
    """
    if lacing != "cross":
        lenlsts = [len(x) for x in args]
        nbrIter = max(lenlsts) if lacing == "long" else min(lenlsts)
        for i in range(nbrIter):
            temp = []
            for sublist in args:
                try:
                    temp.append(sublist[i])
                except IndexError:
                    temp.append(sublist[-1])    
            yield(temp) 
    else:
        for combination in itertools.product(*args):
            yield(combination)

def NewForm(s1, isVoid1):
    message = None
    temp_path = System.IO.Path.GetTempPath()
    rand_name = System.Guid.NewGuid().ToString()
    sat_path = "%s%s.sat" % (temp_path, rand_name)
    try:
        if factor != 1:
            s1 = s1.Scale(factor)
        #
        sat1 = s1.ExportToSAT(sat_path)
        satOpt = SATImportOptions()
        satOpt.Placement = ImportPlacement.Origin
        satOpt.Unit = ImportUnit.Foot
        satId = doc.Import(sat1, satOpt, view1)
        opt1 = Options()
        opt1.ComputeReferences = True
        el1 = doc.GetElement(satId)
        geom1 = el1.get_Geometry(opt1)
        enum = geom1.GetEnumerator()
        enum.MoveNext()
        geom2 = enum.Current.GetInstanceGeometry()
        enum2 = geom2.GetEnumerator()
        enum2.MoveNext()
        s1 = enum2.Current
        # unpin
        el1.Pinned = False
        doc.Delete(satId)
        System.IO.File.Delete(sat_path)
    except:
        message = traceback.format_exc()
        pass
    if message is None:
        try:
            s2 = FreeFormElement.Create(doc,s1)
            if isVoid1:
                void_par = s2.get_Parameter(BuiltInParameter.ELEMENT_IS_CUTTING)
                void_par.Set(1)
            return s2.ToDSType(False)
        except:
            message = traceback.format_exc()
            return message
    else : return message

lst_geom, lst_isVoid = tolist(IN[0]),  tolist(IN[1])

acceptable_views = (ViewType.ThreeD, ViewType.FloorPlan, ViewType.EngineeringPlan, ViewType.CeilingPlan, ViewType.Elevation, ViewType.Section)
view1 = FilteredElementCollector(doc).OfClass(View).FirstOrDefault(System.Func[DB.Element, System.Boolean](lambda v : v.ViewType in acceptable_views and not v.IsTemplate))

units = doc.GetUnits().GetFormatOptions(SpecTypeId.Length).GetUnitTypeId()
factor = UnitUtils.ConvertToInternalUnits(1,units)
OUT = []
if doc.IsFamilyDocument:
    TransactionManager.Instance.EnsureInTransaction(doc)
    for geom, isVoid in customZip3("long", lst_geom, lst_isVoid):
        OUT.append(NewForm(geom, isVoid))
    TransactionManager.Instance.TransactionTaskDone()
4 Likes

Thanks Soren, I ran your script but still I can see the shape but not work with it.

Thank you @c.poupin, it worked and created the volume in the family document as @sovitek shown me before.

However, trying to include the node in the script with the BIMmorphe, it doesn’extrudes the cad layers either as surface or solid. I must be doing something wrong with the lists or lacing. My bad, I am still fresh. :weary_face:

I have also installed the PythonNet3 packages just in case. I appreciate your help.

2 Likes

These images show that the shapes you are selecting font form closed curves. Can you isolate one of them in a 3D view before running the graph so we can understand what the geometry you are starting with is doing? To use extrude as solid you need curves which form a cluster loop.

2 Likes

Hi Jacob,

Does the view below work? Basically it’s a column joinery what I need to extrude.

Starts to - select the chain of lines and see if you get a single closed loop.

My guess is that you don’t. It’ll be many segments disjointed, or overlapping, or crossing. I recommend processing the file in AutoCAD first to get closed polycurves on unique layers, or extracting to an intermediate file (i.e. open the DWG in Dynamo for Civil 3D, select the closed polylines, use Object.Geometry to extract the curve loop and convert to polycurves, write the polycurves out to JSON, read the JSON into Dynamo for Revit and use that to create the solids).

1 Like

Hi Jacob,

I worked already on the CAD file, basically I set everything as polyline by the same layer. I checked everything was enclosed by placing some hatches in autocad.

I cannot find Object.Geometry, but I have tried with Element.Geometry, as shown below. I may not follow all the steps you mentioned earlier to run the routine.

However, I tried to Extrude.AsSolid the hole shape but it’s partially works. It covered some gaps, and there some missing some bits.


Also, I noticed there are some issue with spring Form to generate the geometry in Revit


That would be in Dynamo for Civil3D, not Dynamo for Revit.

You are passing invalid data into the node, so you are going to get this error.

If they are all in the same layer you are not going to be able to generate closed polylines, as the right side of curve A will have an overlap with the left side of curve B. That will mean that the PolyCurve will branch in some cases, which is shown in your shape by the voids. You want a single closed polyline per layer (not just closed openings - the workflow you are building is selecting line by line segment by line segment in a continuous loop where the end of curve 1 becomes the start of curve 2, end of 2 becomes the start of 3, 3 to 4, and 4 to 1 if you were building a rectangle), or better yet preprocess and in Civil 3D and export to an intermediate file which is read into Revit to build the forms. Faster and more accurate that way in my experience.

Overall when I look at this shape, it feels like you are over modeling to some extent - the blocking on the inside won’t be seen, nor will some of the interior gaps, and some of the pieces are quite small - Revit has a minimum tolerance after all. i would strongly consider making one loop for the outside face, nothing more.

Thanks @jacob.small, I complicated myself by trying to invent the wheel. :zany_face:

In the end the routine worked as you mentioned. Then, by just deleting the “spare” solid the extrusion was done in few seconds. Besides, it process the extrusion as a freeform with an specific material.

I have attached some screenshots if anyone is interested.

Also, I would like to thank to @sovitek @c.poupin and @Mike.Buttery they gave me all the insights to complete this as well.

Much appreciated for your help. :sports_medal:



3 Likes