Script-based export

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
Creating a new Python module from the export template
Creating a new Python module from the export 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.

OBJ export dialog with script set in Misc options
OBJ export dialog with script set in Misc options

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#FloorstotalFloorAreaavgFloorArea

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

methoddescription

model.getReports()

returns dict of CGA report() data

model.getOffsets()

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:

ContextModule Name

context is being run by itself

__main__

context is started from exporter

__export__

context is started on startup procedure

__startup__

 

See also