Multiple LandXML export of TinSurfaces

Hi,

I’m trying to export multiple LandXML fails from one dwg fail with Dynamo. There is an requirement that we have to export every single pavement surfaces to different landXML. I’m trying to create a dynamo script that will help me first of all identify all the tin surfaces in modelspace, secondly find the find all surfaces with similar pavement name and regroupe them under the right name. After that it has to export all the tin surfaces with a correct LandXML fail name to a specific folder. I have done the first two parts with an ease, but struggling to export the surfaces into landXML. I used chatGPT to make a custom Python node, which also seems to run on many issus - it seems like I solve one issue, but then find another one.
Here is my dynamo script:

And this is the the custom node:
"import clr
clr.AddReference(‘AcMgd’)
clr.AddReference(‘AcDbMgd’)
clr.AddReference(‘AecBaseMgd’)
clr.AddReference(‘AeccDbMgd’)

import Autodesk.AutoCAD.ApplicationServices as acApp
import Autodesk.AutoCAD.DatabaseServices as acDb
import Autodesk.Civil.ApplicationServices as civilApp
import Autodesk.Civil.DatabaseServices as civilDb
import System

Sisendid

surfacesIn = IN[0] # 2nd order list of Dynamo TinSurface wrapper objects
titles = IN[1] # List of export group names
filePathBase = IN[2] # Base path like “C:\Temp\Export”

doc = acApp.Application.DocumentManager.MdiActiveDocument
db = doc.Database
civdoc = civilApp.CivilApplication.ActiveDocument # CivilDocument objekt

results =
trans = None

try:
trans = db.TransactionManager.StartTransaction()

# Leia kõik pinnad dokumendist
surfIds = civdoc.SurfaceIds  # See on ObjectIdCollection
surfaceMap = {}

# Ehita nimi -> ObjectId map
for surfId in surfIds:
    surfObj = trans.GetObject(surfId, acDb.OpenMode.ForRead)
    if hasattr(surfObj, "Name"):
        surfaceMap[surfObj.Name] = surfId

# Käi läbi kõik sisendid
for i, surfaceGroup in enumerate(surfacesIn):
    title = titles[i] if i < len(titles) else "Untitled"

    for j, dynSurface in enumerate(surfaceGroup):
        try:
            if dynSurface is None:
                results.append("Skipped: surface is None at group {}, index {}".format(i, j))
                continue

            # Hangi pinna nimi Dynamo wrapperist
            surfName = dynSurface.Name
            if surfName not in surfaceMap:
                results.append("Skipped: surface '{}' not found in Civil doc".format(surfName))
                continue

            surfId = surfaceMap[surfName]
            civilSurface = trans.GetObject(surfId, acDb.OpenMode.ForRead)

            if hasattr(civilSurface, "ExportToLandXml"):
                outPath = "{}_{}_{}.xml".format(filePathBase, title.replace(" ", "_"), j)
                civilSurface.ExportToLandXml(outPath, True, True, True)
                results.append("Exported: " + outPath)
            else:
                results.append("Skipped: AeccTinSurface has no ExportToLandXml")
        except Exception as innerEx:
            results.append("Inner error [{}][{}]: {}".format(i, j, str(innerEx)))

trans.Commit()

except Exception as e:
if trans is not None:
try:
trans.Abort()
except:
pass
results.append("Fatal error: " + str(e))

OUT = results
"

Here are the dynamo and Civil 3D files. Does anybody have an idea why my solution just doesn’t to the export part? Has anyone got a better solution for my problem?
LandXML Export2.dyn (30.0 KB)
LandXML.dwg (4.5 MB)

Best regards
Eno

@eno.lints
Can you please
show us where you found Surface Method
civilSurface.ExportToLandXml(outPath, True, True, True)
in API CIVIL 3D

Well, I don’t see any methods for that either in the .NET reference or the COM API.
So, I don’t know if there is an easy solution.
You can try document.sendcommand, but the dialogless version of landxmlout doesn’t support object selection, so the only way I can think of is using the nodes in a python (or designscript) loop: put all objects to dref, then in a new dwg, in python loop for every input shortcut–>create reference–>run landxlmout using sendcommand with custom path for every file like “path + f”{surfacename}.xml", then delete the referenced object. So in theory it will run the export only with one surface. Because of the lack of object selection I don’t think LISP will work either.
So right now I cannot think of anything better.

Also this would be a great addition to the API and Dynamo, because more and more contracting companies are requesting LandXML files for construction. @zachri.jensen

EDIT: I think I found a non Dynamo solution for you:

I haven’t tested it but as of the comments it should work.

Honestly I think exporting to a single land xml and then post processing will be faster than multiple exports as the capability to edit XMLs as standalone documents is pretty straight forward.

Seems like a POC would take a day for a Python tool (Python is ideal for processing text like this), with full support in about two weeks (localization of data in the file is a beast for this type of task).

I agree, but a Python tool requires at least some vibe coding, and creating a robust tool requires more knowledge that not everyone has access to.
I think an OOTB solution (export node) for controlled automation would fit better with average end users.
But yeah, in the current state of things postprocessing it is.

Nah - the need is pretty straight forward, XML is pretty cut and dry as a format, and the effort would be minimal to none. It would also be usable outside of Civil3D so Civil users could do the export once and then start processing it with Dynamo sandbox or even Dynamo as a Service, and Revit/Forma users could read in only the data they need.

Honestly the more I think about it the more I wonder why we don’t have a good package for working with LandXMLs…

1 Like

Hi again, thanks for the replys. As Jacob suggested, the solution was to export all the surfaces into landXML and then import this landXML into another dwg drawing. And with dynamo I am able to delete unneccesary surfaces and make the correct XML-s as I need.

Where this need comes from is our projects. Last project we had to share with client around 3700 surfaces, eksported into 47 XML-s. Doing this manually will “cost” us a day and possibility to make mistakes is huge. Doing it automatically can be done in just an hour or even less. If Autodesk can add some LandXML nodes into Civil3D toolkit package, would be awesome.

I got closer to a solution I’m looking for, so thanks.
Best regards
Eno Lints

1 Like