Bounding Box applied via Python API on Mesh body does not track when mesh is moved
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hello,
Ran into a strange issue. Using a modified version of ModTheMachine's Bounding Box Code, I found that it worked perfectly for BRepBodies. However, when I run my code on a MeshBody, it does not track the body if the body as been moved or rotated.
Some screenshots:
expected result when code is run:
expected result when code is re-run after box has been moved
expected result when code is re-run after box is rotated
However, when applied to a mesh, I get these results.
Prior to translation:
after translation:
While collecting these screenshots, I also discovered that the movement of the MeshBody cannot be undone via the timeline. How should I address this, to make the MeshBody outcome work the same way as the BRepBody? Thanks for the help in advance!
My code is below.
#Author-Hilmi Abideen
#Description-For generating a substrate body, based on existing geometry. A substrate will be created based on an existing plane and assigned a material.
import adsk.core, adsk.fusion, adsk.cam, traceback
clampDist = 2.5 #cm
testSuccess = False
failPoint = False
def run(context):
ui = None
try:
app = adsk.core.Application.get()
ui = app.userInterface
des = adsk.fusion.Design.cast(app.activeProduct)
target = ui.selectEntity('Select the body.', 'Bodies,MeshBodies').entity
ui.messageBox('Selected')
# # Draw the bounding box using a sketch.
sk = des.rootComponent.sketches.add(des.rootComponent.xYConstructionPlane)
drawXYBoundingBox(target, sk)
# Call the function to get the tight bounding box.
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
def drawXYBoundingBox(body, sketch):
ui = None
try:
bndBox= calculateTightBoundingBox(body)
# Draw the bounding box using a sketch.
# sk = sketch
lines = sketch.sketchCurves.sketchLines
minXYZ = bndBox.minPoint
minXYmaxZ = adsk.core.Point3D.create(bndBox.minPoint.x, bndBox.minPoint.y, bndBox.maxPoint.z)
minXmaxYZ = adsk.core.Point3D.create(bndBox.minPoint.x, bndBox.maxPoint.y, bndBox.maxPoint.z)
minXZmaxY = adsk.core.Point3D.create(bndBox.minPoint.x, bndBox.maxPoint.y, bndBox.minPoint.z)
maxXYZ = bndBox.maxPoint
maxXYminZ = adsk.core.Point3D.create(bndBox.maxPoint.x, bndBox.maxPoint.y, bndBox.minPoint.z)
maxXZminY = adsk.core.Point3D.create(bndBox.maxPoint.x, bndBox.minPoint.y, bndBox.maxPoint.z)
maxXminYZ = adsk.core.Point3D.create(bndBox.maxPoint.x, bndBox.minPoint.y, bndBox.minPoint.z)
# Draw Bounding Box Around base
# attempting to use rectangle
lines1 = lines.addTwoPointRectangle(minXYZ,maxXYminZ)
# create a set of curves that are offset clampDist from the body
dirPoint = adsk.core.Point3D.create(0, -1, 0)
curves = sketch.findConnectedCurves(lines1.item(0))
offsetCurves = sketch.offset(curves, dirPoint, clampDist)
ui.messageBox('Bounding Box Drawn')
return(None)
except:
# An error occurred so return None.
return(None)
# Calculates a tight bounding box around the input body. An optional
# tolerance argument is available. This specificies the tolerance in
# centimeters. If not provided the best existing display mesh is used.
def calculateTightBoundingBox(body, tolerance = 0):
try:
failPoint = True
# If the tolerance is zero, use the best display mesh available.
if body.objectType == adsk.fusion.MeshBody.classType():
#directly get point coordinates from an STL that is a mesh body.
triMesh = body.mesh
# ui.messageBox('Body is of Type Mesh')
elif tolerance <= 2:
# Get the best display mesh available.
bodyBrep = adsk.fusion.BRepBody.cast(body)
triMesh = bodyBrep.meshManager.displayMeshes.bestMesh
# ui.messageBox('Body is of Type BRep')
else:
# Calculate a new mesh based on the input tolerance.
meshMgr = adsk.fusion.MeshManager.cast(body.meshManager)
meshCalc = meshMgr.createMeshCalculator()
meshCalc.surfaceTolerance = tolerance
triMesh = meshCalc.calculate()
# ui.messageBox('Mesh was Calculate')
# Calculate the range of the mesh.
smallPnt = adsk.core.Point3D.cast(triMesh.nodeCoordinates[0])
largePnt = adsk.core.Point3D.cast(triMesh.nodeCoordinates[0])
vertex = adsk.core.Point3D.cast(None)
for vertex in triMesh.nodeCoordinates:
if vertex.x < smallPnt.x:
smallPnt.x = vertex.x
if vertex.y < smallPnt.y:
smallPnt.y = vertex.y
if vertex.z < smallPnt.z:
smallPnt.z = vertex.z
if vertex.x > largePnt.x:
largePnt.x = vertex.x
if vertex.y > largePnt.y:
largePnt.y = vertex.y
if vertex.z > largePnt.z:
largePnt.z = vertex.z
# Create and return a BoundingBox3D as the result.
global testSuccess
testSuccess = True
#ui.messageBox('Tight BB Calculated')
return(adsk.core.BoundingBox3D.create(smallPnt, largePnt))
except:
if ui:
# An error occurred so return None.
# ui.messageBox('Tight BB Failed')
return(None)