Announcements

The Autodesk Community Forums has a new look. Read more about what's changed on the Community Announcements board.

Coordinate System When Sketching On A Plane

Jsoares1994
Explorer

Coordinate System When Sketching On A Plane

Jsoares1994
Explorer
Explorer

Hey all,

 

I'm working on a script that will help me design the fretboard of a guitar. The script is supposed to create a sketch which will contain construction lines indicating the positions of the frets, as well as construction lines showing where the strings will be to help properly visualize everything during the design process. This sketch is to be positioned on a construction plane 2" above the root component's XZ plane. This is my first time using the API, so it's been a bit of a struggle, but I'm finally getting on. I'm able to create the needed construction plane, place a sketch on it, and create sketch elements within it. However, I am having a really strange issue where the coordinate system in the sketch is not aligned with the root component's coordinate system, and I cannot figure out why. Here is my code thus far:

import adsk.core, adsk.fusion, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        
        #doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        
        #Initializing stuff
        design = app.activeProduct
        userParams = design.userParameters
        units = design.unitsManager
        point3d = adsk.core.Point3D
        point2d = adsk.core.Point2D
        design.unitsManager.defaultLengthUnits = 'in'

        rootComp = design.rootComponent
        rootSketches = rootComp.sketches
        planes = rootComp.constructionPlanes

        xyPlane = rootComp.xYConstructionPlane
        xzPlane = rootComp.xZConstructionPlane
        yzPlane = rootComp.yZConstructionPlane

        #Creating a sketch giving an overview of the fretboard
            #Create sketch plane 2 inches above the xz plane
        planeInput = planes.createInput()
        planeInput.setByOffset(xzPlane,adsk.core.ValueInput.createByReal(units.convert(2,'in','cm')))
        fretboardOverviewPlane = planes.add(planeInput)
        fretboardOverviewPlane.name = 'fretboardOverviewPlane'
            #Create sketch on the plane
        fretboardOverviewSketch = rootSketches.add(fretboardOverviewPlane)
        fretboardOverviewSketch.name = 'fretboardOverviewSketch'

        #Getting relevant values from user parameters
        scaleLength = userParams.itemByName('scaleLength').value
        numberOfFrets = userParams.itemByName('numberOfFrets').value
        fretboardWidthAtNut = userParams.itemByName('fretboardWidthAtNut').value
        fretboardWidthAtLastFret = userParams.itemByName('fretboardWidthAtLastFret').value
        stringSpacingAtNut = userParams.itemByName('stringSpacingAtNut').value
        stringSpacingAtBridge = userParams.itemByName('stringSpacingAtBridge').value
        fretMarkerLineWidth = userParams.itemByName('fretboardWidthAtLastFret').value*1.5   #make the fret marker lines a bit wider than the fretboard

        lines = fretboardOverviewSketch.sketchCurves.sketchLines
        lines.addByTwoPoints(point3d.create(-fretMarkerLineWidth/2,0,0),point3d.create(fretMarkerLineWidth/2,0,0))
        lines.addByTwoPoints(point3d.create(-fretMarkerLineWidth/2,0,scaleLength),point3d.create(fretMarkerLineWidth/2,0,scaleLength))




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

The issue lies in line 48:

lines.addByTwoPoints(point3d.create(-fretMarkerLineWidth/2,0,scaleLength),point3d.create(fretMarkerLineWidth/2,0,scaleLength))

I would expect this to generate a line parallel to the x-axis and offset by scaleLength units in the positive z direction, as pictured below:

 

correct.PNG

However this is not the case. Instead, the code above generates this:

incorrect 1.PNG

With the line being offset in the positive y direction instead of positive z. Swapping the y and z components of the point3d.create command so it reads

lines.addByTwoPoints(point3d.create(-fretMarkerLineWidth/2,scaleLength,0),point3d.create(fretMarkerLineWidth/2,scaleLength,0))

then offsets the line in the negative z direction, as below:

incorrect2.PNG

The only way to achieve what I want is to swap the components and negate them. So the code that produces what I am looking for is

lines.addByTwoPoints(point3d.create(-fretMarkerLineWidth/2,0,-scaleLength),point3d.create(fretMarkerLineWidth/2,0,-scaleLength))

 

So what gives? How do I make the coordinate systems align?

0 Likes
Reply
Accepted solutions (1)
1,201 Views
2 Replies
Replies (2)

Jsoares1994
Explorer
Explorer

Whoops, the last code snippet is incorrect. The code that actually produces what I am looking for is

 

lines.addByTwoPoints(point3d.create(-fretMarkerLineWidth/2,,-scaleLength,0),point3d.create(fretMarkerLineWidth/2,,-scaleLength,0))

 

 

0 Likes

BrianEkins
Mentor
Mentor
Accepted solution

You can think of a sketch as a coordinate system positioned in 3D space.  The sketch geometry in that sketch is drawn relative to that coordinate system.  The problem is that you have limited control over this coordinate system.  When you create a sketch, you select a planar entity.  This can be a construction plane or a planar face.  This defines the X-Y plane of the sketch coordinate system but the direction of the X and Y axes aren't under your control.  I believe in the case where you choose a construction plane, it will use the same orientation as the parent construction plane but when you pick a face it can be difficult to predict the position and orientation.

 

Below is a script you can use the visualize the coordinate system of a sketch.  Run the script and select a sketch from the browser.  It will display a small triad, as shown below, at the origin of the sketch.  The red arrow is the X axis, the green is the Y axis, and the blue is the Z axis.

sketchCoord.png

I made the blue arrow smaller because even though a sketch can contain 3D geometry, it is typically used as a 2D container and geometry is just drawn on the X-Y plane.  Because the position and orientation can't always be known, some useful tools are the modelToSketchSpace and sketchToModelSpace methods and the transform property of the Sketch object.

 

Running the script a second time will remove the triad.

 

 

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

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

        # Check to see if the coordinate system custom graphics already exist.
        for graphicsGroup in root.customGraphicsGroups:
            if graphicsGroup.id == 'SketchCoord':
                graphicsGroup.deleteMe()
                return

        # Have the sketch selected.
        sketchSel = ui.selectEntity('Select a sketch in the browser', 'Sketches')
        if not sketchSel:
            return
        
        sketch = adsk.fusion.Sketch.cast(sketchSel.entity)

        origin = sketch.sketchToModelSpace(adsk.core.Point3D.create(0,0,0))
        xPoint = sketch.sketchToModelSpace(adsk.core.Point3D.create(1,0,0))
        yPoint = sketch.sketchToModelSpace(adsk.core.Point3D.create(0,1,0))
        zPoint = sketch.sketchToModelSpace(adsk.core.Point3D.create(0,0,0.75))

        triadGraphics = root.customGraphicsGroups.add()
        triadGraphics.id = 'SketchCoord'

        tempBRep = adsk.fusion.TemporaryBRepManager.get()
        radius = 0.05
        xCyl = tempBRep.createCylinderOrCone(origin, radius, xPoint, radius)
        yCyl = tempBRep.createCylinderOrCone(origin, radius, yPoint, radius)
        zCyl = tempBRep.createCylinderOrCone(origin, radius * .75, zPoint, radius * .75)

        xDir = origin.vectorTo(xPoint)
        xDir.scaleBy(.25)
        xConePoint = xPoint.copy()
        xConePoint.translateBy(xDir)
        xCone = tempBRep.createCylinderOrCone(xPoint, radius*2, xConePoint, 0)

        yDir = origin.vectorTo(yPoint)
        yDir.scaleBy(.25)
        yConePoint = yPoint.copy()
        yConePoint.translateBy(yDir)
        yCone = tempBRep.createCylinderOrCone(yPoint, radius*2, yConePoint, 0)

        zDir = origin.vectorTo(zPoint)
        zDir.scaleBy(.25)
        zConePoint = zPoint.copy()
        zConePoint.translateBy(zDir)
        zCone = tempBRep.createCylinderOrCone(zPoint, radius*2*.75, zConePoint, 0)

        redColor = adsk.fusion.CustomGraphicsBasicMaterialColorEffect.create(adsk.core.Color.create(255,0,0,255),
                                                                          adsk.core.Color.create(255,0,0,255),
                                                                          adsk.core.Color.create(255,255,255,255),
                                                                          adsk.core.Color.create(0,0,0,255), 40, 1)
        xCylGraphics = triadGraphics.addBRepBody(xCyl)
        xCylGraphics.color = redColor
        xConeGraphics = triadGraphics.addBRepBody(xCone)
        xConeGraphics.color = redColor

        greenColor = adsk.fusion.CustomGraphicsBasicMaterialColorEffect.create(adsk.core.Color.create(0,255,0,255),
                                                                          adsk.core.Color.create(0,255,0,255),
                                                                          adsk.core.Color.create(255,255,255,255),
                                                                          adsk.core.Color.create(0,0,0,255), 40, 1)
        yCylGraphics = triadGraphics.addBRepBody(yCyl)
        yCylGraphics.color = greenColor
        yConeGraphics = triadGraphics.addBRepBody(yCone)
        yConeGraphics.color = greenColor

        blueColor = adsk.fusion.CustomGraphicsBasicMaterialColorEffect.create(adsk.core.Color.create(0,0,255,255),
                                                                          adsk.core.Color.create(0,0,255,255),
                                                                          adsk.core.Color.create(255,255,255,255),
                                                                          adsk.core.Color.create(0,0,0,255), 40, 1)
        zCylGraphics = triadGraphics.addBRepBody(zCyl)
        zCylGraphics.color = blueColor
        zConeGraphics = triadGraphics.addBRepBody(zCone)
        zConeGraphics.color = blueColor

        blackColor = adsk.fusion.CustomGraphicsBasicMaterialColorEffect.create(adsk.core.Color.create(0,0,0,255),
                                                                          adsk.core.Color.create(0,0,0,255),
                                                                          adsk.core.Color.create(255,255,255,255),
                                                                          adsk.core.Color.create(0,0,0,255), 40, 1)

        viewScale = adsk.fusion.CustomGraphicsViewScale.create(100, origin)
        triadGraphics.viewScale = viewScale                               
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
3 Likes