Another powerful feature of the scripting interface is the Script Based Export. Arbitrary python commands can be executed during model generation via callback methods.
Script-based export template
- Create a new python export script from template File > New... > Python > Python Module
- Choose Module: Export (Reporting) as template
Export callback functions
When a new module is created from the export template, the following callback methods are present:
initExport | Called before the export starts |
initModel | Called for each shape before generation. |
finishModel | Called for each shape after generation. |
finishExport | Called after all shapes are generated. |
Such a script can be used for
- the Script based Export (Python)
This "exporter" generates the models and executes the attached python script in parallel. No geometry files are created.
- Any geometry exporter
The models are generated and exported as usual, the attached python script is executed in parallel.
Example : Processing CGA report data
The following code snippet is a typical example of a CGA rule that reports data during generation.
FloorArea --> report("area", geometry.area)
Reported data can be accessed using the export callback functions.
The code below gives an example of how report data can be accessed and written to a file.
'''
Created on Nov 6, 2013
@author: andi
'''
from scripting import *
# Get a CityEngine instance
ce = CE()
REPORT = ""
def initExport(exportContextOID):
global REPORT
REPORT = "Name,#Floors,totalFloorArea,averageFloorArea\n"
def finishModel(exportContextOID, shapeOID, modelOID):
shape = Shape(shapeOID)
model = Model(modelOID)
global REPORT
i = 0
totalArea = 0.0
reports = model.getReports()
if 'area' in reports.keys():
for area in reports['floorArea']:
totalArea +=area
i+=1
REPORT += "%s,%d,%f,%f\n" % (ce.getName(shape), i, area, area/i)
else :
REPORT += "%s,%d,%f,%f\n" % (model, 0, 0, 0)
def finishExport(exportContextOID):
filename = ce.toFSPath("models/"+"/reportdata.txt")
FILE = open(filename, "w")
FILE.write(REPORT)
FILE.close()
In this case, the resulting comma-separated file contains the following data:
Name | #Floors | totalFloorArea | avgFloorArea |
---|---|---|---|
LotSouth_35 | 5 | 357.3825 | 71.47651 |
LotSouth_37 | 4 | 335.8072 | 83.95179 |
LotSouth_38 | 3 | 379.4594 | 126.4865 |
... | ... | ... | ... |
Specific methods in callback functions
These Python methods only work in callback functions
method | description |
---|---|
returns dict of CGA report() data | |
returns tuple of local/global export offsets |
Checking Module Name
To prevent code outside the callback methods from being executed when the exporter calls the script, the module attribute __name__ can be used to distinguish the caller.
if __name__ == '__main__':
#only do stuff is script is started directly
This allows to have a script that can both be used for normal Python exection as well as for script-based export, e.g.
def finishModel(exportContextOID, shapeOID, modelOID):
# export callback code
if __name__ == '__main__':
exportSettings = OBJExportModelSettings()
exportSettings.setScript("/general/scripts/scriptbasedexport.py")
ce.export(ce.selection(), exportSettings)
In the example above the main clause will not be executed when the script is called by the script-based exporter
Module names in different contexts
Resulting module name __name__ in different contexts:
Context | Module Name |
---|---|
context is being run by itself | __main__ |
context is started from exporter | __export__ |
context is started on startup procedure | __startup__ |
See also