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: 

Create 3d spline that is tangent to edge of brep surface

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
thomasL7NS5
351 Views, 6 Replies

Create 3d spline that is tangent to edge of brep surface

I am trying to create a script through python API that allows a user to select the bottom left vertex of "body 1" then the bottom right vertex of "body 2". The script will then generate a 3d spline between these vertices. The script should then add a tangent relationship between the edge adjacent to the bottom right vertex of "body 2" as seen in the screenshot attached. Creating this tangent relationship is causing difficulties. If anyone has some tips about how to achieve this that would be great. Thanks in advance. 

 

#Author-
#Description-

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

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

#####################################Create the 3d spline sketch#####################################
        #use select bottom left vertex of right body
        VertexSel1 = ui.selectEntity('Select bottom left vertex of right body', 'Vertices ')
        if VertexSel1:
            vertex1 = VertexSel1.entity
        BNMR1coord = vertex1.geometry

        #User select bottom right vertex of left body
        VertexSel5 = ui.selectEntity('Select bottom right vertex of left body', 'Vertices ')
        if VertexSel5:
            vertex5 = VertexSel5.entity
        BNMR5coord = vertex5.geometry

        #Initialize the active sketch for BNMR 
        sketches = root.sketches
        sketchBNMR = sketches.add(root.xYConstructionPlane)
        sketchBNMR.name = 'Bottom Sketch'

        #create needed variables
        BNMRheight = BNMR5coord.y - BNMR1coord.y
        BNMRdepth = BNMR5coord.z - BNMR1coord.z
        BNMRwidth = BNMR5coord.x - BNMR1coord.x

        #Find all of the z values of the middle coordinates
        BNMR2_z = BNMR1coord.z + 0.23*BNMRdepth
        BNMR3_z = BNMR1coord.z + 0.57*BNMRdepth
        BNMR4_z = BNMR1coord.z + 0.82*BNMRdepth

        #find all of the x values of the middle coordinates
        BNMR2_x = BNMR5coord.x - 0.69*BNMRwidth
        BNMR3_x = BNMR5coord.x - 0.45*BNMRwidth
        BNMR4_x = BNMR5coord.x - 0.21*BNMRwidth

        #find all of the y values of the middle coordinates
        BNMR2_y = BNMR1coord.y + 0.28*BNMRheight
        BNMR3_y = BNMR1coord.y + 0.75*BNMRheight
        BNMR4_y = BNMR1coord.y + 0.92*BNMRheight

        #List the points that will be used to create the spline
        BNMR1 = adsk.core.Point3D.create(BNMR1coord.x, BNMR1coord.y, BNMR1coord.z)
        BNMR2 = adsk.core.Point3D.create(BNMR2_x, BNMR2_y, BNMR2_z)
        BNMR3 = adsk.core.Point3D.create(BNMR3_x, BNMR3_y, BNMR3_z)
        BNMR4 = adsk.core.Point3D.create(BNMR4_x, BNMR4_y, BNMR4_z)
        BNMR5 = adsk.core.Point3D.create(BNMR5coord.x, BNMR5coord.y, BNMR5coord.z)

        #Define a datastruct of points for the spline
        BNMRSketchPoints = adsk.core.ObjectCollection.create()
        BNMRSketchPoints.add(BNMR1)
        BNMRSketchPoints.add(BNMR2)
        BNMRSketchPoints.add(BNMR3)
        BNMRSketchPoints.add(BNMR4)
        BNMRSketchPoints.add(BNMR5)
    
        #sketch the splines
        spline1 = sketchBNMR.sketchCurves.sketchFittedSplines.add(BNMRSketchPoints)
        
        #Add a tangent relationship to the spline at vertex 5 and horizontal at vertex 1
        face1 = vertex1.faces.item(0) #Get the face attached to the vertex for the forehead
        edge1 = face1.edges.item(0) #get the edge
        tanline1 = spline1.activateTangentHandle(spline1.startSketchPoint) #use to make tanline horizontal
        sketchBNMR.geometricConstraints.addHorizontal(tanline1) #use to make tanline vertical or horizontal
        
        tangent_constraint1 = sketchBNMR.geometricConstraints.addTangent(spline1, edge1)


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

 

 

6 REPLIES 6
Message 2 of 7
MichaelT_123
in reply to: thomasL7NS5

Hi Mr ThomasL7NS5,

 

The first issue... from docs:

returnValue = geometricConstraints_var.addTangent(curveOne, curveTwo)

The second issue ... as per your f3d and png files.

What is 3D curve tangent to 3D surface? At a given (non-singular) point on Riemann's surface, an infinite number of straight lines pass through it ( and even greater curvy ones).

So, you have to decide the plane where the tangential relation of two curves is established. Like in the real life, the tangent plane relationship will be defined naturally … in the case of 3D rigid surfaces.

Judging by the code you presented, it should not be a significant hurdle for you; an edge projection might help.

 

The third issue ... regarding the API documentation of the function.

Would it be helpful to clarify that the (curveOne, curveTwo) arguments should be of 2D kind or a least have coplanar with sketch plane tangent vectors at a tangent point?

 

Regards

MichaelT 

MichaelT
Message 3 of 7
thomasL7NS5
in reply to: MichaelT_123

Hi @MichaelT_123,

 

Thank you for the reply!

 

A projection of the edge does work well when the spline is on the same plane, for example with all of the same z-coordinates. However, through the UI I am able to apply a tangent relationship of the 3d spline sketch. Please see the attached video that will hopefully clarify what I am trying to achieve through the API. If the .addTagnent(curveone, curve2) is constrained to 2d, this may not be possible? 

Message 4 of 7
BrianEkins
in reply to: thomasL7NS5

I don't believe it matters if the curve lie on the X-Y plane of the sketch or not. Here's a version of your program that finds the edges of the faces that the selected vertices are connected to. It then does some logic to determine which of the two edges to use and then includes that edge into the sketch. Now it can create a tangent constraint between the included sketch curve and the spline. The code that determines the edge can probably be cleaner, but this does seem to work.

BrianEkins_1-1690566216292.png

 

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

#####################################Create the 3d spline sketch#####################################
        #use select bottom left vertex of right body
        VertexSel1 = ui.selectEntity('Select bottom left vertex of right body', 'Vertices ')
        if VertexSel1:
            vertex1: adsk.fusion.BRepVertex = VertexSel1.entity
        BNMR1coord = vertex1.geometry

        #User select bottom right vertex of left body
        VertexSel5 = ui.selectEntity('Select bottom right vertex of left body', 'Vertices ')
        if VertexSel5:
            vertex5: adsk.fusion.BRepVertex = VertexSel5.entity
        BNMR5coord = vertex5.geometry

        #Initialize the active sketch for BNMR 
        sketches = root.sketches
        sketchBNMR = sketches.add(root.xYConstructionPlane)
        sketchBNMR.name = 'Bottom Sketch'

        #create needed variables
        BNMRheight = BNMR5coord.y - BNMR1coord.y
        BNMRdepth = BNMR5coord.z - BNMR1coord.z
        BNMRwidth = BNMR5coord.x - BNMR1coord.x

        #Find all of the z values of the middle coordinates
        BNMR2_z = BNMR1coord.z + 0.23*BNMRdepth
        BNMR3_z = BNMR1coord.z + 0.57*BNMRdepth
        BNMR4_z = BNMR1coord.z + 0.82*BNMRdepth

        #find all of the x values of the middle coordinates
        BNMR2_x = BNMR5coord.x - 0.69*BNMRwidth
        BNMR3_x = BNMR5coord.x - 0.45*BNMRwidth
        BNMR4_x = BNMR5coord.x - 0.21*BNMRwidth

        #find all of the y values of the middle coordinates
        BNMR2_y = BNMR1coord.y + 0.28*BNMRheight
        BNMR3_y = BNMR1coord.y + 0.75*BNMRheight
        BNMR4_y = BNMR1coord.y + 0.92*BNMRheight

        #List the points that will be used to create the spline
        BNMR1 = adsk.core.Point3D.create(BNMR1coord.x, BNMR1coord.y, BNMR1coord.z)
        BNMR2 = adsk.core.Point3D.create(BNMR2_x, BNMR2_y, BNMR2_z)
        BNMR3 = adsk.core.Point3D.create(BNMR3_x, BNMR3_y, BNMR3_z)
        BNMR4 = adsk.core.Point3D.create(BNMR4_x, BNMR4_y, BNMR4_z)
        BNMR5 = adsk.core.Point3D.create(BNMR5coord.x, BNMR5coord.y, BNMR5coord.z)

        #Define a datastruct of points for the spline
        BNMRSketchPoints = adsk.core.ObjectCollection.create()
        BNMRSketchPoints.add(BNMR1)
        BNMRSketchPoints.add(BNMR2)
        BNMRSketchPoints.add(BNMR3)
        BNMRSketchPoints.add(BNMR4)
        BNMRSketchPoints.add(BNMR5)
    
        #sketch the splines
        spline1 = sketchBNMR.sketchCurves.sketchFittedSplines.add(BNMRSketchPoints)

        # Find the edge connected to vertex one that is somewhat in the X direction.
        vert1Edge1 = vertex1.edges[0]
        vert1Edge2 = vertex1.edges[1]
        edge1Dir = vert1Edge1.startVertex.geometry.vectorTo(vert1Edge1.endVertex.geometry)
        edge2Dir = vert1Edge2.startVertex.geometry.vectorTo(vert1Edge2.endVertex.geometry)
        xVec = adsk.core.Vector3D.create(1,0,0)
       
        angle1 = edge1Dir.angleTo(xVec)
        if angle1 > math.pi / 2:
            angle1 = math.pi - angle1
        angle2 = edge2Dir.angleTo(xVec)
        if angle2 > math.pi / 2:
            angle2 = math.pi - angle2
        if angle1 < angle2:
            edge1 = vert1Edge1
        else:
            edge1 = vert1Edge2

        # Find the edge connected to vertex tow that is somewhat in the X direction.
        vert2Edge1 = vertex5.edges[0]
        vert2Edge2 = vertex5.edges[1]
        edge1Dir = vert2Edge1.startVertex.geometry.vectorTo(vert2Edge1.endVertex.geometry)
        edge2Dir = vert2Edge2.startVertex.geometry.vectorTo(vert2Edge2.endVertex.geometry)
       
        angle1 = edge1Dir.angleTo(xVec)
        if angle1 > math.pi / 2:
            angle1 = math.pi - angle1
        angle2 = edge2Dir.angleTo(xVec)
        if angle2 > math.pi / 2:
            angle2 = math.pi - angle2
        if angle1 < angle2:
            edge2 = vert2Edge1
        else:
            edge2 = vert2Edge2

        curve1 = sketchBNMR.include(edge1).item(0)
        curve2 = sketchBNMR.include(edge2).item(0)

        sketchBNMR.geometricConstraints.addTangent(curve1, spline1)
        sketchBNMR.geometricConstraints.addTangent(curve2, spline1)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

  

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 5 of 7
thomasL7NS5
in reply to: BrianEkins

Hi @BrianEkins,

 

That did seem to do the trick. Thanks for the insight!

 

Thomas

Message 6 of 7

@Jorge_Jaramillo - this post is being edited to remove PII.

 

Hi @thomasL7NS5 ,

 

I didn't have the time to finish it sooner, but below is what I did to try to solve your problem.

 

I choose to select the edges instead of the vertices, then selecting the pair of vertices that are nearest to each other, also an optimization to the spline points calculation, and finally constraining the spline with the previously selected edges (based on @BrianEkins implementation).

 

 

 

def spline_tangent_to_two_edges():
    try:
        app = adsk.core.Application.get()
        root = des.rootComponent
        ui = app.userInterface

#####################################Create the 3d spline sketch#####################################
        # use select first edge
        selection = ui.selectEntity('Select first edge ...', 'Edges')
        if selection:
            edge1: adsk.fusion.BRepEdge = selection.entity
        # User select second edge
        selection = ui.selectEntity('Select second edge ...', 'Edges')
        if selection:
            edge2: adsk.fusion.BRepEdge = selection.entity
        # select neartest vertices between edges
        (vertex1, vertex5) = sorted([(i,j) for i in [edge1.startVertex, edge1.endVertex]
                                           for j in [edge2.startVertex, edge2.endVertex]],
                                     key=lambda p: p[0].geometry.distanceTo(p[1].geometry))[0]

        spline_factors = [(0.00, 0.00, 0.00),
                          (0.31, 0.28, 0.23),
                          (0.55, 0.75, 0.57),
                          (0.79, 0.92, 0.82),
                          (1.00, 1.00, 1.00)]
        spline_points = [ adsk.core.Point3D.create(
                            vertex1.geometry.x * (1 - kx) + kx * vertex5.geometry.x,
                            vertex1.geometry.y * (1 - ky) + ky * vertex5.geometry.y,
                            vertex1.geometry.z * (1 - kz) + kz * vertex5.geometry.z,
                          ) for (kx, ky, kz) in spline_factors]

        #Initialize the active sketch for BNMR 
        sketches = root.sketches
        sketchBNMR = sketches.add(root.xYConstructionPlane)
        sketchBNMR.name = 'Bottom Sketch'
        spline1 = sketchBNMR.sketchCurves.sketchFittedSplines.add(adsk.core.ObjectCollection.createWithArray(spline_points))

        curve1 = sketchBNMR.include(edge1).item(0)
        curve2 = sketchBNMR.include(edge2).item(0)

        sketchBNMR.geometricConstraints.addTangent(curve1, spline1)
        sketchBNMR.geometricConstraints.addTangent(curve2, spline1)
    except:
        app.log('Failed:\n{}'.format(traceback.format_exc()))

 

 

 

I hope it could help you.

 

Regards,

Jorge Jaramillo

 

Message 7 of 7
MichaelT_123
in reply to: BrianEkins

 Hi Mr BrianEkins,

 

### I don't believe it matters if the curve lie on the X-Y plane of the sketch or not ###

 

If I can trust my memory (while its level is steadily declining), I recall some problems with applying tangent constraints in F360 via straight API.

 

The API "tangencing" always has been like swimming in murky water full of sharks. I wonder how many drafters have lost their virtual limbs? I personally have lost quite a few … they have since regrown😏.

 

I am pleased that the 'only 2D constraints' limitation has been somehow tempered, perhaps with the recent addition of the new sketch's curves functionality – blend. The script you presented shows that it is now possible to establish tangential relations between spline ends, even if they are of a 3D kind.

However, such functionality can't be applied to the spline interiors (or their inside fit points).

Well,… at least I was not able to do this in the simple UI-driven experiment. Besides splines, F360 offers other curve types: circles (3D), ellipses, conics,….

 

How about them?

Has the murky water been filtered, and sharks underwent dental procedures?  ... for them.

 

If not, the third issue I raised in my previous post still stands. It would be beneficial to clarify a very brief and, in my opinion… too optimistic description of the addTangent() function.

 

Regards

MichaelT

MichaelT

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