Bounding Box applied via Python API on Mesh body does not track when mesh is moved

Bounding Box applied via Python API on Mesh body does not track when mesh is moved

muhammad_hilmi
Explorer Explorer
438 Views
0 Replies
Message 1 of 1

Bounding Box applied via Python API on Mesh body does not track when mesh is moved

muhammad_hilmi
Explorer
Explorer

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:

muhammad_hilmi_0-1612416182275.png

expected result when code is re-run after box has been moved

muhammad_hilmi_1-1612416235325.png

expected result when code is re-run after box is rotated

muhammad_hilmi_2-1612416284346.png

 

 

However, when applied to a mesh, I get these results.

Prior to translation:

muhammad_hilmi_3-1612416325489.png

after translation:

muhammad_hilmi_4-1612416421211.png

 

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)

 

 

 

 

0 Likes
439 Views
0 Replies
Replies (0)