Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

Bug when using the cam.GenerateAllToolpaths(False) Function

Joshua.mursic
Advocate

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
Reply
Accepted solutions (2)
1,209 Views
22 Replies
Replies (22)

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

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

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

Joshua.mursic
Advocate
Advocate

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

0 Likes

jeff.pek
Community Manager
Community Manager

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

   Jeff

0 Likes

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

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.

 

1 Like

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

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

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

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

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

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

jeff.pek
Community Manager
Community Manager

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

  Jeff

0 Likes

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

Joshua.mursic
Advocate
Advocate

Yes with just an empty CAM environment 

0 Likes

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

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

1 Like

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

 

1 Like