How to duplicate a sketch by using API

How to duplicate a sketch by using API

shutov441-vuz
Contributor Contributor
2,093 Views
6 Replies
Message 1 of 7

How to duplicate a sketch by using API

shutov441-vuz
Contributor
Contributor

Hi. I have a sketch in my project and I need to duplicate it and move a copy along the Z axis by using API. How can i do this?

0 Likes
2,094 Views
6 Replies
Replies (6)
Message 2 of 7

kandennti
Mentor
Mentor

Hi @shutov441-vuz .

 

I've written a script that clones a sketch in a test before.

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        filter =[
            # 'Sketches'
            # 'SketchConstraints',
            'Profiles',
            'Texts',
            'SketchCurves',
            'SketchLines',
            'SketchCircles',
            'SketchPoints']

        # select sketch entity
        msg :str = 'Select Sketch Entity'
        selFiltter :str = ','.join(filter)
        sel :adsk.core.Selection = selectEnt(_ui, msg ,selFiltter)
        if not sel: return

        # get sketch entities
        skt :adsk.fusion.Sketch = getSketch(sel.entity)
        objs :adsk.core.ObjectCollection = getSketchAllEntities(skt)

        # clone sketch
        support = skt.referencePlane
        comp :adsk.fusion.Component = skt.parentComponent
        mat = adsk.core.Matrix3D.create()
        clone :adsk.fusion.Sketch = comp.sketches.add(support)
        skt.copy(objs, mat, clone)

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

def getSketch(
    ent
    ) -> adsk.fusion.Sketch:

    skt = adsk.fusion.Sketch.cast(ent)
    if skt:
        return skt
    
    return ent.parentSketch

def getSketchAllEntities(
    skt :adsk.fusion.Sketch
    ) -> adsk.core.ObjectCollection:

    objs = adsk.core.ObjectCollection.create()
    [objs.add(e) for e in skt.sketchPoints if not e.isReference]
    [objs.add(e) for e in skt.sketchCurves]
    [objs.add(e) for e in skt.sketchTexts]

    return objs

def selectEnt(
    _ui :adsk.core.UserInterface,
    msg :str, 
    filtterStr :str
    ) -> adsk.core.Selection :

    try:
        sel = _ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None

 

0 Likes
Message 3 of 7

shutov441-vuz
Contributor
Contributor

Hi, thank you for help!

I trying to use your solution and get an error on line 33.

"support = skt.referencePlane"

What could it be?

0 Likes
Message 4 of 7

kandennti
Mentor
Mentor

The test was inadequate.
Therefore, there were some that could not be cloned correctly.

I want to review it a little more, including the error, so it will take some time.

0 Likes
Message 5 of 7

kandennti
Mentor
Mentor

Pass the sketch to the following function to create a duplicate sketch.
Not available in direct mode.

# create clone sketch
def execCloneSketch(
    self :adsk.fusion.Sketch
    ) -> adsk.fusion.Sketch:

    # list to ObjectCollection
    def list2objs(lst) -> adsk.core.ObjectCollection:

        objs = adsk.core.ObjectCollection.create()
        [objs.add(o) for o in lst]

        return objs

    # get all sketch entities
    def getAllEntities() -> adsk.core.ObjectCollection:

        objs = adsk.core.ObjectCollection.create()

        # point
        lst = [e for e in self.sketchPoints 
            if not e.isReference and e != self.originPoint]

        # curve line
        lst.extend([e for e in self.sketchCurves
            if not e.isReference])

        # text
        lst.extend([e for e in self.sketchTexts
            if not e.isReference])

        return list2objs(lst)


    try:
        # get comp
        comp :adsk.fusion.Component = self.parentComponent

        # get sketch support plane
        support = self.referencePlane

        # get sketch entities
        objs :adsk.core.ObjectCollection = getAllEntities()
        if objs.count < 1:
            return None

        # create sketch
        clone :adsk.fusion.Sketch = comp.sketches.add(support)

        # duplicate entities
        mat :adsk.core.Matrix3D = self.transform.copy()
        cloneObjs = self.copy(objs, mat, clone)

        # transform entities - This process is necessary!
        invMat = clone.transform.copy()
        invMat.invert()

        des :adsk.fusion.Design = comp.parentDesign
        if not comp == des.rootComponent:
            occ = self.assemblyContext
            occMat = occ.transform.copy()
            occMat.invert()
            invMat.transformBy(occMat)

        cloneObjs = [e for e in cloneObjs if e != clone.originPoint]
        clone.move(list2objs(cloneObjs), invMat)

        return clone

    except:
        errMsg = 'Failed:\n{}'.format(traceback.format_exc())

        app = adsk.core.Application.get()
        app.userInterface.palettes.itemById('TextCommands').writeText(str(errMsg))
        print(errMsg)
        return None


I tried a little here, but I couldn't reproduce the error.
Is it possible to attach data that has a sketch that causes an error?

0 Likes
Message 6 of 7

shutov441-vuz
Contributor
Contributor

I changed your script a little and did this, but the curve was inserted into the original sketch. Originally I wanted to apply the loft function between sketches, but it can be done between the curves of the same sketch. I'm right? I have attached my script, it creates a copy of the curve, but I cannot create the surface. Maybe you can tell me what I'm doing wrong? The answer to your question: the error occurs on any sketch, for example on a line.

ScriptError.PNG

#Fusion360API Python script
import adsk.core, adsk.fusion, traceback

_app = adsk.core.Application.cast(None)
_ui = adsk.core.UserInterface.cast(None)

def run(context):
    try:
        global _app, _ui
        _app = adsk.core.Application.get()
        _ui = _app.userInterface
        filter =[
            # 'Sketches'
            # 'SketchConstraints',
            'Profiles',
            'Texts',
            'SketchCurves',
            'SketchLines',
            'SketchCircles',
            'SketchPoints']
        design = _app.activeProduct
        rootComp = design.rootComponent

        # select sketch entity
        msg :str = 'Select Sketch Entity'
        selFiltter :str = ','.join(filter)
        sel :adsk.core.Selection = selectEnt(_ui, msg ,selFiltter)
        if not sel: return

         # get sketch entities
        skt :adsk.fusion.Sketch = getSketch(sel.entity)
        objs :adsk.core.ObjectCollection = getSketchAllEntities(skt)

        new_obj = adsk.core.ObjectCollection.create()

        mat = adsk.core.Matrix3D.create()
        mat.translation = adsk.core.Vector3D.create(0, 0, 1)

        new_obj = skt.copy(objs, mat)

        path1 = rootComp.features.createPath(skt.sketchCurves[0])
        path2 = rootComp.features.createPath(skt.sketchCurves[1])

        loftFeats = rootComp.features.loftFeatures
        loftInput = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        loftSectionsObj = loftInput.loftSections
        loftSectionsObj.add(path1)
        loftSectionsObj.add(path2)
        loftInput.isSolid = False

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

def selectEnt(
    _ui :adsk.core.UserInterface,
    msg :str, 
    filtterStr :str
    ) -> adsk.core.Selection :

    try:
        sel = _ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None

def getSketch(
    ent
    ) -> adsk.fusion.Sketch:

    skt = adsk.fusion.Sketch.cast(ent)
    if skt:
        return skt
    
    return ent.parentSketch

def getSketchAllEntities(
    skt :adsk.fusion.Sketch
    ) -> adsk.core.ObjectCollection:

    objs = adsk.core.ObjectCollection.create()
    [objs.add(e) for e in skt.sketchPoints if not e.isReference]
    [objs.add(e) for e in skt.sketchCurves]
    [objs.add(e) for e in skt.sketchTexts]

    return objs

I am able to create a curve between the two sketches that I search by name in the script, this even works with 3D sketches.

0 Likes
Message 7 of 7

kandennti
Mentor
Mentor

I found that I got that error when I used it in direct mode.
Please use in parametric mode.

0 Likes