Problem getting Bounding Box After Creating a Pattern Feature. Need the Bounding Box of the Occurrence that Contains the Pattern.

Problem getting Bounding Box After Creating a Pattern Feature. Need the Bounding Box of the Occurrence that Contains the Pattern.

ebunn3
Advocate Advocate
418 Views
2 Replies
Message 1 of 3

Problem getting Bounding Box After Creating a Pattern Feature. Need the Bounding Box of the Occurrence that Contains the Pattern.

ebunn3
Advocate
Advocate

Hi,

 

I have attached some code below that will create a pattern feature of a selected component.  That part works fine.  Problem is, without terminating the code, I want to pull the bounding box of the occurrence that holds the pattern feature.  You will see when running the code that the bounding box for that occurrence returns all zeros.  If I allow the macro to finish and subsequently re-run just the code on the bottom ("getOccurrencesByCompName") to get the bounding box of the occurrence I get an accurate bounding box:

 

#DEACTIVATE THE PATTERN FEATURE CODE AND RUN THIS TO SEE THAT IT DOES RETURN THE BOUNDNING BOX BUT ONLY WORKS AFTER THE PATTERN CODE TERMINATES
occ = getOccurrencesByCompName('Main_Rect_Pattern_Z')
bbMin = occ[0].boundingBox.minPoint
bbMax = occ[0].boundingBox.maxPoint

print(bbMin.x,bbMin.y,bbMin.z)
print(bbMax.x,bbMax.y,bbMax.z)

 

  I do not want to terminate the code and have to re-run this other code to gain access to the bounding box information.  I need it while the original code is still running.

 

Looking for a work around for this problem.  Is there a way to re-calculate the fusion model so I can pull the bounding box measurements while the code is still running?  The bounding box must reflect the pattern feature in the component.

 

Here is the full code for the pattern feature.  You just need a model with a component in it to select.  Sample model attached as well.

 

Eric

 

import adsk.core, adsk.fusion, traceback

def addExistingComponent(newComp,destComp):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface

        des: adsk.fusion.Design = app.activeProduct
        root = des.rootComponent
        occ = destComp.occurrences.addExistingComponent(newComp, adsk.core.Matrix3D.create())
        return occ
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))  

def rectangularPattern(srcComp,quantity1,distance1,quantity2,distance2,compName,zDir = False):
    """ creates a rectangular pattern feature for a selected component.
    pass in the selected occurrence and quantity1,distance1,quantity2,distance2 all
    as strings"""
    def traverseForBodies(occs,lst):
        """gets all bodies in occurence, including bodies in childOccurences
        lst = list()
        traverseForBodies(product,lst)"""
        if not occs.bRepBodies.count == 0:
            for bod in occs.bRepBodies:
                if bod.isVisible:lst.append(bod)
        try:
            #check child occurences
            if occs.childOccurrences:
                occChild = occs.childOccurrences
                for child in occChild:
                    traverseForBodies(child,lst)
        except:
            pass
    def PatternBodies(  srcComp: adsk.fusion.Component, 
                    destOccu: adsk.fusion.Occurrence,
                    quantityOne: adsk.core.ValueInput, 
                    distanceOne: adsk.core.ValueInput, 
                    quantityTwo: adsk.core.ValueInput, 
                    distanceTwo: adsk.core.ValueInput):
        try:
            #time the calculation
            import timeit
            start = timeit.default_timer()
            
            # Create input entities for rectangular pattern
            inputEntites = adsk.core.ObjectCollection.create()

            # lst = list()
            # traverseForBodies(srcComp,lst)
            # for i in lst:
            #     # copy bodies to dest component
            #     cpb = destOccu.component.features.copyPasteBodies.add(i)
            #     inputEntites.add(cpb.bodies[0])

            #this will pattern the source component within the destination occurrence (destOccu)
            #add and occurrence of the source component within the destination occurence
            if srcComp.objectType == 'adsk::fusion::Occurrence':
                copyComp = destOccu.component.occurrences.addExistingComponent(srcComp.component,adsk.core.Matrix3D.create())
            elif srcComp.objectType == 'adsk::fusion::Component':
                copyComp = destOccu.component.occurrences.addExistingComponent(srcComp,adsk.core.Matrix3D.create())

            #add copyComp to inputEntities to pattern
            inputEntites.add(copyComp)

            # Get x and y axes for rectangular pattern
            xAxis = destOccu.component.xConstructionAxis
            yAxis = destOccu.component.yConstructionAxis
            zAxis = destOccu.component.zConstructionAxis

            # Create the input for rectangular pattern
            rectangularPatterns = destOccu.component.features.rectangularPatternFeatures

            # Set the data for first direction
            if quantity1 != '1' and zDir == False:
                rectangularPatternInput = rectangularPatterns.createInput(inputEntites, xAxis, quantityOne, distanceOne, adsk.fusion.PatternDistanceType.SpacingPatternDistanceType)

            # Set the data for second direction
            if quantity2 != '1' and zDir == False:
                rectangularPatternInput.setDirectionTwo(yAxis, quantityTwo, distanceTwo)

            if zDir == True:
                rectangularPatternInput = rectangularPatterns.createInput(inputEntites, zAxis, quantityOne, distanceOne, adsk.fusion.PatternDistanceType.SpacingPatternDistanceType)
                #DirectionTwo must be set to 1 and distance of 0.00
                rectangularPatternInput.setDirectionTwo(yAxis, quantityTwo, distanceTwo)
                
            # Create the rectangular pattern
            rectangularFeature = rectangularPatterns.add(rectangularPatternInput)

            stop = timeit.default_timer()
            print('Pattern Time: ', stop - start) 

        except:
            app.log(f'Error in PatternBodies: {traceback.format_exc()}')

    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface     
        product = app.activeProduct
        des = adsk.fusion.Design.cast(product)
        desType = des.designType
        if desType == 0:
            des.designType = adsk.fusion.DesignTypes.ParametricDesignType 

        #source component to take bodies from
        rootComp = adsk.fusion.Design.cast(app.activeProduct).rootComponent

        #create the new component
        matrix = adsk.core.Matrix3D.create()
        destOccu = rootComp.occurrences.addNewComponent(matrix)
        destComp = destOccu.component
        destComp.name = compName

        # create ValueInput's for each dimension quantity1,distance1,quantity2,distance2
        quantityOne = adsk.core.ValueInput.createByString(quantity1)
        distanceOne = adsk.core.ValueInput.createByString(distance1 + ' cm')
        quantityTwo = adsk.core.ValueInput.createByString(quantity2)
        distanceTwo = adsk.core.ValueInput.createByString(distance2 + ' cm')

        PatternBodies(srcComp, destOccu, quantityOne, distanceOne, quantityTwo, distanceTwo)
        return srcComp, destComp
    except:
        app.log(f'Error in rectangularPattern: {traceback.format_exc()}')

def getOccurrencesByCompName(compName):
    """this function will get the component occurrences name.
    Pass in component name from tree and the occurrence will
    be returned as newC
    ret = getOccurrencesByCompName('XY_Bearing')"""
    app = adsk.core.Application.get()
    ui  = app.userInterface
    design = app.activeProduct
    root = design.rootComponent
    occ = root.occurrences.asList
    newC = list()
    for i in occ:
        if i.component.name == compName:
            name = i.fullPathName
            newC.append(occ.itemByName(name))
    return newC

#RUN THIS FIRST TO CREATE THE PATTERNS,  PRINTS ALL ZEROS FOR THE BOUNDING BOX.
app = adsk.core.Application.get()
ui  = app.userInterface

#Select body
comp = ui.selectEntity('Select a component', 'Occurrences').entity#.component
print("")
bbMin=comp.boundingBox.minPoint
bbMax=comp.boundingBox.maxPoint
prodL = bbMax.x-bbMin.x
prodW = bbMax.y-bbMin.y
prodH = bbMax.z-bbMin.z

quantityOne=str(4)
distanceOne=str(prodL)
quantityTwo=str(4)
distanceTwo=str(prodW)
ret = rectangularPattern(comp,quantityOne,distanceOne,quantityTwo,distanceTwo,'Main_Rect_Pattern_XY')

#create Z Array
quantityOne=str(5)
distanceOne=str(prodH)
quantityTwo=str(1)
distanceTwo=str(0.00)
ret = rectangularPattern(ret[1],quantityOne,distanceOne,quantityTwo,distanceTwo,'Main_Rect_Pattern_Z',True)

bbMin = ret[1].boundingBox.minPoint
bbMax = ret[1].boundingBox.maxPoint

print(bbMin.x,bbMin.y,bbMin.z)
print(bbMax.x,bbMax.y,bbMax.z)


# #DEACTIVATE THE PATTERN FEATURE CODE AND RUN THIS TO SEE THAT IT DOES RETURN THE BOUNDNING BOX BUT ONLY WORKS AFTER THE PATTERN CODE TERMINATES
# occ = getOccurrencesByCompName('Main_Rect_Pattern_Z')
# bbMin = occ[0].boundingBox.minPoint
# bbMax = occ[0].boundingBox.maxPoint

# print(bbMin.x,bbMin.y,bbMin.z)
# print(bbMax.x,bbMax.y,bbMax.z)

 

0 Likes
Accepted solutions (1)
419 Views
2 Replies
Replies (2)
Message 2 of 3

kandennti
Mentor
Mentor
Accepted solution

Hi @ebunn3 .

 

I found the cause.

・・・
        ret = rectangularPattern(ret[1],quantityOne,distanceOne,quantityTwo,distanceTwo,'Main_Rect_Pattern_Z',True)

        app.activeViewport.refresh() # <-here

        bbMin = ret[1].boundingBox.minPoint
        bbMax = ret[1].boundingBox.maxPoint
・・・

 

Why not use the "run" function?
It is very inconvenient.

Message 3 of 3

ebunn3
Advocate
Advocate

OMG!  Such a simple solution.  Thank you so much.  Coming from a Solidworks background I was searching for 'rebuild' instead of refresh.  I knew there had to be a similar function.

 

Eric