Display an Arrow at the Centroid of Selected Faces

Goal

The following script creates an arrow annotation and places it at the centroid on each specified face. The length of each arrow is half of the value of the Bounding Box of the face.

Code

for geoId in  ExtAPI.SelectionManager.CurrentSelection.Ids :
    geoEntity=ExtAPI.DataModel.GeoData.GeoEntityById(geoId)
    if geoEntity.Type != GeoCellTypeEnum.GeoFace :
        print("Only faces are supported")
        continue
   
    # Get the centroid of the face in CAD units
    locationCAD = geoEntity.Centroid

    # Get the normal of the face at the centroid
    params = geoEntity.ParamAtPoint(geoEntity.Centroid)
    direction = geoEntity.NormalAtParam(params[0], params[1])
   
    # Create the arrow, set size at half the bounding box length of the face
    bbox = geoEntity.GetBoundingBox()
    sizeCAD = sqrt((bbox[0]-bbox[3])**2 + (bbox[1]-bbox[4])**2 + (bbox[2]-bbox[5])**2)
    arrow = ExtAPI.Graphics.Scene.Factory3D.CreateArrow(sizeCAD/2)
    arrow.Visible = False
    # Set the color to red
    arrow.Color=0xFF0000

    # Align the arrow
    x = direction[0]
    y = direction[1]
    z = direction[2]
    r = sqrt(y*y+z*z)
    arrow.Transformation3D.Rotate(ExtAPI.Graphics.CreateVector3D(0,1,0), atan2(x,r))
    arrow.Transformation3D.Rotate(ExtAPI.Graphics.CreateVector3D(1,0,0), atan2(z,y) - pi/2.0)
    arrow.Transformation3D.Translate(locationCAD[0],locationCAD[1],locationCAD[2])
   
    ExtAPI.Graphics.Scene.Visible = True
    arrow.Visible = True
    print user_dir