Help on API script to create a sphere at both ends of a path

Help on API script to create a sphere at both ends of a path

2way3dtext
Contributor Contributor
696 Views
2 Replies
Message 1 of 3

Help on API script to create a sphere at both ends of a path

2way3dtext
Contributor
Contributor

I would like for the script attached below to create a sphere at both ends of a selected path.

 

This code creates two sketches, one for each end of a selected path. Even though the code to create the circles and lines on each sketch is identical, only one of the profiles can be revolved, while the other is considered an invalid profile for a revolve feature.

 

May I receive some advice on fixing this issue?

 

I have also tried using the following command to copy and paste the successfully revolved sphere to the opposite end point of the path, however I received an error when trying to run that script as well.

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

kandennti
Mentor
Mentor
Accepted solution

Hi @2way3dtext .

 

I only saw "Error Script revolve both ends".

The easiest solution was to get the profile just before doing revolves.createInput.

・・・
        profile_2 = sketch_2.profiles.item(0)
        profile_1 = sketch_1.profiles.item(0) # <-Here

        # Create an revolution input to be able to define the input needed for a revolution
        # while specifying the profile and that a new component is to be created
        revolves = comp.features.revolveFeatures
        revInput_1 = revolves.createInput(
            profile_1, axisLine_1, adsk.fusion.FeatureOperations.NewComponentFeatureOperation)
        revInput_2 = revolves.createInput(
            profile_2, axisLine_2, adsk.fusion.FeatureOperations.NewComponentFeatureOperation)
・・・

I don't know the exact cause of the error, but I think it's because I'm creating Dimensions and Constraints after getting the profile.

 

I think if you get what you need when you need it, you can avoid the error.
(There are so many variables in one function that I can't keep track of them all in my head.)

 

 

If I were to Refactoring this, it would be the creation of two sketches that would be needed as profiles.
If I were to refactoring this, I would create two sketches that I would need as profiles, and since the two sketches are almost identical, I would consider having them processed by a single function.

import adsk.core
import adsk.fusion
import adsk.cam
import traceback
import math

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        design = app.activeProduct
        unitsMgr = design.fusionUnitsManager
        unitsMgr.distanceDisplayUnits = adsk.fusion.DistanceUnits.MillimeterDistanceUnits

        # pipe diameter
        pipeDiameter = 1
        pipeRadius = pipeDiameter * 0.5

        # select edge
        sel = ui.selectEntity(
            'Select a path to create a pipe', 'Edges,SketchCurves')
        selObj = sel.entity
        comp = design.rootComponent

        # create path
        feats = comp.features
        chainedOption = adsk.fusion.ChainedCurveOptions.noChainedCurves
        path = adsk.fusion.Path.create(selObj, chainedOption)

        # get construction Planes
        planes = comp.constructionPlanes

        # create construction plane_1
        planeInput = planes.createInput()
        planeInput.setByDistanceOnPath(
            selObj, adsk.core.ValueInput.createByReal(0))
        plane_1 = planes.add(planeInput)

        # create construction plane_2
        planeInput.setByDistanceOnPath(
            selObj, adsk.core.ValueInput.createByReal(1))
        plane_2 = planes.add(planeInput)

        # create Profile Sketch
        sketch_1: adsk.fusion.Sketch = createProfileSketch(plane_1, pipeRadius)
        sketch_2: adsk.fusion.Sketch = createProfileSketch(plane_2, pipeRadius)

        # Create an revolution input to be able to define the input needed for a revolution
        # while specifying the profile and that a new component is to be created
        revolves = comp.features.revolveFeatures
        revInput_1 = revolves.createInput(
            sketch_1.profiles[0],
            sketch_1.sketchCurves.sketchLines[0],
            adsk.fusion.FeatureOperations.NewBodyFeatureOperation
        )

        revInput_2 = revolves.createInput(
            sketch_2.profiles[0],
            sketch_2.sketchCurves.sketchLines[0],
            adsk.fusion.FeatureOperations.NewBodyFeatureOperation
        )

        # Define that the extent is an angle of 2*pi to get a sphere
        angle = adsk.core.ValueInput.createByReal(2*math.pi)
        revInput_1.setAngleExtent(False, angle)
        revInput_2.setAngleExtent(False, angle)

        # Create the extrusion.
        ext_1 = revolves.add(revInput_1)
        ext_2 = revolves.add(revInput_2)

        # Create an object collection to use an input.
        profs = adsk.core.ObjectCollection.create()

        # Add all of the profiles to the collection.
        for prof in sketch_2.profiles:
            profs.add(prof)

        # create sweep
        sweepFeats = feats.sweepFeatures
        sweepInput = sweepFeats.createInput(
            profs, path, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        sweepInput.orientation = adsk.fusion.SweepOrientationTypes.PerpendicularOrientationType
        sweepFeat = sweepFeats.add(sweepInput)

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


def createProfileSketch(
        refPlane: adsk.fusion.ConstructionPlane,
        pipeRadius: float) -> adsk.fusion.Sketch:

    # get sketches
    sketches: adsk.fusion.Sketches = refPlane.component.sketches

    # create sketch
    sketch: adsk.fusion.Sketch = sketches.add(refPlane)

    # circle
    circles: adsk.fusion.SketchCircle = sketch.sketchCurves.sketchCircles
    circle: adsk.fusion.SketchCircle = circles.addByCenterRadius(
        adsk.core.Point3D.create(0, 0, 0), pipeRadius)

    # axis line
    lines: adsk.fusion.SketchLines = sketch.sketchCurves.sketchLines
    axisLine: adsk.fusion.SketchLine = lines.addByTwoPoints(
        adsk.core.Point3D.create(-pipeRadius, 0, 0),
        adsk.core.Point3D.create(pipeRadius, 0, 0)
    )

    # dimension
    dimensions: adsk.fusion.SketchDimensions = sketch.sketchDimensions
    dimensions.addDistanceDimension(
        axisLine.startSketchPoint,
        axisLine.endSketchPoint,
        adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,
        circle.centerSketchPoint.geometry
    )

    textPoint: adsk.core.Point3D = circle.centerSketchPoint.geometry
    textPoint.translateBy(
        adsk.core.Vector3D.create(0.001, 0.001, 0.001)
    )
    dimensions.addRadialDimension(circle, textPoint)

    # geometricConstraints
    constraints: adsk.fusion.GeometricConstraints = sketch.geometricConstraints
    constraints.addCoincident(
        axisLine.startSketchPoint,
        circle
    )

    constraints.addCoincident(
        axisLine.endSketchPoint,
        circle
    )
    constraints.addHorizontal(axisLine)

    setDimension(circle)

    return sketch


def setDimension(
        self: adsk.fusion.SketchCircle):

    skt: adsk.fusion.Sketch = self.parentSketch
    ori: adsk.fusion.SketchPoint = skt.sketchPoints.item(0)
    ctr: adsk.fusion.SketchPoint = self.centerSketchPoint
    ary = [(o + c) * 0.5 for (o, c) in
           zip(ori.geometry.asArray(), ctr.geometry.asArray())]
    mid: adsk.core.Point3D = ori.geometry.copy()
    mid.setWithArray(ary)

    dims: adsk.fusion.SketchDimensions = skt.sketchDimensions
    h = adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation
    v = adsk.fusion.DimensionOrientations.VerticalDimensionOrientation

    dims.addDistanceDimension(ori, ctr, h, mid, True)
    dims.addDistanceDimension(ori, ctr, v, mid, True)

 

This is still not enough.

Message 3 of 3

2way3dtext
Contributor
Contributor

Dear @kandennti