Wrong dimension of splitted body

Jorge_Jaramillo
Collaborator

Wrong dimension of splitted body

Jorge_Jaramillo
Collaborator
Collaborator

Hi all,

 

I developed the following code to split and arrange splitted bodies vertically:

 

def slice_body() -> None:
    # -----------------------------------------------------
    # INPUT parameters:
    # -----------------------------------------------------
    prm_width: float = 2.5 # slices of 25mm
    prm_space: float = 1.0 # spaces of 10mm
    orig_body: adsk.fusion.BRepBody = root.bRepBodies[0]  # first body in the root component
    DEBUG: float = True
    # -----------------------------------------------------

    if DEBUG:
        skt: adsk.fusion.Sketch = root.sketches.add(root.xYConstructionPlane)
    
    sliced_occ: adsk.fusion.Occurrence = root.occurrences.addNewComponent(adsk.core.Matrix3D.create())
    sliced_occ.isGroundToParent = False
    sliced_comp: adsk.fusion.Component = sliced_occ.component
    sliced_comp.name = 'sliced_body'

    sliced_cut_occ: adsk.fusion.Occurrence = sliced_comp.occurrences.addNewComponent(adsk.core.Matrix3D.create())
    sliced_cut_comp = sliced_cut_occ.component
    sliced_cut_comp.name = 'to_cut'

    sliced_pos_occ: adsk.fusion.Occurrence = sliced_comp.occurrences.addNewComponent(adsk.core.Matrix3D.create())
    sliced_pos_comp = sliced_pos_occ.component
    sliced_pos_comp.name = 'positives'

    sliced_neg_occ: adsk.fusion.Occurrence = sliced_comp.occurrences.addNewComponent(adsk.core.Matrix3D.create())
    sliced_neg_comp = sliced_neg_occ.component
    sliced_neg_comp.name = 'negatives'

    cpb: adsk.fusion.CopyPasteBody = sliced_pos_comp.features.copyPasteBodies.add(orig_body)
    body_to_slice: adsk.fusion.BRepBody = cpb.bodies[0]
    min_point: adsk.core.Point3D = body_to_slice.boundingBox.minPoint.copy()
    mfi = sliced_pos_comp.features.moveFeatures.createInput2(
        adsk.core.ObjectCollection.createWithArray([body_to_slice]))
    mfi.defineAsTranslateXYZ(
        adsk.core.ValueInput.createByReal(-min_point.x),
        adsk.core.ValueInput.createByReal(-min_point.y),
        adsk.core.ValueInput.createByReal(-min_point.z),
        True
    )
    sliced_pos_comp.features.moveFeatures.add(mfi)
    max_point: adsk.core.Point3D = body_to_slice.boundingBox.maxPoint.copy()
    app.log(f'{body_to_slice.boundingBox.minPoint.asArray()=} {max_point.asArray()=}')

    yy: float = 0
    top_z: float = -prm_space
    num_slices = 0
    while (yy < max_point.y):
        app.log(f' ... # {num_slices+1}')
        yy += prm_space if num_slices%2 else prm_width
        if (yy < max_point.y):
            cpi = sliced_comp.constructionPlanes.createInput(sliced_occ)
            cpi.setByOffset(sliced_comp.xZConstructionPlane, adsk.core.ValueInput.createByReal(yy))
            cp = sliced_comp.constructionPlanes.add(cpi)
            cp.name = f'y-{yy}'

            sbi = sliced_pos_comp.features.splitBodyFeatures.createInput(body_to_slice, cp, True)
            sbf = sliced_pos_comp.features.splitBodyFeatures.add(sbi)
            if sbf.bodies.count == 2:
                mp = [b.boundingBox.minPoint.y for b in sbf.bodies]
                
                if mp[0] < mp[1]:
                    slice = sbf.bodies[0]
                    body_to_slice = sbf.bodies[1]
                else:
                    slice = sbf.bodies[1]
                    body_to_slice = sbf.bodies[0]
            else:
                app.log(f'split result in {sbf.bodies.count} bodies')
                return
        else:
            slice = body_to_slice
        if num_slices % 2:
            cpb: adsk.fusion.CopyPasteBody = sliced_neg_comp.features.copyPasteBodies.add(slice)
            # slice.deleteMe() ### crash if the body is deleted
            slice.isVisible = False  # to hide it instead
        else:
            cpb: adsk.fusion.CopyPasteBody = sliced_cut_comp.features.copyPasteBodies.add(slice)
            mfi = sliced_cut_comp.features.moveFeatures.createInput2(
                adsk.core.ObjectCollection.createWithArray([cpb.bodies[0]]))
            mfi.defineAsTranslateXYZ(
                adsk.core.ValueInput.createByReal(0),
                adsk.core.ValueInput.createByReal(-prm_width*3-yy),
                adsk.core.ValueInput.createByReal(top_z + prm_space),
                True
            )
            mf = sliced_cut_comp.features.moveFeatures.add(mfi)
            top_z = mf.bodies[0].boundingBox.maxPoint.z
            if DEBUG:
                skt.sketchCurves.sketchLines.addByTwoPoints(
                    adsk.core.Point3D.create(0, 0, top_z),
                    adsk.core.Point3D.create(40, 0, top_z)
                )
                app.log(f'   ... {top_z+prm_space=}')
        num_slices += 1
        adsk.doEvents()

 

 

This algorithm works fine except for the 7th piece:

Jorge_Jaramillo_0-1720381538964.png

 

Look that there is a very small gap between 7th and 8th parts.  I'm expecting 10mm.

Checking the result of the bounding box in line #89 where it set the Z coordinate for the next item based on the height of the current item, it returned 22.116 mm instead of 30.767 mm.

In order to check the dimensions I created a sketch and project the profiles of item 7th and 8th and then draw lines to measure the distances:

Jorge_Jaramillo_2-1720382116600.png

 

Look that the 22.116 mm it reports is the same as it get it from the bounding box property, but is NOT the real height dimension of the body.  Length and width are ok.  It looks like it is taking the back face to define its Z dimension, but the front face is still higher.

 

Could it be a BUG in Fusion 360? 

I hope someone from Fusion360 API team could look at it.

I worry I could not trust on this dimension to complete my development.

 

Attached is the design I used in this test if someone want to make test on your side (it take first body in root component to be copied and splitted according to the input parameters at the beginning of the function).

 

Regards,

Jorge

 

0 Likes
Reply
152 Views
0 Replies
Replies (0)