Announcements
Autodesk Community will be read-only between April 26 and April 27 as we complete essential maintenance. We will remove this banner once completed. Thanks for your understanding

Using the API to create constraints between two sketches

bloudraak
Enthusiast

Using the API to create constraints between two sketches

bloudraak
Enthusiast
Enthusiast

When using the UI, I'm able to do the following:

 

  1. Create new component
  2. Create a sketch for the component
  3. Create a rectangle on the sketch 
  4. Add dimension constraints on the rectangle
  5. Exit the sketch
  6. Extrude
  7. Select the top face
  8. Create a new sketch on the top face
  9. Add points to the new sketch
  10. Add dimension constraints between the points on the new sketch and the rectangle created earlier such that the points are a specific distance from each corner.
  11. Exit the sketch
  12. Make sketches visible
  13. Create holes for each point

When trying to do this using the API, Fusion 360 crashes as in it dumps (see error report 318009543, if you're working at Autodesk).

 

Here's the code:

 

# Author-
# Description-
import math

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


def r(x, n):
    return math.ceil(x / n) * n


def get_top_face(component):
    body: adsk.fusion.BRepBody = component.bRepBodies[0]
    faces: adsk.fusion.BRepFaces = body.faces
    return max(faces, key=(lambda f: f.centroid.z))


def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        tray_doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        tray_design = tray_doc.products[0]
        root = tray_design.rootComponent
        units_mgr = tray_design.unitsManager
        units_mgr.distanceDisplayUnits = adsk.fusion.DistanceUnits.MillimeterDistanceUnits
        lib = app.materialLibraries.itemByName('Fusion 360 Material Library')
        pcb = lib.materials.itemByName('FR4')
        steel = lib.materials.itemByName('Steel')
        horizontal = adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation
        vertical = adsk.fusion.DimensionOrientations.VerticalDimensionOrientation

        s = 2.5
        x = 7.0
        y = 5.0
        c = (r(0.8 + 2, 2)) / 10
        w = c * 2 + r(x, s)
        d = c * 2 + r(y, s)

        parameters = tray_design.userParameters
        parameters.add('Space', adsk.core.ValueInput.createByReal(s), 'mm', '')
        parameters.add('HoleDiameter', adsk.core.ValueInput.createByReal(0.42), 'mm', '')
        parameters.add('Width', adsk.core.ValueInput.createByReal(x), 'mm', '')
        parameters.add('Depth', adsk.core.ValueInput.createByReal(y), 'mm', '')
        parameters.add('Height', adsk.core.ValueInput.createByReal(0.2), 'mm', '')
        parameters.add('HoleClearance', adsk.core.ValueInput.createByReal(c), 'mm', '')
        parameters.add('MountingWidth', adsk.core.ValueInput.createByString("ceil(Width/Space)*Space"), 'mm', '')
        parameters.add('MountingDepth', adsk.core.ValueInput.createByString("ceil(Depth/Space)*Space"), 'mm', '')

        component = root.occurrences.addNewComponent(adsk.core.Matrix3D.create()).component
        component.name = "Tray"
        component.material = steel

        sketch = component.sketches.add(component.xYConstructionPlane)
        sketch.name = "Tray"
        lines = sketch.sketchCurves.sketchLines
        rectangle = lines.addTwoPointRectangle(adsk.core.Point3D.create(0, 0, 0), adsk.core.Point3D.create(w, d, 0))

        # Add Constraints
        sketch.geometricConstraints.addHorizontal(rectangle.item(0))
        sketch.geometricConstraints.addHorizontal(rectangle.item(2))
        sketch.geometricConstraints.addVertical(rectangle.item(1))
        sketch.geometricConstraints.addVertical(rectangle.item(3))

        dim = sketch.sketchDimensions.addDistanceDimension(rectangle.item(0).startSketchPoint,
                                                           rectangle.item(0).endSketchPoint,
                                                           horizontal,
                                                           adsk.core.Point3D.create(w / 2, -1))
        dim.parameter.expression = "MountingWidth + HoleClearance*2"

        dim = sketch.sketchDimensions.addDistanceDimension(rectangle.item(3).startSketchPoint,
                                                           rectangle.item(3).endSketchPoint,
                                                           vertical,
                                                           adsk.core.Point3D.create(-1, d / 2))
        dim.parameter.expression = "MountingDepth + HoleClearance*2"

        extrudes = component.features.extrudeFeatures
        prof = sketch.profiles.item(0)
        distance = adsk.core.ValueInput.createByString("Height")
        extrudes.addSimple(prof, distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

        # Create Sketch for Holes
        face = get_top_face(component)
        sketch = component.sketches.addWithoutEdges(face)
        sketch.name = "Mounting"
        points = adsk.core.ObjectCollection.create()
        point1 = sketch.sketchPoints.add(adsk.core.Point3D.create(c, c, 0))
        point2 = sketch.sketchPoints.add(adsk.core.Point3D.create(c, d - c, 0))
        point3 = sketch.sketchPoints.add(adsk.core.Point3D.create(w - c, c, 0))
        point4 = sketch.sketchPoints.add(adsk.core.Point3D.create(w - c, d - c, 0))
        points.add(point1)
        points.add(point2)
        points.add(point3)
        points.add(point4)
        dim = sketch.sketchDimensions.addDistanceDimension(rectangle.item(0).startSketchPoint,
                                                           point1,
                                                           horizontal,
                                                           adsk.core.Point3D.create(0.5, -0.5))
        dim.parameter.expression = "HoleClearance"

        dim = sketch.sketchDimensions.addDistanceDimension(rectangle.item(1).startSketchPoint,
                                                           point1,
                                                           vertical,
                                                           adsk.core.Point3D.create(-0.5, 0.5))
        dim.parameter.expression = "HoleClearance"

        dim = sketch.sketchDimensions.addDistanceDimension(rectangle.item(2).startSketchPoint,
                                                           point4,
                                                           vertical,
                                                           adsk.core.Point3D.create(w + 0.5, d - 0.5))
        dim.parameter.expression = "HoleClearance"

        dim = sketch.sketchDimensions.addDistanceDimension(rectangle.item(1).startSketchPoint,
                                                           point4,
                                                           horizontal,
                                                           adsk.core.Point3D.create(w - 0.5, d + 0.5))
        dim.parameter.expression = "HoleClearance"

        dim = sketch.sketchDimensions.addDistanceDimension(point2,
                                                           point1,
                                                           vertical,
                                                           adsk.core.Point3D.create(-0.5, d / 2))
        dim.parameter.expression = "MountingDepth"

        dim = sketch.sketchDimensions.addDistanceDimension(point3,
                                                           point1,
                                                           horizontal,
                                                           adsk.core.Point3D.create(w / 2, -0.5))
        dim.parameter.expression = "MountingWidth"

        dim = sketch.sketchDimensions.addDistanceDimension(point3,
                                                           point4,
                                                           vertical,
                                                           adsk.core.Point3D.create(w + 0.5, d / 2))
        dim.parameter.expression = "MountingDepth"

        dim = sketch.sketchDimensions.addDistanceDimension(point4,
                                                           point2,
                                                           horizontal,
                                                           adsk.core.Point3D.create(w / 2, d + 0.5))
        dim.parameter.expression = "MountingWidth"

        hole_size = adsk.core.ValueInput.createByString("HoleDiameter")
        holes = component.features.holeFeatures
        hole = holes.createSimpleInput(hole_size)
        hole.setPositionBySketchPoints(points)
        hole.setAllExtent(adsk.fusion.ExtentDirections.PositiveExtentDirection)
        hole = holes.add(hole)
        hole.name = "Mounting"

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

 

Software Engineer
https://wernerstrydom.com
0 Likes
Reply
Accepted solutions (1)
1,003 Views
4 Replies
Replies (4)

BrianEkins
Mentor
Mentor

Fusion doesn't support creating constraints between entities in different sketches.  I think what you're seeing the UI is that Fusion is projecting the sketch line of the rectangle into the current sketch and then the constraint is being created to this projected line, which exists in the new sketch. Also, depending on your preferences, when you create a new sketch on a plane, all of the edges of the plane are automatically projected into the sketch. Fusion doesn't show in the graphics window until you move the mouse over them. You may be doing that too.  The main thing is that you can only create dimension and geometry constraints between geometry that exists in a single sketch. To use geometry outside the sketch you have to first project into the sketch you want to use it in.

 

I see in your code, when you create the second sketch, you're calling the addWithoutEdges method to create the sketch which does not include the edges of the face. Using the add method will include. You can also use the Sketch.project method to project specifc entities into the sketch.

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

bloudraak
Enthusiast
Enthusiast

Thanks that makes more sense. After all, I'm placing constraints between the holes and the edges of the top face.  The fact that Fusion 360 crashed was a bit of a problem.

 

I'm struggling to figure out how to project and then get the "rectangle" that represents the boundary of the top face so that I can place constraints. If parameters then change, the holes will be updated concerning the edge. 

Software Engineer
https://wernerstrydom.com
0 Likes

BrianEkins
Mentor
Mentor
Accepted solution

The crash is concerning. The API call should fail instead of Fusion crashing.

 

There are two approaches to this. One is to use the add method when creating the second sketch so that Fusion will automatically project the edges of the face into the sketch. You'll have access to those entities in the SketchLines and SketchCircles collections associated with the second sketch but you'll have to figure out a way to determine which line or circle is the one you want.  Typically, you would use geometric information from the entity like its direction or position to decide if it's the correct one.  The other approach is to do a similar approach with finding the edges of the faces you want and then projecting only those edges. Either way, you need to find the geometry you need, either on the face or in the sketch.

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

bloudraak
Enthusiast
Enthusiast
I decided to consolidate everything into one messy sketch.

I wish there was an API to layout the dimension text so they don't overlap... it's a glorious mess 🙂
Software Engineer
https://wernerstrydom.com
0 Likes