<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Betreff: module for flat dowel in Fusion API and Scripts Forum</title>
    <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12291120#M2716</link>
    <description>&lt;P&gt;How do i get a preview?&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;i tried everythin, but as soon as i call my first function&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;createSketchOnMidplaneAngled(selectedFace) the face selection immediattley vanishes.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;i would like to do all my functions whenever a user input changes to see how a change would affect the operation&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;Ok i don't know why but suddenly the preview function handler is working and is doing everthing i wanted by it's own. I think it was a bug in fusion..&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
    <pubDate>Sat, 07 Oct 2023 14:08:54 GMT</pubDate>
    <dc:creator>FedX33</dc:creator>
    <dc:date>2023-10-07T14:08:54Z</dc:date>
    <item>
      <title>module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12281466#M2707</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;i would like to create a little Helper to automatically model the cutouts for lamellos. I think this could be quite interessting for other woddworking users too..&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Programming is not a problem, but the Fusion API is so big and complex that i find it very hard to get startet.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;First of all here is my plan:&lt;/P&gt;&lt;P&gt;I want to choose a face were the cutouts should be done:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_0-1696328116618.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1274501i8865FE1EF87EB818/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_0-1696328116618.png" alt="dmilich_0-1696328116618.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;so far so good. Now it should reate a sketch with a fully constrained middle line along the long edge:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_1-1696328280625.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1274502iAE22D033B3EFC881/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_1-1696328280625.png" alt="dmilich_1-1696328280625.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;well, i tried a lot of things but wasn't able to achieve this step..&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This middle line is only a helper line for the next steps:&lt;/P&gt;&lt;P&gt;create a face 90° through the line to get the face in between the board on create a new sketch on this face to create the typical flat dowel contour, constrained to the first middle line:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_2-1696328563649.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1274503i0F933F761FC3AE2B/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_2-1696328563649.png" alt="dmilich_2-1696328563649.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Thats my code so far.. It's just a input selection of a face and a new sketch lying on this face with its boundaries.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;import adsk.core
import adsk.fusion
import os
from ...lib import fusion360utils as futil
from ... import config
app = adsk.core.Application.get()
ui = app.userInterface
# Need to bring in design

design = adsk.fusion.Design.cast(app.activeProduct)
#component = adsk.fusion.Component.cast(app.activeDocument)
userParams = design.userParameters
#sketches = component.sketches



# TODO *** Specify the command identity information. ***
CMD_ID = f'{config.COMPANY_NAME}_{config.ADDIN_NAME}_cmdDialog'
CMD_NAME = 'Lamello Zauberrei'
CMD_Description = 'A Fusion 360 Add-in Command with a dialog'

# Specify that the command will be promoted to the panel.
IS_PROMOTED = True

# TODO *** Define the location where the command button will be created. ***
# This is done by specifying the workspace, the tab, and the panel, and the 
# command it will be inserted beside. Not providing the command to position it
# will insert it at the end.
WORKSPACE_ID = 'FusionSolidEnvironment'
PANEL_ID = 'SolidScriptsAddinsPanel'
COMMAND_BESIDE_ID = 'ScriptsManagerCommand'

# Resource location for command icons, here we assume a sub folder in this directory named "resources".
ICON_FOLDER = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'resources', '')

# Local list of event handlers used to maintain a reference so
# they are not released and garbage collected.
local_handlers = []


# Executed when add-in is run.
def start():
    # Create a command Definition.
    cmd_def = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_NAME, CMD_Description, ICON_FOLDER)

    # Define an event handler for the command created event. It will be called when the button is clicked.
    futil.add_handler(cmd_def.commandCreated, command_created)

    # ******** Add a button into the UI so the user can run the command. ********
    # Get the target workspace the button will be created in.
    workspace = ui.workspaces.itemById(WORKSPACE_ID)

    # Get the panel the button will be created in.
    panel = workspace.toolbarPanels.itemById(PANEL_ID)

    # Create the button command control in the UI after the specified existing command.
    control = panel.controls.addCommand(cmd_def, COMMAND_BESIDE_ID, False)

    # Specify if the command is promoted to the main toolbar. 
    control.isPromoted = IS_PROMOTED


# Executed when add-in is stopped.
def stop():
    # Get the various UI elements for this command
    workspace = ui.workspaces.itemById(WORKSPACE_ID)
    panel = workspace.toolbarPanels.itemById(PANEL_ID)
    command_control = panel.controls.itemById(CMD_ID)
    command_definition = ui.commandDefinitions.itemById(CMD_ID)

    # Delete the button command control
    if command_control:
        command_control.deleteMe()

    # Delete the command definition
    if command_definition:
        command_definition.deleteMe()


# Function that is called when a user clicks the corresponding button in the UI.
# This defines the contents of the command dialog and connects to the command related events.
def command_created(args: adsk.core.CommandCreatedEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Inputfenster Aufruf')

    # https://help.autodesk.com/view/fusion360/ENU/?contextId=CommandInputs
    inputs = args.command.commandInputs

    # TODO Define the dialog for your command by adding different inputs to the command.

    # Create a simple text box input.
    #inputs.addTextBoxCommandInput('text_box', 'Some Text', 'Enter some text.', 1, False)

    # Create a value input field and set the default using 1 unit of the default length unit.
    defaultLengthUnits = app.activeProduct.unitsManager.defaultLengthUnits
    #default_value = adsk.core.ValueInput.createByString('1')
    #inputs.addValueInput('value_input', 'Some Value', defaultLengthUnits, default_value)

    faceSelection = inputs.addSelectionInput("selectedSurface","Stirnseite","Stirnseite auswählen")
    faceSelection.addSelectionFilter(adsk.core.SelectionCommandInput.Faces)
    
    # TODO Connect to the events that are needed by this command.
    futil.add_handler(args.command.execute, command_execute, local_handlers=local_handlers)
    futil.add_handler(args.command.inputChanged, command_input_changed, local_handlers=local_handlers)
    futil.add_handler(args.command.executePreview, command_preview, local_handlers=local_handlers)
    futil.add_handler(args.command.validateInputs, command_validate_input, local_handlers=local_handlers)
    futil.add_handler(args.command.destroy, command_destroy, local_handlers=local_handlers)




# This event handler is called when the user clicks the OK button in the command dialog or 
# is immediately called after the created event not command inputs were created for the dialog.
def command_execute(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Execute Event')

    # TODO ******************************** Your code here ********************************

    # Get a reference to your command's inputs.
    inputs = args.command.commandInputs
    
    
    face_input: adsk.core.SelectionCommandInput = inputs.itemById("selectedSurface")
    selectedFace: adsk.fusion.BRepFace = face_input.selection(0).entity

    newSketch = design.rootComponent.sketches.add(selectedFace)
    newSketch.name = "new Dowel Sketch"    
    


        
# This event handler is called when the command needs to compute a new preview in the graphics window.
def command_preview(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Preview Event')
    inputs = args.command.commandInputs


# This event handler is called when the user changes anything in the command dialog
# allowing you to modify values of other inputs based on that change.
def command_input_changed(args: adsk.core.InputChangedEventArgs):
    changed_input = args.input
    inputs = args.inputs

    # General logging for debug.
    futil.log(f'{CMD_NAME} Input Changed Event fired from a change to {changed_input.id}')


# This event handler is called when the user interacts with any of the inputs in the dialog
# which allows you to verify that all of the inputs are valid and enables the OK button.
def command_validate_input(args: adsk.core.ValidateInputsEventArgs):
    # General logging for debug.
    #futil.log(f'{CMD_NAME} Validate Input Event')

    inputs = args.inputs
    
    # Verify the validity of the input values. This controls if the OK button is enabled or not.
    #valueInput = inputs.itemById('value_input')
    #if valueInput.value &amp;gt;= 0:
    #    args.areInputsValid = True
    #else:
    #    args.areInputsValid = False
        

# This event handler is called when the command terminates.
def command_destroy(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Destroy Event')

    global local_handlers
    local_handlers = []&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;i would be greatful for any help &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;br&lt;/P&gt;</description>
      <pubDate>Tue, 03 Oct 2023 10:26:42 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12281466#M2707</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-03T10:26:42Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12281894#M2708</link>
      <description>&lt;P&gt;Alright some more steps are working. The middle line on the first sketch is now created and fully constraint &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm quite sure there are better ways to achieve this, but for now its fine.&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def command_execute(args: adsk.core.CommandEventArgs):
    # General logging for debug.
    futil.log(f'{CMD_NAME} Command Execute Event')

    # TODO ******************************** Your code here ********************************

    # Get a reference to your command's inputs.
    inputs = args.command.commandInputs
    
    
    face_input: adsk.core.SelectionCommandInput = inputs.itemById("selectedSurface")
    selectedFace: adsk.fusion.BRepFace = face_input.selection(0).entity

    newSketch = design.rootComponent.sketches.add(selectedFace)
    newSketch.name = "new Dowel Sketch"    
    
    edges = selectedFace.edges
    
    for edge in edges:
        futil.log(str(edge.length))
    
    #get body of selected sketch and project its edges to the created sketch, this results in a fully constraint projection 
    body = selectedFace.body
    #newSketch.projectCutEdges(body)    

    lines = newSketch.sketchCurves.sketchLines
    curves = newSketch.sketchCurves
    
    sorted_curves = sorted(curves, key=lambda x: x.length if hasattr(x, 'length') else 0)
    
    shortest_curves = sorted_curves[:2]
    
    futil.log(f"CURVE COUNT: {curves.count}")
        
    for curve in sorted_curves:
        futil.log(f"sorted Curve length: {curve.length if hasattr(curve, 'length') else 'No length'}") 
           
        
    #Add a constraint midpoint on first 2 shortest edges
    midpoints = []
    for curve in shortest_curves:
        newPoint3D = adsk.core.Point3D.create(0, 0, 0)
        newSketchPoint = newSketch.sketchPoints.add(newPoint3D)
        geometricConstraints = newSketch.geometricConstraints
        geometricConstraints.addMidPoint(newSketchPoint, curve)
        midpoints.append(newSketchPoint)
    
    if len(midpoints) == 2:
        midLine = newSketch.sketchCurves.sketchLines.addByTwoPoints(midpoints[0], midpoints[1])
        midLine.isConstruction = True&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;the goal was to automatically detect the short sides of the board and draw the middle line across theese.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 03 Oct 2023 16:19:08 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12281894#M2708</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-03T16:19:08Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12285648#M2709</link>
      <description>&lt;P&gt;Another approach, that I think might be simpler, is to find the two long edges and the faces they connect to, then create a midplane construction plane between them. Then, create a sketch on this plane and project the original selected face onto this sketch. That will give you the line at the top you'll need to constrain your sketch geometry to. With this approach, you only have one sketch, which seems cleaner to me.&lt;/P&gt;</description>
      <pubDate>Thu, 05 Oct 2023 00:12:26 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12285648#M2709</guid>
      <dc:creator>BrianEkins</dc:creator>
      <dc:date>2023-10-05T00:12:26Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287218#M2710</link>
      <description>&lt;P&gt;i like the idea, but it turns out to be more complex that i thougt. The problem is, when i try to use the feature on a board with angle cut:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_0-1696520056712.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1275718i2A9A4D424CF85B0F/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_0-1696520056712.png" alt="dmilich_0-1696520056712.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;in that case projecting just the selected plane gives me 4 curves. I need to project the intersected part only. But it seems that theres no operation to do this directly. So the only way i found so far is to create a patch on the selected face, which is a BRepBody and can be projected via .projectCutEdges which makes it a lot more complex&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def createMidplane(face: adsk.fusion.BRepFace) -&amp;gt; Tuple[adsk.fusion.Sketch]:
    planes = design.rootComponent.constructionPlanes
    sketches = design.rootComponent.sketches
    bodies = design.rootComponent.bRepBodies
    patchFeature = design.rootComponent.features.patchFeatures
    
    edges = face.edges
    #Sort edges longest to shortest
    sorted_edges = sorted(edges, key=lambda edge: edge.length, reverse=True)
    longest_edge_1 = sorted_edges[0]
    longest_edge_2 = sorted_edges[1]
    
    #Get normal Vektors of selected planes and edge Planes and check for 90° angle 
    ok, normalOfSelectedFace = face.evaluator.getNormalAtPoint(face.pointOnFace)
    if not ok:
        ui.messageBox("Could not create normal Vektor of selected plane", "Error")
        return     
    
    #Planes at Edge1
    for face in longest_edge_1.faces:
        ok, normalOfFace = face.evaluator.getNormalAtPoint(face.pointOnFace)
        if not ok:
            ui.messageBox("Could not create normal Vektor edge1 Plane", "Error")
            return
        
        angleOfFaces = normalOfFace.angleTo(normalOfSelectedFace)
        futil.log(f"Edge 1 Winkel: {angleOfFaces}")

        if angleOfFaces &amp;gt; 0:
            planesInput = planes.createInput()
            planesInput.setByOffset(face, adsk.core.ValueInput.createByReal(0))
            planeEdge1 = planes.add(planesInput)
            planeEdge1.isLightBulbOn = False
            planeEdge1.name = "planeEdge1"

    #Planes at Edge2    
    for face in longest_edge_2.faces:
        ok, normalOfFace = face.evaluator.getNormalAtPoint(face.pointOnFace)
        if not ok:
            ui.messageBox("Could not create normal Vektor edge2 Plane", "Error")
            return
        
        angleOfFaces = normalOfFace.angleTo(normalOfSelectedFace)
        futil.log(f"Edge 2 Winkel: {angleOfFaces}")
        if angleOfFaces &amp;gt; 0:
            planesInput = planes.createInput()
            planesInput.setByOffset(face, adsk.core.ValueInput.createByReal(0))
            planeEdge2 = planes.add(planesInput)
            planeEdge2.isLightBulbOn = False
            planeEdge2.name = "planeEdge2"          

    planesInput = planes.createInput()
    planesInput.setByTwoPlanes(planeEdge1,planeEdge2)
    midplane = planes.add(planesInput)
    midplane.name ="lamelloMidplane"

    lamelloSketch = sketches.add(midplane)
    lamelloSketch.name = "Lamello"
    
    #newPatchInput = patchFeature.createInput(face, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
    #newPatch = patchFeature.add(newPatchInput)
    
    
    #lamelloSketch.project(longest_edge_2)
    #lamelloSketch.projectToSurface(midplane, )
    lamelloSketch.project(face)
    #lamelloSketch.projectCutEdges
    #return lamelloSketch&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;That's my approach to find the midplane and create it.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Oct 2023 15:37:45 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287218#M2710</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-05T15:37:45Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287360#M2711</link>
      <description>&lt;P&gt;i created a patch, so i'm able to use .projectCutEdges&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def createMidplane(selFace: adsk.fusion.BRepFace) -&amp;gt; Tuple[adsk.fusion.Sketch]:
    planes = design.rootComponent.constructionPlanes
    sketches = design.rootComponent.sketches
    bodies = design.rootComponent.bRepBodies
    patchFeature = design.rootComponent.features.patchFeatures
    
    edges = selFace.edges
    #Sort edges longest to shortest
    sorted_edges = sorted(edges, key=lambda edge: edge.length, reverse=True)
    longest_edge_1 = sorted_edges[0]
    longest_edge_2 = sorted_edges[1]
    
    #Get normal Vektors of selected planes and edge Planes and check for 90° angle 
    ok, normalOfSelectedFace = selFace.evaluator.getNormalAtPoint(selFace.pointOnFace)
    if not ok:
        ui.messageBox("Could not create normal Vektor of selected plane", "Error")
        return     
    
    #Planes at Edge1
    for face in longest_edge_1.faces:
        ok, normalOfFace = face.evaluator.getNormalAtPoint(face.pointOnFace)
        if not ok:
            ui.messageBox("Could not create normal Vektor edge1 Plane", "Error")
            return
        
        angleOfFaces = normalOfFace.angleTo(normalOfSelectedFace)
        futil.log(f"Edge 1 Winkel: {angleOfFaces}")

        if angleOfFaces &amp;gt; 0:
            planesInput = planes.createInput()
            planesInput.setByOffset(face, adsk.core.ValueInput.createByReal(0))
            planeEdge1 = planes.add(planesInput)
            planeEdge1.isLightBulbOn = False
            planeEdge1.name = "planeEdge1"

    #Planes at Edge2    
    for face in longest_edge_2.faces:
        ok, normalOfFace = face.evaluator.getNormalAtPoint(face.pointOnFace)
        if not ok:
            ui.messageBox("Could not create normal Vektor edge2 Plane", "Error")
            return
        
        angleOfFaces = normalOfFace.angleTo(normalOfSelectedFace)
        futil.log(f"Edge 2 Winkel: {angleOfFaces}")
        if angleOfFaces &amp;gt; 0:
            planesInput = planes.createInput()
            planesInput.setByOffset(face, adsk.core.ValueInput.createByReal(0))
            planeEdge2 = planes.add(planesInput)
            planeEdge2.isLightBulbOn = False
            planeEdge2.name = "planeEdge2"          

    
    patchSketch = sketches.add(selFace)
    patchSketch.name ="patchSketch"
    patchInput = patchFeature.createInput(patchSketch.profiles[0], adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
    newPatchBody = patchFeature.add(patchInput)
    
    planesInput = planes.createInput()
    planesInput.setByTwoPlanes(planeEdge1,planeEdge2)
    midplane = planes.add(planesInput)
    midplane.name ="lamelloMidplane"

    lamelloSketch = sketches.add(midplane)
    lamelloSketch.name = "Lamello"

    lamelloSketch.projectCutEdges(newPatchBody.bodies.item(0))
    
    return lamelloSketch&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;so now it's working, but the board has to be absolutley symmetrical, because the faces at the edges can have an angle:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_0-1696522783824.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1275759i222DF81CE81E2CA5/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_0-1696522783824.png" alt="dmilich_0-1696522783824.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;should be no big deal, as this is not really a realistic scenario for me..&lt;BR /&gt;&lt;BR /&gt;for creating the lamello profile i created a function:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="general"&gt;class LamelloResult(NamedTuple):
    midpoint: adsk.core.Point3D
    vLine: adsk.fusion.SketchLine
    hLine: adsk.fusion.SketchLine

def drawLamello(size, sketch: adsk.fusion.Sketch) -&amp;gt; LamelloResult:

    if size == 20:
        point1 = adsk.core.Point3D.create(0,0,0)
        point2 = adsk.core.Point3D.create(4.7,0,0)
        midpointH = sketch.sketchPoints.add(adsk.core.Point3D.create(0,0,0))
        
        point3 = adsk.core.Point3D.create(2.35,0.75,0)
        point4 = adsk.core.Point3D.create(2.35,-0.75,0)
        midpointV = sketch.sketchPoints.add(adsk.core.Point3D.create(0,0,0))
        
    lineH = sketch.sketchCurves.sketchLines.addByTwoPoints(point1, point2)
    lineH.isConstruction = True
    lineV = sketch.sketchCurves.sketchLines.addByTwoPoints(point3, point4)
    lineV.isConstruction = True
    
    sketch.geometricConstraints.addMidPoint(midpointH,lineH)
    sketch.geometricConstraints.addMidPoint(midpointV,lineV)
    sketch.geometricConstraints.addCoincident(midpointH,midpointV)
    sketch.geometricConstraints.addPerpendicular(lineH,lineV)
    
    sketch.sketchDimensions.addDistanceDimension(lineH.startSketchPoint,lineH.endSketchPoint,adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,adsk.core.Point3D.create(0,-0.5,0))
    sketch.sketchDimensions.addDistanceDimension(lineV.startSketchPoint,lineV.endSketchPoint,adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,adsk.core.Point3D.create(0,-0.5,0))
    
    arc1 = sketch.sketchCurves.sketchArcs.addByThreePoints(point1,point3,point2)
    sketch.geometricConstraints.addCoincident(arc1.endSketchPoint,lineH.startSketchPoint)
    sketch.geometricConstraints.addCoincident(arc1.startSketchPoint,lineH.endSketchPoint)
    sketch.geometricConstraints.addCoincident(lineV.startSketchPoint,arc1)
    
    
    arc2 = sketch.sketchCurves.sketchArcs.addByThreePoints(point1,point4,point2)
    sketch.geometricConstraints.addCoincident(arc2.startSketchPoint,lineH.startSketchPoint)
    sketch.geometricConstraints.addCoincident(arc2.endSketchPoint,lineH.endSketchPoint)
    sketch.geometricConstraints.addCoincident(lineV.endSketchPoint,arc2)
    
    return LamelloResult(midpointH, lineV, lineH)&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;it gives me back the midpoint and its horizontal and vertical line, so i'm able to constrain it.&amp;nbsp;&lt;BR /&gt;What would be the best approach to create a pattern dependend on the users input? Should i create all profiles with a loop or is it better to create one cutout and use the pathPatternFeature?&lt;BR /&gt;&lt;BR /&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Oct 2023 16:27:00 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287360#M2711</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-05T16:27:00Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287374#M2712</link>
      <description>&lt;P&gt;You can still use the midplane construction plane and the&amp;nbsp;&lt;A href="https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-1EB28A55-7250-4694-A253-582B395AB234" target="_blank" rel="noopener"&gt;intersectWithSketchPlane&lt;/A&gt; method to intersect the face with the sketch plane. That eliminates the problem with the angled face.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Which Lamelo connector are you using?&lt;/P&gt;</description>
      <pubDate>Thu, 05 Oct 2023 16:38:51 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287374#M2712</guid>
      <dc:creator>BrianEkins</dc:creator>
      <dc:date>2023-10-05T16:38:51Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287446#M2713</link>
      <description>&lt;P&gt;thanks this would be a solution, but there's another downside to it. If you want to do lamello cuts on a angled board, the sketch face needs to be perpendicular to the selected face:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_0-1696525053205.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1275777iFB8D95A31BFAD748/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_0-1696525053205.png" alt="dmilich_0-1696525053205.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;so i think i will stick to the first method.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;i use standard 00, 10 and 20 lamellos, because its easy to cut them on my CNC&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="dmilich_1-1696525184892.png" style="width: 600px;"&gt;&lt;img src="https://forums.autodesk.com/t5/image/serverpage/image-id/1275778i25774C30C915C84F/image-size/medium?v=v2&amp;amp;px=400" role="button" title="dmilich_1-1696525184892.png" alt="dmilich_1-1696525184892.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Oct 2023 16:59:49 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287446#M2713</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-05T16:59:49Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287991#M2714</link>
      <description>&lt;P&gt;i would create the pattern as a sketch. I wrote a code to create a fully contraint pattern were i want to add my drawLaemello() and constrain is also in the next step&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def createPattern(patternSketch: adsk.fusion.Sketch, startDistance: float, numProfiles: int, lamelloSize: int):
    length = patternSketch.sketchCurves.sketchLines[0].length
    futil.log(f"Pattern line lenght is: {length}")
    patternLine = patternSketch.sketchCurves.sketchLines[0]
    #distanceBetween = (length-startDistance)/(numProfiles-1)    
    distanceBetween = (length-(2*startDistance)) / (numProfiles-1)
    
    vector = adsk.core.Vector3D.create(patternLine.endSketchPoint.geometry.x - patternLine.startSketchPoint.geometry.x,
                                      patternLine.endSketchPoint.geometry.y - patternLine.startSketchPoint.geometry.y,
                                      0)
    vector.normalize()
    perpendicularVector = adsk.core.Vector3D.create(-vector.y, vector.x, 0)

    futil.log(f"num profiles: {numProfiles}")
    lamelloResults = []
    prevPosPoint = None
    for i in range(numProfiles):
        # Berechne die Position für dieses Profil
        xPos = patternLine.startSketchPoint.geometry.x + vector.x * (startDistance + i * distanceBetween)
        yPos = patternLine.startSketchPoint.geometry.y + vector.y * (startDistance + i * distanceBetween)
        posPoint = adsk.core.Point3D.create(xPos, yPos, 0)
        currentPoint = patternSketch.sketchPoints.add(posPoint)
        
        if prevPosPoint:
            newLine = patternSketch.sketchCurves.sketchLines.addByTwoPoints(prevPosPoint, currentPoint)
            newLine.isConstruction = True
            patternSketch.geometricConstraints.addCoincident(currentPoint, patternLine)
            patternSketch.sketchDimensions.addDistanceDimension(currentPoint, prevPosPoint,adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,adsk.core.Point3D.create(1,1,0))
        else:
            newLine = patternSketch.sketchCurves.sketchLines.addByTwoPoints(patternLine.startSketchPoint, currentPoint)
            newLine.isConstruction = True
            patternSketch.geometricConstraints.addCoincident(currentPoint, patternLine)
            patternSketch.sketchDimensions.addDistanceDimension(currentPoint, patternLine.startSketchPoint,adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,adsk.core.Point3D.create(1,1,0))

        
        prevPosPoint = currentPoint&lt;/LI-CODE&gt;&lt;P&gt;or is there a better way of doing this ?&amp;nbsp;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 05 Oct 2023 20:59:40 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12287991#M2714</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-05T20:59:40Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12289706#M2715</link>
      <description>&lt;P&gt;is there a possible solution to generate a preview of the cut ?&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="python"&gt;def createPattern(patternSketch: adsk.fusion.Sketch, startDistance: float, numProfiles: int, lamelloSize: int, stärke: adsk.core.ValueInput):
    length = patternSketch.sketchCurves.sketchLines[0].length
    futil.log(f"Pattern line lenght is: {length}")
    patternLine = patternSketch.sketchCurves.sketchLines[0]
    #distanceBetween = (length-startDistance)/(numProfiles-1)    
    distanceBetween = (length-(2*startDistance)) / (numProfiles-1)
    
    vector = adsk.core.Vector3D.create(patternLine.endSketchPoint.geometry.x - patternLine.startSketchPoint.geometry.x,
                                      patternLine.endSketchPoint.geometry.y - patternLine.startSketchPoint.geometry.y,
                                      0)
    vector.normalize()
    #perpendicularVector = adsk.core.Vector3D.create(-vector.y, vector.x, 0)

    prevPosPoint = None
    for i in range(numProfiles):
        # Berechne die Position für dieses Profil
        xPos = patternLine.startSketchPoint.geometry.x + vector.x * (startDistance + i * distanceBetween)
        yPos = patternLine.startSketchPoint.geometry.y + vector.y * (startDistance + i * distanceBetween)
        posPoint = adsk.core.Point3D.create(xPos, yPos, 0)
        currentPoint = patternSketch.sketchPoints.add(posPoint)
        
        if prevPosPoint:
            newLine = patternSketch.sketchCurves.sketchLines.addByTwoPoints(prevPosPoint, currentPoint)
            newLine.isConstruction = True
            patternSketch.geometricConstraints.addCoincident(currentPoint, patternLine)
            patternSketch.sketchDimensions.addDistanceDimension(currentPoint, prevPosPoint,adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,adsk.core.Point3D.create(1,1,0))
            lamelloSketch = drawLamello(lamelloSize,patternSketch)
            patternSketch.geometricConstraints.addCoincident(lamelloSketch.midpoint,currentPoint)
            patternSketch.geometricConstraints.addPerpendicular(lamelloSketch.vLine,patternLine)        
        else:
            newLine = patternSketch.sketchCurves.sketchLines.addByTwoPoints(patternLine.startSketchPoint, currentPoint)
            newLine.isConstruction = True
            patternSketch.geometricConstraints.addCoincident(currentPoint, patternLine)
            patternSketch.sketchDimensions.addDistanceDimension(currentPoint, patternLine.startSketchPoint,adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,adsk.core.Point3D.create(1,1,0))
            lamelloSketch = drawLamello(lamelloSize,patternSketch)
            patternSketch.geometricConstraints.addCoincident(lamelloSketch.midpoint,currentPoint)
            patternSketch.geometricConstraints.addPerpendicular(lamelloSketch.vLine,patternLine)
        
        prevPosPoint = currentPoint
        
    
    profileCollection = adsk.core.ObjectCollection.create()
    for profile in patternSketch.profiles:
        profileCollection.add(profile)
    extFeatures = patternSketch.parentComponent.features.extrudeFeatures
    extInput = extFeatures.createInput(profileCollection, adsk.fusion.FeatureOperations.CutFeatureOperation)
    extInput.setSymmetricExtent(stärke, True)
    extFeatures.add(extInput)&lt;/LI-CODE&gt;</description>
      <pubDate>Fri, 06 Oct 2023 15:18:11 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12289706#M2715</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-06T15:18:11Z</dc:date>
    </item>
    <item>
      <title>Betreff: module for flat dowel</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12291120#M2716</link>
      <description>&lt;P&gt;How do i get a preview?&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;i tried everythin, but as soon as i call my first function&amp;nbsp;&lt;/P&gt;&lt;DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;createSketchOnMidplaneAngled(selectedFace) the face selection immediattley vanishes.&lt;/SPAN&gt;&lt;/DIV&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;&lt;DIV&gt;&lt;SPAN&gt;i would like to do all my functions whenever a user input changes to see how a change would affect the operation&amp;nbsp;&lt;BR /&gt;&lt;BR /&gt;Ok i don't know why but suddenly the preview function handler is working and is doing everthing i wanted by it's own. I think it was a bug in fusion..&lt;/SPAN&gt;&lt;/DIV&gt;&lt;/DIV&gt;</description>
      <pubDate>Sat, 07 Oct 2023 14:08:54 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/module-for-flat-dowel/m-p/12291120#M2716</guid>
      <dc:creator>FedX33</dc:creator>
      <dc:date>2023-10-07T14:08:54Z</dc:date>
    </item>
  </channel>
</rss>

