Control distance and rectangle position

Control distance and rectangle position

lionel.courgnaud
Enthusiast Enthusiast
425 Views
2 Replies
Message 1 of 3

Control distance and rectangle position

lionel.courgnaud
Enthusiast
Enthusiast

Hello,

 

I need to script the following thing

 

Capture d’écran 2022-04-03 à 09.46.15.png

 

my process is simple.:

- create a 3 points rectangle outside of my sketch.

- apply constraints (parallel, perpendicular and dimension) to the rectangle

- apply a distance of 2mm between the item(0) (first sketchLine of my rectangle) and a edge of the sketch

- apply a distance of 1.7mm between the item(1) (next sketchLine of my rectangle) and the middle point of my edges

 

sometimes I have a good result, sometimes not ... How could I do to have good results. I guess it's all about selecting the right sketchLine in the rectangle before applying constraints, but I don't know how to do it.

 

Any helps ?

Thks 🙂

 

 

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

kandennti
Mentor
Mentor
Accepted solution

Hi @lionel.courgnaud .

 

I don't know the details, but it is possible to determine if a point is on a surface with SurfaceEvaluator.isParameterOnFace.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-e6682eb7-48f8-472d-9872-71da3c5ba8c8 

 

Without relying on constraints, I calculated the three vertices of the rectangle and drew it with the sketchLines.addThreePointRectangle method.

https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-f2298d37-2ae0-4db8-8f8e-b374edb49213 

 

# Fusion360API Python script

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


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

        rectangleSize = 0.34
        offsetDistance = 0.2

        msg: str = 'Select Sketch Line'
        selFilter: str = 'SketchLines'

        while(True):
            sel: adsk.core.Selection = selectEnt(msg, selFilter)
            if not sel:
                return
            sktLine: adsk.fusion.SketchLine = sel.entity

            createRectangle(
                sktLine,
                rectangleSize,
                offsetDistance
            )

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

def createRectangle(
    sktLine: adsk.fusion.SketchLine,
    rectangleSize: float,
    offsetDistance: float):

    # sketch
    skt: adsk.fusion.Sketch = sktLine.parentSketch
    axisZ: adsk.core.Vector3D = skt.xDirection.crossProduct(
        skt.yDirection
    )

    # sketch support face
    face: adsk.fusion.BRepFace = adsk.fusion.BRepFace.cast(
        skt.referencePlane
    )
    if not face:
        return

    # offset vector
    vecV: adsk.core.Vector3D = sktLine.geometry.asInfiniteLine().direction
    vecV.normalize()

    vecH: adsk.core.Vector3D = vecV.crossProduct(axisZ)
    vecH.normalize()

    # mid point
    line: adsk.core.Line3D = sktLine.geometry
    sPnt: adsk.core.Point3D = skt.sketchToModelSpace(line.startPoint)
    ePnt: adsk.core.Point3D = skt.sketchToModelSpace(line.endPoint)
    mPnt: adsk.core.Point3D = adsk.core.Point3D.create(
        (sPnt.x + ePnt.x) * 0.5,
        (sPnt.y + ePnt.y) * 0.5,
        (sPnt.z + ePnt.z) * 0.5
    )

    # center vector
    centerVec: adsk.core.Vector3D = vecH.copy()
    centerVec.scaleBy(
        rectangleSize * 0.5 + offsetDistance
    )

    # get center point on face
    center: adsk.core.Point3D = None
    eva: adsk.core.SurfaceEvaluator = face.evaluator
    pnt: adsk.core.Point3D
    vec: adsk.core.Vector3D
    prm: adsk.core.Point2D
    for scl in [1, -1]:
        vec = centerVec.copy()
        vec.scaleBy(scl)

        pnt = mPnt.copy()
        pnt.translateBy(vec)

        _, prm = eva.getParameterAtPoint(pnt)

        if eva.isParameterOnFace(prm):
            center = pnt
            break

    if not center:
        return

    # Vector to the vertices
    vec = vecV.copy()
    vec.add(vecH)
    vec.normalize()
    vec.scaleBy(
        rectangleSize * 0.5 * math.sqrt(2)
    )

    vertices = []
    p: adsk.core.Point3D
    for deg in [0, 90, 180]:
        p = center.copy()
        p.translateBy(vec)

        mat: adsk.core.Matrix3D = adsk.core.Matrix3D.create()
        mat.setToRotation(
            math.radians(deg),
            axisZ,
            center
        )
        p.transformBy(mat)

        # skt.modelToSketchSpace(p) #NG
        mat = skt.transform.copy()
        mat.invert()
        p.transformBy(mat)

        vertices.append(p)


    # draw Rectangle
    lines: adsk.fusion.SketchLines = skt.sketchCurves.sketchLines
    lines.addThreePointRectangle(
        vertices[0],
        vertices[1],
        vertices[2],
    )


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

lionel.courgnaud
Enthusiast
Enthusiast

Thanks for this awesome and well documented work 🙂

I finally found a way to do the job, but yours seems to be a more optimized solution.

I think I'll use it and I hope to reduce the all job execution time (about 12 minutes on a body with 118 faces)

 

thanks again ! 

0 Likes