"Invalid Splitting Tool" while trying to use splitBodyFeatures.add with a Profile

"Invalid Splitting Tool" while trying to use splitBodyFeatures.add with a Profile

FusionMaxR
Participant Participant
557 Views
4 Replies
Message 1 of 5

"Invalid Splitting Tool" while trying to use splitBodyFeatures.add with a Profile

FusionMaxR
Participant
Participant

Hi,

I am trying to split a Body with a Profile or a Sketch as a Splitting tool while using the api, but I alway get an error, that the splittingTool I use is not valid. How can I split a Body with the api while using a more complex geometry than a single sketchline? 

The Reference Manual gives some contradicting information about what can be used as an splittingTool:

 

SplitBodyFeatureInput Object --> "The splitting tool is a single entity that can be either a solid or open BRepBody,construction plane, profile, or a face."

 

SplitBodyFeature.setSplittingTool Method --> The splitting tool is a single entity that can be either a solid body, open body, construction plane, face, or sketch curve that partially or fully intersects the body to split.

 

Here is my Test-Code and a picture of my Test-Model:

#Author-
#Description-

import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        design: adsk.fusion.Design = app.activeProduct
        rootComp = design.rootComponent

        body = ui.selectEntity('Select a body', 'Bodies').entity
        splittingTool: adsk.fusion.Profile = ui.selectEntity('Select a face to split the body.','Profiles').entity

        isExtended = True
        splitBodyFeatures = rootComp.features.splitBodyFeatures
        input = splitBodyFeatures.createInput(body, splittingTool, isExtended)
        splitBodyFeature = splitBodyFeatures.add(input)

  
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

reinhardt7AXQY_0-1682081588820.png

 

 

0 Likes
Accepted solutions (1)
558 Views
4 Replies
Replies (4)
Message 2 of 5

kandennti
Mentor
Mentor

Hi @FusionMaxR .

 

I can reproduce the error, and also, when I set the splittingTool to surfaceBody, it did not cause the error.
I think it is a bug.

However, I think I can create an alternative.

0 Likes
Message 3 of 5

john.kirchner
Autodesk
Autodesk
Accepted solution

This is a bug, a profile should be a valid input for splittingTool - I will create a ticket for this to be fixed. In the meantime splittingTool should work with a ConstructionPlane, BRepBody, SketchCurve, or BRepFace.



0 Likes
Message 4 of 5

kandennti
Mentor
Mentor

@FusionMaxR .

 

I have thought of an alternative, but it is incomplete because it is an error in direct mode.

# Fusion360API Python script
import traceback
import adsk.core
import adsk.fusion

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        design: adsk.fusion.Design = app.activeProduct
        rootComp = design.rootComponent

        body: adsk.fusion.BRepBody = rootComp.bRepBodies[0]
        splittingTool: adsk.fusion.Profile = rootComp.sketches[0].profiles[0]

        exec_splitBody_by_profile_like(body, splittingTool)

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def exec_splitBody_by_profile_like(
    body: adsk.fusion.BRepBody,
    prof: adsk.fusion.Profile,
) -> None:

    def get_min_max_length( 
        body: adsk.fusion.BRepBody,
        vector: adsk.core.Vector3D,
        sktPlane: adsk.core.Plane,
    ) -> list[float, float]:

        measMgr: adsk.core.MeasureManager = app.measureManager
        bBox: adsk.core.OrientedBoundingBox3D = measMgr.getOrientedBoundingBox(
            body,
            vector,
            get_perpendicular_vector(vector),
        )

        offset = bBox.length * 0.5
        bBoxPoints = []
        for l in [offset, -offset]:
            vec: adsk.core.Vector3D = vector.copy()
            vec.scaleBy(l)
            pnt: adsk.core.Point3D = bBox.centerPoint.copy()
            pnt.translateBy(vec)
            bBoxPoints.append(pnt)

        infLine: adsk.core.InfiniteLine3D = adsk.core.InfiniteLine3D.create(
            bBox.centerPoint,
            vector,
        )
        origin: adsk.core.Point3D = sktPlane.intersectWithLine(infLine)

        lengths = []
        for p in bBoxPoints:
            dist = origin.distanceTo(p)

            vec = origin.vectorTo(p)
            vec.normalize()
            if vector.isEqualTo(vec):
                dist *= -1

            lengths.append(dist)
        
        return lengths


    def get_perpendicular_vector(
        vector: adsk.core.Vector3D,
    ) -> adsk.core.Vector3D:

        v: adsk.core.Vector3D = adsk.core.Vector3D.create(1,0,0)
        if vector.isParallelTo(v):
            v = adsk.core.Vector3D.create(0,1,0)

        return vector.crossProduct(v)


    def create_extrude(
        prof: adsk.fusion.Profile,
        lengths: list,
    )-> adsk.fusion.ExtrudeFeature:

        comp: adsk.fusion.Component = prof.parentSketch.parentComponent
        extrudeFeats: adsk.fusion.ExtrudeFeatures = comp.features.extrudeFeatures
        extrudeIpt: adsk.fusion.ExtrudeFeatureInput = extrudeFeats.createInput(
            prof,
            adsk.fusion.FeatureOperations.NewBodyFeatureOperation,
        )
        extrudeIpt.setTwoSidesExtent(
            adsk.fusion.DistanceExtentDefinition.create(
                adsk.core.ValueInput.createByReal(lengths[0])
            ),
            adsk.fusion.DistanceExtentDefinition.create(
                adsk.core.ValueInput.createByReal(lengths[1])
            ),
        )
        extrudeIpt.isSolid = False

        return extrudeFeats.add(extrudeIpt)


    def split_body(
        targetBody: adsk.fusion.BRepBody,
        toolBody: adsk.fusion.BRepBody,
    ) -> adsk.fusion.SplitBodyFeature:

        comp: adsk.fusion.Component = targetBody.parentComponent
        splitBodyFeats: adsk.fusion.SplitBodyFeatures = comp.features.splitBodyFeatures
        splitIpt: adsk.fusion.SplitBodyFeatureInput = splitBodyFeats.createInput(
            targetBody,
            toolBody,
            True,
        )

        return splitBodyFeats.add(splitIpt)


    def remove_body(
        targetBody: adsk.fusion.BRepBody,
    ) -> adsk.fusion.RemoveFeature:

        comp: adsk.fusion.Component = targetBody.parentComponent
        removeFeats: adsk.fusion.RemoveFeatures = comp.features.removeFeatures

        return removeFeats.add(targetBody)

    # *******
    app: adsk.core.Application = adsk.core.Application.get()
    des: adsk.fusion.Design = app.activeProduct

    if des.designType == adsk.fusion.DesignTypes.ParametricDesignType:
        tl: adsk.fusion.Timeline = des.timeline
        startPos = tl.markerPosition

    skt: adsk.fusion.Sketch = prof.parentSketch

    minMaxLength = get_min_max_length(
        body,
        skt.xDirection.crossProduct(skt.yDirection),
        skt.referencePlane.geometry
    )

    extrudeFeat: adsk.fusion.ExtrudeFeature = create_extrude(
        prof,
        minMaxLength,
    )

    split_body(
        body,
        extrudeFeat.bodies[0]
    )

    remove_body(extrudeFeat.bodies[0])

    if tl:
        try:
            tl.timelineGroups.add(startPos, tl.markerPosition -1)
        except:
            pass


When I do SplitBody manually, it seems to be responding to the profile loop rather than responding to the profile.
However, the error also occurred in the profile loop.

0 Likes
Message 5 of 5

FusionMaxR
Participant
Participant

Thank you for your help kandennti and john.kirchner. For now I could change my process to use combines, CutFeatureOperation which works fine. I will keep an eye open for the bug to be fixed and then maybe will change my process back to the intended way. 

Regards Max