Split file by layers

Hi guys!

Is it possible to create a routine that creates an individual file for each layer of my dwg containing only its objects?

I know it does not sound like a good practice, but sometimes we must deal with the problems as they appear… :sweat_smile:

Also, I’ve found a LISP that seems to do that but I’m not sure about its safety, have any of you used it?

(https://www.cadforum.cz/en/qaID.asp?tip=3682)

Hi @apegaia,

If you’re able to upgrade to Civil 3D 2025.1, there is a new node called Object.Export that seems like a good fit for this. You could group your objects by layer using the List.GroupByKey node, then decide on the file naming scheme that you want to use.

4 Likes

For older verisons of Dynamo, you can use this code:

import sys
import os
import clr

clr.AddReference('acmgd')
clr.AddReference('acdbmgd')
clr.AddReference('accoremgd')
clr.AddReference('AecBaseMgd')
clr.AddReference('AecPropDataMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AeccPressurePipesMgd')
clr.AddReference('acdbmgdbrep')
clr.AddReference('System.Windows.Forms')

from System import *
from System.IO import *
from System.Collections.Specialized import *
from System.Windows.Forms import MessageBox

from Autodesk.AutoCAD.Runtime import *
from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.EditorInput import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.AutoCAD.Geometry import *

from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *

aDoc = Application.DocumentManager.MdiActiveDocument
cDoc = CivilApplication.ActiveDocument
ed = aDoc.Editor

def WBlockMultiple(paths, objectSets):
    if len(paths) != len(objectSets):
        return "The number of file paths must match the number of object sets."

    global aDoc
    global ed

    for i in range(len(paths)):
        path = paths[i]
        oHand = objectSets[i]

        oic = ObjectIdCollection()

        with aDoc.Database as db:
            tr = db.TransactionManager.StartTransaction()
            with tr:
                try:
                    for handle in oHand:
                        newhandleint = int(handle, 16)
                        hexa = Handle(newhandleint)
                        oid = db.GetObjectId(False, hexa, oHand.index(handle))
                        oic.Add(oid)

                    with Database(True, False) as newdb:
                        db.Wblock(newdb, oic, Point3d.Origin, DuplicateRecordCloning.Ignore)
                        newdb.SaveAs(path, DwgVersion.Newest)
                    
                    ed.WriteMessage(f"\nSuccessfully saved to {path}")
                except Exception as e:
                    ed.WriteMessage(f"\nThe process failed for {path}: {str(e)}")
                    return "The process failed for one or more paths."
    
    return 'Completed'

paths = IN[0]
objectSets = IN[1]

Log = WBlockMultiple(paths, objectSets)

OUT = Log
2 Likes

Thanks! Good to know we’ll have a native way of doing so! I think I’ll use it on future projects!

Man, you’re literally a legend!!

I was thinking with myself if there was any way to use the wblock function to do this, and I think adapting this script will be really perfect to do so!!

Really can’t thank you enough for this! Hahah

1 Like