I am developing a Python script tool to transform a 2D feature class into a multipatch.
Right now, I have to split the script into 2 scripts and manually do the extrusion, because I cannot figure out how to make the extrusion based on a field. I could apply a fixed extrusion by writing:
Solved! Go to Solution.
You can get the value field from a SearchCursor and then use it in your expression.
expression = str(list(set([hgts[0] for hgts in arcpy.da.SearchCursor(fc, 'Field holding hgt')]))[0])
This will grab the first value from the distinct list in case your field has multiple differing values.
To conclude on the subject, in case someone encountered the same difficulty:
I managed to finish my script to create a multipatch fc from a 2d polygon fc. I had 2 huge hurdles: the extrusion and the symbology. For the extrusion, I decided to use Python CIM access. I created an extrusion object with my field as expression and I updated the CIM definition of my layer. For the symbology, I applied the workaround already discussed: creating a new layer and using updateConnectionProperties on the new layer.
You can get the value field from a SearchCursor and then use it in your expression.
expression = str(list(set([hgts[0] for hgts in arcpy.da.SearchCursor(fc, 'Field holding hgt')]))[0])
This will grab the first value from the distinct list in case your field has multiple differing values.
Thanks a lot, it worked perfectly and I would never have thought of it!
Sorry to ask again, but I just realized that it did not work completely for me. The extrusion expression holds only one value (the one of the first feature), so the extrusion is the same for all the features in the layer.
I tried to pass the list of field values (which would match each feature with its field value) but no extrusion happened. Any suggestions? Thanks again.
I was wondering about that and was going to add a warning that it would set every feature to that single height... I don't think there is mechanism yet for 'extrude by attribute' programmatically beyond this single value. That polygon image in the docs is a little misleading and I think it was the result of the manual process they listed below... but, the expression parameter makes me curious if one could use an arcade expression there...
"return $feature.HeightField"
I haven't seen anything regarding arcade in arcpy so I'd be surprised if that worked. Might be worth posting this to the ideas section.
Yes the doc is very misleading. You would think that because it is written expression, you could enter more than one value!
I had noticed too that the expression for the feature layer extrusion in Pro offered only Arcade and VBScript. I tried your suggestion for returning an Arcade expression, but no success as you feared it. Thanks again for your help. I think I may end up splitting my layer by extrusion values, do the extrusion for each, run arcpy.Layer3DToFeatureClass_3d on each and combined all the features.
To conclude on the subject, in case someone encountered the same difficulty:
I managed to finish my script to create a multipatch fc from a 2d polygon fc. I had 2 huge hurdles: the extrusion and the symbology. For the extrusion, I decided to use Python CIM access. I created an extrusion object with my field as expression and I updated the CIM definition of my layer. For the symbology, I applied the workaround already discussed: creating a new layer and using updateConnectionProperties on the new layer.
@clc , how did you end up modifying the cim extrusion. I am not finding any python documentation for this. Thanks
I used: CreateCIMObjectFromClassName found in the Creating CIM objects section of https://pro.arcgis.com/en/pro-app/latest/arcpy/mapping/python-cim-access.htm#
Here is my code:
# Get the layer CIM definition of my layer to be extruded
cim_lay = lay.getDefinition('V2')
# Create a CIM object
cim_obj = arcpy.cim.CreateCIMObjectFromClassName('CIMFeatureExtrusion','V2')
cim_obj.extrusionType = 'Base'
cim_obj.extrusionUnit = {'uwkid': 9002}
cim_obj.extrusionExpressionInfo.expression = '$feature.Extrusion_ft'
# Set the extrusion property
cim_lay.extrusion = cim_obj
Hope this helps. Catherine
Thanks Catherine. I also knocked it out. I noticed in Pro 3.1 that my 2D layer would not move to 3D without marking isflattened to false. Just for anyone else trying to do this.