MBuehler-esristaff

classification approach towards (volumetric) multiPatch data

Discussion created by MBuehler-esristaff Employee on Feb 29, 2012
hi !

in an other thread, a user has asked how non-attributed multiPatches, once imported into the CityEngine and thus converted to shapes, can be 'classified' based on their volumetric appearence. here's one strategic approach that handles this issue in CGA code. please note this example provides only an 'experimental brain construct' and not a proper solution.

a classification like this, once it provides acceptable results, can be further broken down into each meshe's subshapes (single polygons) and e.g. test the shape orientation for proper texturing.
polygon orientation classification could be done as proposed in this thread :
http://forums.arcgis.com/threads/51546-Calculating-shape-slopes

* * *

let's have a look at the task at hand :

let's assume your multiPatch data has NO attributes imported, e.g. because the multiPatch data comes from unknown origin or it's been converted from kml and you need to texture all objects as well as possible.

left : imported shapes without any attributes | right : classified subvolumes
[ATTACH=CONFIG]12304[/ATTACH]


so what the process is actually about is to analyze all the volumes geometrically and track down each possible type of object to classify it.
volumes, which are wider and higher than e.g. a room are classified as 'building'
volumes, which are less thick than 0.5 meters, higher than 2 meters and longer than 2 meters are classified as 'wall'
and so on.


the following code shows an initial, very crude, example of such classification.

note the initial alignScopeToGeometry() operation, which aligns the scope ( http://forums.arcgis.com/threads/44417-CGA-Understanding-the-concept-of-the-scope ) to the longest edge of the volume, thus lets a volume be measured semantically. e.g. scope.sx is the 'length', scope.sy is the 'height', scope.sz is the 'depth'

now, a series of attributes for minima and maxima of specific classification types can be defined and checked one after each other to classify the volumes.


special objects, such as the roof railing wall - as seen on the right side of the screenshot - may have a scope which does not represent the actual volumetric appearence properly since the scope (the scope is visible in the screenshot !) is a 'bounding box'. thus, some genius is required to write the classification rules to cleverly classify also elements like this.



##################################################################################################################
# attributes
##################################################################################################################

attr minBuildingPartWidth  = 3
attr minBuildingPartHeight  = 2.5
attr minBuildingPartDepth = 3

attr maxSmallBoxWidth  = .6
attr maxSmallBoxHeight  = 1.2

attr maxBigBoxWidth  = 6
attr maxBigBoxHeight  = 3

attr wallThickness  = 0.5
attr wallMinHeight  = 2



@StartRule
Shape -->
 alignScopeToGeometry(yUp, world.lowest, longest)  # scope.sx is aligned to the longest edge, scope.sy points upwards
 alignScopeToAxes(y)         # orient scope.sy exactly vertical
 ShapeDimensions(scope.sx, scope.sy, scope.sz)
 print(scope.sx)
 print(scope.sy)
 print(scope.sz)

ShapeDimensions(xDim, yDim, zDim) -->
 # large volumes
 case xDim > minBuildingPartWidth && yDim > minBuildingPartHeight && zDim > minBuildingPartDepth :
  ShapeType("building")
 # wall like volumes
 case (xDim < wallThickness && yDim > wallMinHeight) || (zDim < wallThickness && yDim > wallMinHeight) :
  ShapeType("wall")
 # big box like structures
 case xDim < maxBigBoxWidth && yDim < maxBigBoxHeight && zDim < maxBigBoxWidth :
  ShapeType("bigBox")
 # small box like structures
 case xDim < maxSmallBoxWidth && yDim < maxSmallBoxHeight && zDim < maxSmallBoxWidth :
  ShapeType("smallBox")

 else:
  ShapeType("Element")


ShapeType(type) -->
 case type == "building" :
  color(1,0,0)
 case type == "wall" :
  color(0,0,0)
 case type == "smallBox" :
  color(.95,1,0)
 case type == "bigBox" :
  color(.5,.5,0)
 else :
  color(1,1,1)
 

Attachments

Outcomes