Bug when using the cam.GenerateAllToolpaths(False) Function

Bug when using the cam.GenerateAllToolpaths(False) Function

Joshua.mursic
Advocate Advocate
2,350 Views
22 Replies
Message 1 of 23

Bug when using the cam.GenerateAllToolpaths(False) Function

Joshua.mursic
Advocate
Advocate

Hello, when using the function below

 

cam.GenerateAllToolpaths(False)

 

I am getting an issue where all of the toolpaths regenerate, but some of them say that they are invalid. 

Joshuamursic_0-1686842638022.png

 

I tried doing a loop and generating each operation one at a time but the same issue occurred, only worse.

 

cam:adsk.cam.CAM = app.activeDocument.products.itemByProductType('CAMProductType')
        for operation in setup.operations:
            cam.generateToolpath(operation)

 

Joshuamursic_1-1686843134997.png

 

If I do the generate all toolpaths manually by selecting them all and Ctrl+G, this does not happen and they all calculate correctly. Is this a bug? Is there a better way to make sure all of my toolpaths are recalculated?

0 Likes
Accepted solutions (2)
2,351 Views
22 Replies
Replies (22)
Message 2 of 23

jeff.pek
Community Manager
Community Manager

Are you able to share a model that does this, along with the script you're using for this?

We can take a look on this end to see what might be happening.

 

Thanks,

  Jeff

0 Likes
Message 3 of 23

Joshua.mursic
Advocate
Advocate
import adsk.core,adsk.cam,adsk.fusion
app = adsk.core.Application.get()
ui = app.userInterface

def machineDie(occurence:adsk.fusion.Occurrence):
       parentDocument = occurence.component.parentDesign.parentDocument
       cam:adsk.cam.CAM = parentDocument.products.itemByProductType('CAMProductType')
       setups = cam.setups

       templateName = 'Removable Die.f3dhsm-template'
       #Get CAM templates
       camManager = adsk.cam.CAMManager.get()
       libraryManager = camManager.libraryManager
       templateLibraries = libraryManager.templateLibrary
       cloudFolder = templateLibraries.urlByLocation(adsk.cam.LibraryLocations.CloudLibraryLocation)
       cloudTemplatelibrary = templateLibraries.childAssetURLs(cloudFolder)

       # Get Templates
       for cloudTemplate in cloudTemplatelibrary:
              templateName = cloudTemplate.toString()
              if template in templateName:
                     templateUrl = adsk.core.URL.create(templateName)
                     templateIndex = templateLibraries.templateAtURL(templateUrl)
       
       template = templateIndex

       #Get Occurence Geometry
       dieMargin = occurence.component.sketches.itemByName("Margin")
       diePrepAxis = occurence.component.constructionAxes.itemByName("PrepAxis")
       dieAxis = occurence.component.constructionAxes.itemByName("DieAxis")
       dieBottom = occurence.component.sketches.itemByName("DieBottom")
       dieOrigin = occurence.component.sketches.itemByName("Origin")

       # Create Setup Input
       setupInput = setups.createInput(adsk.cam.OperationTypes.TurningOperation)
       setupInput.models = [occurence]
       setupInput.stockMode = adsk.cam.SetupStockModes.FixedCylinderStock
       # Create Setup
       setup = setups.add(setupInput)
       setup.name = 'Test'

       # Defin Setup Parameters
       setup.parameters.itemByName('job_spindle').expression = "'primary'"
       setup.parameters.itemByName('wcs_orientation_mode').expression = "'axesZX'"
       setup.parameters.itemByName('job_rotaryAxis').value.value = [dieAxis]
       setup.parameters.itemByName('wcs_orientation_flipZ').expression = "false"
       setup.parameters.itemByName('wcs_origin_turning').expression = "'stock front'"
       setup.parameters.itemByName('job_spunProfileTolerance').expression = "0.05 mm"
       setup.parameters.itemByName('jobSafeZ_mode').expression = "'stock front'" 
       setup.parameters.itemByName('jobSafeZ_offset').expression = "0.5mm"
       setup.parameters.itemByName('chuckFront_mode').expression = "'stock back'"
       setup.parameters.itemByName('chuckFront_offset').expression = "-0.5 mm"
       setup.parameters.itemByName('job_stockMode').expression = "'fixedcylinder'"
       setup.parameters.itemByName('job_stockDiameter').expression = "15.875"
       setup.parameters.itemByName('job_stockLength').expression = "modelLength+6mm"
       setup.parameters.itemByName('job_stockLengthMode').expression = "'front'"
       setup.parameters.itemByName('job_stockFixedRoundingValue').expression = "0mm"
       setup.createFromCAMTemplate(template)

       # Build common refrence Items
       sketchPoint = dieMargin.sketchPoints.item(0)
       # Start selecting custom points and geometry

       rotaryRoughOp = setup.operations.item(4)
       rotaryRoughOp.parameters.itemByName("view_orientation_axisZ").value.value = [diePrepAxis]
       rotaryRoughOp.parameters.itemByName("bottomHeight_ref").value.value = [sketchPoint]

       prepFinishVertical = setup.operations.item(5)
       prepFinishVertical.parameters.itemByName("boundaryMode").value.value = 'selection'
       boundary:adsk.cam.CadContours2dParameterValue = prepFinishVertical.parameters.itemByName("machiningBoundarySel")
       cadContours: adsk.cam.CadContours2dParameterValue = boundary.value
       chainSels: adsk.cam.CurveSelections = cadContours.getCurveSelections()
       chainSels.clear()
       chainSel: adsk.cam.ChainSelection = chainSels.createNewChainSelection()
       crvs =[c for c in dieMargin.sketchCurves]
       chainSel.inputGeometry = crvs
       cadContours.applyCurveSelections(chainSels)
       
       prepFinishVertical.parameters.itemByName("view_orientation_axisZ").value.value = [diePrepAxis]
       prepFinishVertical.parameters.itemByName("bottomHeight_ref").value.value = [dieOrigin]

       prepFinishHorizontal = setup.operations.item(6)
       prepFinishHorizontal.parameters.itemByName("backHeight_ref").value.value = [sketchPoint]

       finishStump = setup.operations.item(7)
       finishStump.parameters.itemByName("frontHeight_ref").value.value = [sketchPoint]

       finishPin = setup.operations.item(8)
       finishPin.parameters.itemByName("frontHeight_mode").expression = "'selection front'"
       finishPin.parameters.itemByName("frontHeight_ref").value.value = [dieBottom]

       #Generate all toolpaths
       cam.generateAllToolpaths(False)

I have attached a sample model and the template that the script references. 

0 Likes
Message 4 of 23

Joshua.mursic
Advocate
Advocate

The operation that is not generating seems to always be the 4th, even when using different templates, or multiple setups.

0 Likes
Message 5 of 23

Joshua.mursic
Advocate
Advocate

@jeff.pek  We could Teamview the bug if that would be helpful to you. 

0 Likes
Message 6 of 23

jeff.pek
Community Manager
Community Manager

Thanks for sharing. We'll try to take a look very soon.

   Jeff

0 Likes
Message 7 of 23

jeff.pek
Community Manager
Community Manager

@Joshua.mursic - How do you call the machineDie function? i.e., what Occurrence do you send it? Is there a more complete script?

 

Jeff

0 Likes
Message 8 of 23

Joshua.mursic
Advocate
Advocate

I am just using the first occurence in the CAM designRoot Folder.

 

 

 

cam:adsk.cam.CAM = app.activeDocument.products.itemByProductType("CAMProductType")
occurences = cam.designRootOccurrence.component.occurrences
occurence = occurences.item(0)

machineDie(occurence)

 

 

And then the machineDie function looks up the template in the users cloud storage and loads it in.

 

Message 9 of 23

jeff.pek
Community Manager
Community Manager

Just to be sure I understand:

 

What you're describing happens independently of actually creating the operations, right?

 

i.e., I could have one script to create everything, and then a separate one to just regenerate what's there, right?

 

Jeff

0 Likes
Message 10 of 23

jeff.pek
Community Manager
Community Manager

I opened up your test.f3d, and ran a simple script that simply regenerated all operations, and everything seemed fine. Does that not work OK for you?

 

Jeff

0 Likes
Message 11 of 23

Joshua.mursic
Advocate
Advocate

When I run the function:

cam.generateAllToolpaths(False)

by itself as a script it works, but when I run it as part of my addon, it dosent.

 

0 Likes
Message 12 of 23

jeff.pek
Community Manager
Community Manager

Interesting. I'm seeing different behavior between the current released build (2.0.16490) -- which I assume you're using -- and later internal builds.

 

When I open your test.f3d, and then run the following in the text command area (after switching to mfg workspace), nothing happens:

   cam = adsk.core.Application.get().activeProduct

   cam.generateAllToolpaths(False)

 

Does that work for you?

 

And when you say it doesn't work in your add-in: even if that's the ONLY thing you do in the add-in? Or do you mean right after you create the operations in the same function?

 

Thanks,

  Jeff

0 Likes
Message 13 of 23

Joshua.mursic
Advocate
Advocate

If a create a quick script and run the code:

 

cam = adsk.core.Application.get().activeProduct

cam.generateAllToolpaths(False)

 

the setup will regenerate and calculate all of the toolpaths no problem.

 

If I call the cam.generateAllToolpaths(False) at the end of the setup and operation creation in my addon, it doesn't recalculate all of the operations.

 

 

0 Likes
Message 14 of 23

jeff.pek
Community Manager
Community Manager

It turns out that it wasn't working for me in the released build because I don't have the Machining Extension enabled. When I enable that, then it's OK from the text command window. And it's also fine when I run (only) the generateAllToolpaths from a script.

 

Jeff

0 Likes
Message 15 of 23

jeff.pek
Community Manager
Community Manager

OK, got it. Thanks for the clarification. Will keep poking at this.

  Jeff

0 Likes
Message 16 of 23

jeff.pek
Community Manager
Community Manager

Another question: what would be the appropriate starting state for running the script? Would it be with no setups/operations in the test document?

 

Jeff

0 Likes
Message 17 of 23

Joshua.mursic
Advocate
Advocate

Yes with just an empty CAM environment 

0 Likes
Message 18 of 23

kandennti
Mentor
Mentor

I tried a few things.

I modified the following part of the machineDie function to avoid an error.

 

・・・
    setups = cam.setups

    # templateName = 'Removable Die.f3dhsm-template'
    template = 'Removable Die.f3dhsm-template'  # <-here

    # Get CAM templates
・・・

 

This may not be directly relevant, but I made the following changes to check the status before executing the generateAllToolpaths method.

・・・

    # Generate all toolpaths
    print("***")
    [report_path(o) for o in setup.operations]
    # cam.generateAllToolpaths(False)


def report_path(operation: adsk.cam.Operation):
    lst = [
        f"name:{operation.name}",
        f"hasToolpath:{operation.hasToolpath}",
        f"isGenerating:{operation.isGenerating}",
        f"hasWarning:{operation.hasWarning}",
        f"hasError:{operation.hasError}",
        "",
    ]

    print("\n".join(lst))

 

When I check, the calculation is started just by importing the template with the setup.createFromCAMTemplate method.
Is this a specification?

0 Likes
Message 19 of 23

jeff.pek
Community Manager
Community Manager

Hi -

 

Thanks for the extra info. Yes, it's expected that the created operations will auto-generate as they are created. So, you shouldn't need to explicitly do this, unless the "Automatically generate toolpath on operation change" preference is unchecked.

 

If I uncheck that, then the generateAllToolpaths call in the script works, and all operations are generated successfully.

 

We need to check why the auto-generation encounters failures.

 

Jeff

Message 20 of 23

Joshua.mursic
Advocate
Advocate
Accepted solution

Interestingly, disabling the Automatic toolpath generation on operation change has resolved this issue for me. I am not sure if you guys have had any success replicating the problem, but this seems to fix the issue.

 

Joshuamursic_0-1687518639667.png