Issues creating an empty surface with dynamo

I’m trying to use Dynamo to import and clip a DEM. The process: create empty surface → add data clip boundary → add DEM. However, I cannot find a working way to create an empty surface. I’ve tried using a bit of code found here:

However, this code no longer seems to work. Every time the python node tries to grab the surface style styleId = cdoc.Styles.SurfaceStyles[styleName] an exception is thrown.

Could anyone point me in the right direction?

Hi
Can you share the python code you are working on?
and an example file

Since I’m just creating a surface from scratch any file will do. The error occurs when I attempt to subscript the style list e.g. “styleId = cdoc.Styles.SurfaceStyles[0]”. Remove the “[0]” and the error goes away. But I don’t know enough about the API to say why it’s behaving this way. As I understand it, I’ll need the style from this list for the TinSurface.Create() function.

Load the Python Standard and DesignScript Libraries

import sys
import clr

Add Assemblies for AutoCAD and Civil3D

clr.AddReference(‘AcMgd’)
clr.AddReference(‘AcCoreMgd’)
clr.AddReference(‘AcDbMgd’)
clr.AddReference(‘AecBaseMgd’)
clr.AddReference(‘AecPropDataMgd’)
clr.AddReference(‘AeccDbMgd’)

Import references from AutoCAD

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 *

Import references from Civil3D

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

The inputs to this node will be stored as a list in the IN variables.

surfaceName = IN[0]
styleName = IN[1]

adoc = Application.DocumentManager.MdiActiveDocument
editor = adoc.Editor

with adoc.LockDocument():
with adoc.Database as db:

    with db.TransactionManager.StartTransaction() as t:
        cdoc = CivilApplication.ActiveDocument
        
        # list of existing Surfaces
        #SurfaceIds = cdoc.GetSurfaceIds()
        #for surfaceId in SurfaceIds:
        #   oSurface = surfaceId.GetObject(OpenMode.ForRead)
        #  if oSurface.Name == surfaceName:
        #      myEnt = t.GetObject(surfaceId, OpenMode.ForWrite)
        #      myEnt.Erase(True)

        # Select a Surface style to us
        styleId = cdoc.Styles.SurfaceStyles[0]
        #styleId = styleId_list[0]
        #styleId = cdoc.Styles.SurfaceStyles[styleName]
        # Create an empty TIN Surface
        #surfaceId = TinSurface.Create(surfaceName, styleId)
        #newSurface.append(surfaceId)
        # get Object
        # surface = t.GetObject(surfaceId, OpenMode.ForRead)
        # Commit before end transaction
        t.Commit()
        pass

Assign your output to the OUT variable.

OUT = styleId

Hi
Try



import clr

clr.AddReference('AcDbMgd')
clr.AddReference('AeccDbMgd')
clr.AddReference('AutoCADNodes')
clr.AddReference('Civil3DNodes')   

from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
import Autodesk.AutoCAD.DynamoNodes as DA
import Autodesk.Civil.DynamoNodes as DC

adoc = Application.DocumentManager.MdiActiveDocument
cdoc = CivilApplication.ActiveDocument

def create_tin():

    
    global adoc
    global cdoc

    with adoc.LockDocument():
        with adoc.Database as db:    
            with db.TransactionManager.StartTransaction() as t:
                surfId = TinSurface.Create(db, "test")
                surf = t.GetObject(surfId, OpenMode.ForWrite)

                t.Commit()
                pass
    return surf

OUT = create_tin()







Hi all,

The last code sample does work, but i had the next code working in C3D 2021, in 2022 it’s not working anymore. Does anyone has a solution?

The lines

  • styleId = cdoc.Styles.SurfaceStyles[styleName]
  • surfaceId = TinSurface.Create(surfaceName, styleId)
    don’t work anymore

Load the Python Standard and DesignScript Libraries

import sys
import clr
import math

Add Assemblies for AutoCAD and Civil 3D APIs

clr.AddReference(‘AcDbMgd’)
clr.AddReference(‘AeccDbMgd’)
clr.AddReference(‘AutoCADNodes’)
clr.AddReference(‘Civil3DNodes’)

Import references from AutoCAD

from Autodesk.AutoCAD.ApplicationServices import *
from Autodesk.AutoCAD.DatabaseServices import *

Import references from Civil3D

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

import Autodesk.AutoCAD.DynamoNodes as DA
import Autodesk.Civil.DynamoNodes as DC

#Import References from dynamo
from Autodesk.AutoCAD.DynamoNodes import SelectionByQuery

The inputs to this node will be stored as a list in the IN variables.

surfaceName = IN[0]
styleName = IN[1]
MaximumTriangleLength = IN[2]
MaximumAngleBetweenAdjacentTinLines = IN[3]
deleteSurface = IN[4]

adoc = Application.DocumentManager.MdiActiveDocument

def delSurface(surfaceName):
global adoc
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
cdoc = CivilApplication.ActiveDocument
# list of existing Surfaces
SurfaceIds = cdoc.GetSurfaceIds()
for surfaceId in SurfaceIds:
oSurface = surfaceId.GetObject(OpenMode.ForRead)
if oSurface.Name == surfaceName:
myEnt = t.GetObject(surfaceId, OpenMode.ForWrite)
myEnt.Erase(True)
# Commit before end transaction
t.Commit()

def selSurface(surfaceName):
global adoc
surface = “”
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
cdoc = CivilApplication.ActiveDocument
# list of existing Surfaces
SurfaceIds = cdoc.GetSurfaceIds()
for surfaceId in SurfaceIds:
oSurface = surfaceId.GetObject(OpenMode.ForRead)
if oSurface.Name == surfaceName:
obj = t.GetObject(surfaceId, OpenMode.ForRead)
# Commit before end transaction
t.Commit()
surface = SelectionByQuery.GetObjectByObjectHandle(str(obj.Handle))

return surface
#==============================================================================================

Boolean {deleteSurface}

True => delete surface and create new surface

False => Select surface

#==============================================================================================
newSurface =
surfaceId=""
styleId=""

if deleteSurface == False:
newSurface = selSurface(surfaceName)

if deleteSurface == True:
delSurface(surfaceName)

with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
cdoc = CivilApplication.ActiveDocument
print(“Start - Create surface”)
# Select a Surface style to use
styleId = cdoc.Styles.SurfaceStyles[styleName]
print(styleId)
# Create an empty TIN Surface
surfaceId = TinSurface.Create(surfaceName, styleId)
print(surfaceId)
# get Object
surface = t.GetObject(surfaceId, OpenMode.ForRead)
#newSurface.append (surface)
#surfId = TinSurface.Create(db, “test”)
#surf = t.GetObject(surfId, OpenMode.ForWrite)

       # Commit before end transaction
       t.Commit()
       pass
       newSurface = SelectionByQuery.GetObjectByObjectHandle(str(surfaceId.Handle))

Assign your output to the OUT variable.

OUT = newSurface

Hi i think wrong in writing name style

Try using
styleId = cdoc.Styles.SurfaceStyles[1]

Hi @hosneyalaa ,

Unfortunately that doesn’t work, if you take a look at the link:

The sample code:

//change the style
ObjectId styleId;
if (civilDoc.Styles.SurfaceStyles.Contains(“Standard”))
{
styleId = civilDoc.Styles.SurfaceStyles[“Standard”];
}
else
{
// create a new style called ‘example style’:
styleId = civilDoc.Styles.SurfaceStyles
.Add(“example style”);

}
// modify the style
SurfaceStyle surfaceStyle = styleId.GetObject(
OpenMode.ForWrite) as SurfaceStyle;

My code must work, as it did before.

Hi @JPS
what do you want to do You create a surface
and then change its style
Or
do you want Create a new surface style
and modify it

Because this is a different topic

I want to use an existing style.

First find the ID and then change the style.

Q10

1 Like

FYI there are dedicated nodes for this in the Camber package starting in v4.0.0.