I would like to get some working examples of using the civil 3d api with pythonnet.
For instance below here is an extract from a python script written by @Paolo_Emilio_Serra1 and slighly modified by me for multi input , it worked ok in IronPython but because of Pythonnet not having strongbox functionality I am having trouble understanding the correct method ref /out values, I have read the other threads:
https://forum.dynamobim.com/t/new-feature-preview-python-3-support-issue-thread/51649/61
and here:
http://pythonnet.github.io/
So I can see these generic examples for passing a “dummy” value and that pythonnet returns a python Tuple but I just cant get it to work without crashing dynamo/CAD when trying the code below and variations (trying without understanding!).
As always your advise is most appreciated, and I hope this thread can act as a focal point for any issues with pythonnet and civil 3d api, and upgrading older code.
# original by @Paolo_Emilio_Serra1 and copyright autodesk 2019
# modified in 2021 to allow for multi input
# Load the Python Standard and DesignScript Libraries
import clr
#import System
# Add Assemblies for AutoCAD and Civil 3D APIs
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')
# Add standard Python references
import sys
#sys.path.append('C:\Program Files (x86)\IronPython 2.7\Lib')
import os
import math
# Add references to manage arrays, collections and interact with the user
from System import *
from System.IO import *
from System.Collections.Specialized import *
from System.Windows.Forms import MessageBox
# Create an alias to the Autodesk.AutoCAD.ApplicationServices.Application class
#import Autodesk.AutoCAD.ApplicationServices.Application as acapp
# 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 for PropertySets
from Autodesk.Aec.PropertyData import *
from Autodesk.Aec.PropertyData.DatabaseServices import *
# Import references for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
adoc = Application.DocumentManager.MdiActiveDocument
cdoc = CivilApplication.ActiveDocument
ed = adoc.Editor
names=IN[0]
northings=IN[1]
eastings=IN[2]
# Example function
def get_soe_by_en(name, easting, northing):
"""
Returns a list with station and offset from the alignment.
"""
global adoc
global cdoc
s1 = "station" #dummy inputs as per advice on other threads
o1 = "offset"
# use float as no longer able to use
# - strongbox functionality as per ironpython i.e. Double #clr.Reference[float]()
station = 1.23
offset = 1.23
output = []
nm=[]
sta=[]
offs=[]
with adoc.LockDocument():
with adoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
bt = t.GetObject(db.BlockTableId, OpenMode.ForWrite)
btr = t.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite)
alignment = None
for ind,x in enumerate(name):
#ind=name.index(i)
for oid in cdoc.GetSitelessAlignmentIds():
al = t.GetObject(oid, OpenMode.ForRead)
if al.Name == name[ind]:
alignment = al
# so trying to use 'dummy' inputs and station offset will be returned to assigned float vars?
station,offset=alignment.StationOffset(easting[ind], northing[ind],s1,o1)
sta.append(station)
offs.append(offset)
break
# Couldn't find the alignment with the given name
if alignment is None:
return
#need to allow for start and and points and for flipping osl and os right points
return [sta, offs]
OUT = get_soe_by_en(names, northings, eastings)