Poor performance building body using the new BRepBodyDefinition

Poor performance building body using the new BRepBodyDefinition

JesusFreke
Advocate Advocate
304 Views
0 Replies
Message 1 of 1

Poor performance building body using the new BRepBodyDefinition

JesusFreke
Advocate
Advocate

I've been experimenting with the new BRepBodyDefinition functionality, but I've found its performance to be a bit lacking, especially when compared to stitching together faces with a StitchFeature.

 

For example, below is a standalone script that creates the helical shape below, first using a BRepBodyDefinition, and then using a Stitch feature.

 

JesusFreke_0-1604636901307.png

 

The version using BRepBodyDefinition takes about 10s to run. While the version using a Stitch feature runs in .2s - 50x faster than the BRepBodyDefinition version.

 

from adsk.core import Point3D, Vector3D
import adsk.fusion
import time
import traceback


def app():
    return adsk.core.Application.get()


def design() -> adsk.fusion.Design:
    return adsk.fusion.Design.cast(app().activeProduct)


def root() -> adsk.fusion.Component:
    return design().rootComponent


def brep() -> adsk.fusion.TemporaryBRepManager:
    return adsk.fusion.TemporaryBRepManager.get()


def create_line_definition(
        body_def: adsk.fusion.BRepBodyDefinition,
        start_point: adsk.fusion.BRepVertexDefinition,
        end_point: adsk.fusion.BRepVertexDefinition):
    return body_def.createEdgeDefinitionByCurve(
        start_point, end_point,
        adsk.core.Line3D.create(start_point.position, end_point.position))


def create_occurrence(*bodies):
    new_occurrence = root().occurrences.addNewComponent(adsk.core.Matrix3D.create())
    for body in bodies:
        new_occurrence.component.bRepBodies.add(body)
    return new_occurrence


def collection_of(collection):
    object_collection = adsk.core.ObjectCollection.create()
    for obj in collection:
        object_collection.add(obj)
    return object_collection


def create_face_for_planar_lines(wires):
    wire_body, _ = brep().createWireFromCurves(wires, allowSelfIntersections=False)
    return brep().createFaceFromPlanarWires([wire_body])


def ruled_helical_triangle_via_brep_def(inner_radius: float, outer_radius: float, height: float, pitch: float, turns: float):
    body_def = adsk.fusion.BRepBodyDefinition.create()
    lump_def = body_def.lumpDefinitions.add()
    shell_def = lump_def.shellDefinitions.add()

    start_point_defs = [
        body_def.createVertexDefinition(
            Point3D.create(inner_radius, 0, 0)),
        body_def.createVertexDefinition(
            Point3D.create(outer_radius, 0, 0)),
        body_def.createVertexDefinition(
            Point3D.create(outer_radius, 0, height))]

    helixes = [
        brep().createHelixWire(
            axisPoint=Point3D.create(0, 0, 0),
            axisVector=Vector3D.create(0, 0, 1),
            startPoint=point.position,
            pitch=pitch,
            turns=turns,
            taperAngle=0) for point in start_point_defs]

    end_point_defs = [body_def.createVertexDefinition(helix.edges[0].endVertex.geometry) for helix in helixes]

    helix_edge_defs = [
        body_def.createEdgeDefinitionByCurve(start_point_defs[i], end_point_defs[i], helixes[i].edges[0].geometry)
        for i in range(3)]

    start_edge_defs = [
        create_line_definition(body_def, start_point_defs[0], start_point_defs[1]),
        create_line_definition(body_def, start_point_defs[1], start_point_defs[2]),
        create_line_definition(body_def, start_point_defs[2], start_point_defs[0])
    ]

    end_edge_defs = [
        create_line_definition(body_def, end_point_defs[1], end_point_defs[0]),
        create_line_definition(body_def, end_point_defs[2], end_point_defs[1]),
        create_line_definition(body_def, end_point_defs[0], end_point_defs[2])
    ]

    helix_surfaces = [
        brep().createRuledSurface(helixes[0].wires[0], helixes[1].wires[0]),
        brep().createRuledSurface(helixes[1].wires[0], helixes[2].wires[0]),
        brep().createRuledSurface(helixes[2].wires[0], helixes[0].wires[0])
    ]

    face_def = shell_def.faceDefinitions.add(helix_surfaces[0].faces[0].geometry, isParamReversed=False)
    loop_def = face_def.loopDefinitions.add()
    loop_def.bRepCoEdgeDefinitions.add(start_edge_defs[0], False)
    loop_def.bRepCoEdgeDefinitions.add(helix_edge_defs[0], False)
    loop_def.bRepCoEdgeDefinitions.add(end_edge_defs[0], False)
    loop_def.bRepCoEdgeDefinitions.add(helix_edge_defs[1], True)

    face_def = shell_def.faceDefinitions.add(helix_surfaces[1].faces[0].geometry, isParamReversed=False)
    loop_def = face_def.loopDefinitions.add()
    loop_def.bRepCoEdgeDefinitions.add(start_edge_defs[1], False)
    loop_def.bRepCoEdgeDefinitions.add(helix_edge_defs[1], False)
    loop_def.bRepCoEdgeDefinitions.add(end_edge_defs[1], False)
    loop_def.bRepCoEdgeDefinitions.add(helix_edge_defs[2], True)

    face_def = shell_def.faceDefinitions.add(helix_surfaces[2].faces[0].geometry, isParamReversed=False)
    loop_def = face_def.loopDefinitions.add()
    loop_def.bRepCoEdgeDefinitions.add(start_edge_defs[2], False)
    loop_def.bRepCoEdgeDefinitions.add(helix_edge_defs[2], False)
    loop_def.bRepCoEdgeDefinitions.add(end_edge_defs[2], False)
    loop_def.bRepCoEdgeDefinitions.add(helix_edge_defs[0], True)

    face_def = shell_def.faceDefinitions.add(
        adsk.core.Plane.create(
            Point3D.create(0, 0, 0),
            Vector3D.create(0, -1, 0)), isParamReversed=False)
    loop_def = face_def.loopDefinitions.add()
    loop_def.bRepCoEdgeDefinitions.add(start_edge_defs[0], False)
    loop_def.bRepCoEdgeDefinitions.add(start_edge_defs[1], False)
    loop_def.bRepCoEdgeDefinitions.add(start_edge_defs[2], False)

    face_def = shell_def.faceDefinitions.add(
        adsk.core.Plane.create(
            Point3D.create(0, 0, 0),
            Vector3D.create(0, -1, 0)), isParamReversed=False)
    loop_def = face_def.loopDefinitions.add()
    loop_def.bRepCoEdgeDefinitions.add(end_edge_defs[0], False)
    loop_def.bRepCoEdgeDefinitions.add(end_edge_defs[1], False)
    loop_def.bRepCoEdgeDefinitions.add(end_edge_defs[2], False)

    body_def.doFullHealing = False

    return body_def.createBody()


def ruled_helical_triangle_via_stitching(
        inner_radius: float, outer_radius: float, height: float, pitch: float, turns: float):
    start_points = [
        Point3D.create(inner_radius, 0, 0),
        Point3D.create(outer_radius, 0, 0),
        Point3D.create(outer_radius, 0, height)]

    helixes = [
        brep().createHelixWire(
            axisPoint=Point3D.create(0, 0, 0),
            axisVector=Vector3D.create(0, 0, 1),
            startPoint=point,
            pitch=pitch,
            turns=turns,
            taperAngle=0) for point in start_points]

    end_points = [helix.edges[0].endVertex.geometry for helix in helixes]

    start_lines = [
        adsk.core.Line3D.create(start_points[0], start_points[1]),
        adsk.core.Line3D.create(start_points[1], start_points[2]),
        adsk.core.Line3D.create(start_points[2], start_points[0])
    ]

    end_lines = [
        adsk.core.Line3D.create(end_points[1], end_points[0]),
        adsk.core.Line3D.create(end_points[2], end_points[1]),
        adsk.core.Line3D.create(end_points[0], end_points[2])
    ]

    helix_surfaces = [
        brep().createRuledSurface(helixes[0].wires[0], helixes[1].wires[0]),
        brep().createRuledSurface(helixes[1].wires[0], helixes[2].wires[0]),
        brep().createRuledSurface(helixes[2].wires[0], helixes[0].wires[0])
    ]

    start_face = create_face_for_planar_lines(start_lines)
    end_face = create_face_for_planar_lines(end_lines)

    occurrence = create_occurrence(
        *helix_surfaces, start_face, end_face)

    stitch_input = root().features.stitchFeatures.createInput(
        collection_of(occurrence.bRepBodies),
        adsk.core.ValueInput.createByReal(app().pointTolerance),
        adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

    root().features.stitchFeatures.add(stitch_input)

    body = brep().copy(occurrence.bRepBodies[0])

    occurrence.deleteMe()

    return body

def run(_):
    try:
        new_doc = app().documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        new_doc.activate()
        design().designType = adsk.fusion.DesignTypes.DirectDesignType

        start_time_ns = time.perf_counter_ns()
        root().bRepBodies.add(ruled_helical_triangle_via_brep_def(5, 6, .5, 1, 50))
        end_time_ns = time.perf_counter_ns()
        print("via brep definition: %f" % ((end_time_ns - start_time_ns) / 1.0e9))
        
        start_time_ns = time.perf_counter_ns()
        root().bRepBodies.add(ruled_helical_triangle_via_stitching(5, 6, .5, 1, 50))
        end_time_ns = time.perf_counter_ns()
        print("via stitching: %f" % ((end_time_ns - start_time_ns) / 1.0e9))
    except:
        traceback.print_exc()

 

 

 

 

 

 

 

305 Views
0 Replies
Replies (0)