I’m trying to create a function in Python that will produce earthwork and material volume reports for all the materials in a sample line group (similar to the _AeccGenerateQuantitiesReport command). I have managed to get the total volume result data for each material list in a sample line group but struggling to find a method in the .net API that exposes what’s in the total volume result data.
Attached is a drawing to test the python script with. Any suggestions would be much appreciated.
# Load Python standard libraries
import clr
# 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')
clr.AddReference('Civil3DNodes')
# 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 for Civil 3D
from Autodesk.Civil.ApplicationServices import *
from Autodesk.Civil.DatabaseServices import *
# 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 *
# Declare global variables
aDoc = acApp.DocumentManager.MdiActiveDocument
ed = aDoc.Editor
cDoc = CivilApplication.ActiveDocument
# Functions
def get_slg_vol_result():
"""
This method gets the total volume result data for material list
associated with a sampleline group.
:param mappingGuid:
:return: Volume result data.
"""
global aDoc
global ed
global cDoc
# Instantiate empty lists
mNames = []
mGuids = []
matNames = []
volumes = []
result = []
error_report = None
try:
# Get the active document in the AutoCAD session:
with aDoc.LockDocument():
with aDoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
# Get the objectId collection of all Alignment objects in the drawing
alignmentId = cDoc.GetAlignmentIds()
# Get the alignment
for a in alignmentId:
alignment = t.GetObject(a, OpenMode.ForRead)
# Get the object collection of all sample line groups
# belonging to alignment
for s in alignment.GetSampleLineGroupIds():
slg = t.GetObject(s, OpenMode.ForRead)
# Get the SLG QTO Mapping Names
mNames = slg.GetQTOMappingNames()
# Get the SLG mapping global unique identifier
for m in mNames:
mGuid = slg.GetMappingGuid(m)
mGuids.append(mGuid)
# Get material names in mapping and total volume
# result data for material list
for n in mGuids:
matName = slg.GetMaterialNamesInMapping(n)
matNames.append(matName)
volume = slg.GetTotalVolumeResultDataForMaterialList(n)
volumes.append(volume)
result = [mNames, mGuids, matNames, volumes]
except:
import traceback
error_report = traceback.format_exc()
if error_report == None:
return result
else:
return error_report
# Output
OUT = get_slg_vol_result()
Hi @Kulkul - for starters it’s fantastic to see what I’m trying to achieve is possible in Python . To be clear I’m trying to access all the results used to create these reports:
# 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.
dataEnteringNode = IN
aDoc = Application.DocumentManager.MdiActiveDocument
editor = aDoc.Editor
cDoc = CivilApplication.ActiveDocument
def get_slg_vol_result():
"""
This method gets the total volume result data for material list
associated with a sampleline group.
:param mappingGuid:
:return: Volume result data.
"""
global aDoc
global ed
global cDoc
# Instantiate empty lists
mNames = []
mGuids = []
matNames = []
volumes = []
volumeres = []
result = []
error_report = None
try:
# Get the active document in the AutoCAD session:
with aDoc.LockDocument():
with aDoc.Database as db:
with db.TransactionManager.StartTransaction() as t:
# Get the objectId collection of all Alignment objects in the drawing
alignmentId = cDoc.GetAlignmentIds()
# Get the alignment
for a in alignmentId:
alignment = t.GetObject(a, OpenMode.ForRead)
# Get the object collection of all sample line groups
# belonging to alignment
for s in alignment.GetSampleLineGroupIds():
slg = t.GetObject(s, OpenMode.ForRead)
# Get the SLG QTO Mapping Names
mNames = slg.GetQTOMappingNames()
# Get the SLG mapping global unique identifier
for m in mNames:
mGuid = slg.GetMappingGuid(m)
mGuids.append(mGuid)
# Get material names in mapping and total volume
# result data for material list
for n in mGuids:
matName = slg.GetMaterialNamesInMapping(n)
matNames.append(matName)
volume = slg.GetTotalVolumeResultDataForMaterialList(n)
##volumetype = volume.kMaterialStructureVolume
volumes.append(volume)
qtoSectionalResult = volume.GetResultsAlongSampleLines()
length = qtoSectionalResult.Length
for i in range(length):
qtoAtStation = qtoSectionalResult[i]
volumeresatstation = qtoAtStation.VolumeResult
fill = volumeresatstation.IncrementalFillVolume
volumeres.append(fill)
result = [mNames, mGuids, matNames, qtoSectionalResult,volumeres]
return result
except:
import traceback
error_report = traceback.format_exc()
# Output
OUT = get_slg_vol_result()
Well in my understanding this is a dead end. As for now, I think it is not possible to get structure volume numbers directly from QTO via the API.
Another approach we are thinking of, is to somehow get the shape areas from AppliedAssemblies–>CalculatedShapes and calculate the volumes from there, but this needs time, as I have designing duties besides my free time programming activities