Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Creating a SketchArc

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
balunist
162 Views, 2 Replies

Creating a SketchArc

I could use some help.  Sorry in advance since this is probably something very basic to some. 

 

I want to create an arc in a sketch.  I have the startPoint, endPoint and radius.   There are two possible apis available.     

sketchArcs.addByCenterStartSweep(centerPoint, startPoint, sweepAngle)
and
sketchArcs.addByThreePoints(startPoint, alongPoint, endPoint) 

I was surprised that there was not a more direct route, giving the endpoints, radius and a direction point the way sketch.offset is handled.  So I've been trying to use the addByCenterStartSweep and I'm struggling. 

 

To get the centerPoint and sweep I was thinking (very likely wrongly) that I needed to do the following

  • get the midPoint between startPoint and endPoint
  • create a vector from midPoint to startPoint called it lineVector
  • create a Matrix3D call it rotate90 and setToRoation(pi / 2, axis, midPoint).  ?? axis = Z axis
  • rotate lineVector  90 degrees  with lineVector.transformBy(rotate90)
  • resize lineVector to radius,  lineVector.scaleBy(radius / lineVector.length)
  • create centerPoint using the lineVector's x,y,z. ??? 
  • create vector1 = centerPoint.vectorTo(startPoint) and vector2 = centerPoint.vectorTo(endPoint)
  • sweep = vector1.angleTo(vector2)
  • create the arc with sketchArcs.addByCenterStartSweep(centerPoint, startPoint, sweep)

 

Tags (1)
Labels (1)
2 REPLIES 2
Message 2 of 3
kandennti
in reply to: balunist

Hi @balunist .

 

If the only conditions are startPoint, endPoint, and radius, four arcs are candidates. I think that is why the method cannot be prepared.

1.png

 

I have created a sample that finds 4 transit points and creates all arcs.

# Fusion360API Python script

import traceback
import adsk.fusion
import adsk.core
import math
import itertools

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

        msg: str = 'Select Sketch Point(start)'
        selFilter: str = 'SketchPoints'
        sel: adsk.core.Selection = selectEnt(msg, selFilter)
        if not sel:
            return
        startPnt: adsk.fusion.SketchPoint = sel.entity

        msg = 'Select Sketch Point(end)'
        sel = selectEnt(msg, selFilter)
        if not sel:
            return
        endPnt: adsk.fusion.SketchPoint = sel.entity

        length = startPnt.worldGeometry.distanceTo(
            endPnt.worldGeometry
        )

        unitMgr: adsk.core.UnitsManager = des.unitsManager
        msg = 'Enter the radius.\n'
        msg += f'({unitMgr.formatInternalValue(length * 0.5)} or more)'
        res, cancelled = ui.inputBox(
            msg,
            '',
            str(
                    unitMgr.convert(
                    length * 0.5,
                    unitMgr.internalUnits,
                    unitMgr.defaultLengthUnits
                ) + 1
            )
        )

        if cancelled:
            return

        if not isFloat(res):
            return

        radius = unitMgr.convert(
            float(res),
            unitMgr.defaultLengthUnits,
            unitMgr.internalUnits
        )

        if radius < length * 0.5:
            return

        createTwoPointsRadiusArcs(
            startPnt,
            endPnt,
            radius,
        )

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

def isFloat(s) -> bool:
    try:
        float(s)
        return True
    except:
        return False


def createTwoPointsRadiusArcs(
    startPnt: adsk.fusion.SketchPoint,
    endPnt: adsk.fusion.SketchPoint,
    radius: float):

    def getMidPoint(
        sPnt: adsk.core.Point3D,
        ePnt: adsk.core.Point3D) -> adsk.core.Point3D:

        return  adsk.core.Point3D.create(
            (sPnt.x + ePnt.x) * 0.5,
            (sPnt.y + ePnt.y) * 0.5,
            (sPnt.z + ePnt.z) * 0.5,
        )

    def getOffsetVector(
        p1: adsk.core.Point3D,
        p2: adsk.core.Point3D,
        vec: adsk.core.Vector3D) -> adsk.core.Vector3D:

        v: adsk.core.Vector3D = vec.crossProduct(
            p1.vectorTo(p2)
        )
        v.normalize()

        return v

    def getCenterPoints(
        sPnt: adsk.core.Point3D,
        mPnt: adsk.core.Point3D,
        r: float,
        offsetVec: adsk.core.Vector3D) -> list:

        l1 = sPnt.distanceTo(mPnt)
        theta = math.acos(l1 / r)

        vec: adsk.core.Vector3D = offsetVec.copy()
        vec.scaleBy(
            math.tan(theta) * l1
        )

        centers = []
        for scl in [1, -1]:
            v: adsk.core.Vector3D = vec.copy()
            v.scaleBy(scl)

            p: adsk.core.Point3D = mPnt.copy()
            p.translateBy(v)

            centers.append(p)

        return centers

    def getTransitPoints(
        centers: list,
        r: float,
        offsetVec: adsk.core.Vector3D) -> list:

        vec: adsk.core.Vector3D = offsetVec.copy()
        vec.scaleBy(r)

        vecs = []
        for s in [1, -1]:
            v: adsk.core.Vector3D = vec.copy()
            v.scaleBy(s)
            vecs.append(v)

        pnts = []
        for pnt, v in itertools.product(centers, vecs):
            p = pnt.copy()
            p.translateBy(v)
            pnts.append(p)

        return pnts

    def createArcs(
        skt: adsk.fusion.Sketch,
        sPnt: adsk.core.Point3D,
        ePnt: adsk.core.Point3D,
        transitPoints: list):

        arcs: adsk.fusion.SketchArcs = skt.sketchCurves.sketchArcs
        arcLst = []
        skt.isComputeDeferred = True
        for mPnt in transitPoints:
            p1: adsk.core.Point3D = skt.modelToSketchSpace(sPnt)
            p2: adsk.core.Point3D = skt.modelToSketchSpace(mPnt)
            p3: adsk.core.Point3D = skt.modelToSketchSpace(ePnt)

            arcLst.append(arcs.addByThreePoints(p1, p2, p3))

        skt.isComputeDeferred = False

    # ********

    skt: adsk.fusion.Sketch = startPnt.parentSketch

    sPnt: adsk.core.Point3D =  startPnt.worldGeometry
    ePnt: adsk.core.Point3D =  endPnt.worldGeometry

    # midPoint
    midPnt: adsk.core.Point3D = getMidPoint(sPnt, ePnt)

    # offset vector
    vec: adsk.core.Vector3D = getOffsetVector(
        sPnt,
        ePnt,
        skt.xDirection.crossProduct(
            skt.yDirection
        )
    )

    # center points
    centers = getCenterPoints(
        sPnt,
        midPnt,
        radius,
        vec
    )

    # transit points
    transitPnts = getTransitPoints(
        centers,
        radius,
        vec
    )

    # arcs
    createArcs(
        skt,
        sPnt,
        ePnt,
        transitPnts
    )


def selectEnt(
        msg: str,
        filterStr: str) -> adsk.core.Selection:

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filterStr)
        return sel
    except:
        return None
Message 3 of 3
balunist
in reply to: kandennti

Kandennti,

Excellent, thank you much!!   So some more background on the reason for my question.   I'm trying to gain a better understanding why an SVG file that I created is being misinterpreted by the sketch.importSVG api for which a fusion defect has been created.   I hoping to see the defect fixed soon since it is needed for some optimization for my add-in.   

 

My goal is to perform a round trip by importing the SVG and you have provided the last piece to the puzzle, the Arc.   I did leave out some additional known arguments in my description,  the large-arc-flag and sweep-flag, which would narrow the 4 possible arcs you created down to one.  

A rx ry x-axis-rotation large-arc-flag sweep-flag

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report