/** * Post Toolpaths API Sample * Demonstrates posting toolpaths in the active document. */ import { adsk } from '@adsk/fusion'; // Params // { // "useCurrentDocument": false, // "saveAsNewDocument": false, // "hubId": "wip1fqaautodesk4298", // "fileURN": "urn:adsk.wipqa:dm.lineage:eSYoD7PzTj66Qw9qLPS3cg", // "useParentFolder": true, // "outputFolder": "urn:adsk.wipqa:fs.folder:co.mo6KmkbWRAiBs3TZZPrvAw", // "targetProject": "20250120147786973", // "ncProgramFilename": "SampleNCProgram", // "postDescription": "Generic 2D" // } function criticalError(message:string){ throw Error(message);} function run(): void { // Read the parameters passed with the script const scriptParameters = JSON.parse(adsk.parameters); if (!scriptParameters) throw Error("Invalid parameters provided."); // Get the Fusion API's application object const app = adsk.core.Application.get(); if (!app) throw Error("No adsk.core.Application."); const ui = app.userInterface // Log some information adsk.log(new Date().toString()); adsk.log("UserName: " + app.userName); adsk.log("User: " + app.currentUser.displayName); adsk.log("UserID: " + app.userId); adsk.log("Version: " + app.version); // Create a new empty document //const doc: adsk.core.Document = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType); const doc = getDocument( app, scriptParameters.useCurrentDocument, scriptParameters.hubId, scriptParameters.fileURN, ); if (!doc) throw Error("Invalid document."); const operationErrorMsg = 'This script requires the active document to contain at least one CAM operation.' const products: adsk.core.Products = doc.products; let product: adsk.core.Product; try { product = products.itemByProductType('CAMProductType') } catch (e) { criticalError(operationErrorMsg)} // Check if the document has a CAMProductType, abandon cleanly if not. const cam = products.itemByProductType("CAMProductType") as adsk.cam.CAM; if (!cam) throw Error("File has no CAM Product."); // Initialize the CAM manager to access the library manager and the post processor library. const camManager = adsk.cam.CAMManager.get() const libraryManager: adsk.cam.CAMLibraryManager = camManager.libraryManager const postLibrary: adsk.cam.PostLibrary = libraryManager.postLibrary // Create a query to filter post processors from the Fusion library by the vendor "Autodesk". const postQuery: adsk.cam.PostConfigurationQuery = postLibrary.createQuery(adsk.cam.LibraryLocations.Fusion360LibraryLocation) postQuery.vendor = "Autodesk" // Set the post configuration to use based on Operation Type of the first Setup. let firstSetupOperationType: adsk.cam.OperationTypes try{ firstSetupOperationType = cam.setups.item(0).operationType} catch (e){ criticalError(operationErrorMsg)} if (firstSetupOperationType === adsk.cam.OperationTypes.MillingOperation){ postQuery.capability = adsk.cam.PostCapabilities.Milling} else if (firstSetupOperationType === adsk.cam.OperationTypes.TurningOperation){ postQuery.capability = adsk.cam.PostCapabilities.Turning} else if (firstSetupOperationType === adsk.cam.OperationTypes.JetOperation){ postQuery.capability = adsk.cam.PostCapabilities.Jet} const postConfigs: adsk.cam.PostConfiguration[] = postQuery.execute() // Check for post configs being available. if (postConfigs.length === 0){ criticalError('No post-configurations found.')} // Find the post required in the post library and import it to local library. const postRequired = scriptParameters.postDescription let postDescription: string | null = null let ncExtension: string | null = null let postConfig: adsk.cam.PostConfiguration | null = null let counter = 0 for (let config of postConfigs) { if (config.description === postRequired) { postDescription = config.description ncExtension = config.extension postConfig = config break; } } if (!postConfig) { criticalError(`Unable to find postprocessor ${postRequired}.`) } // Prompt the user with an option to view the resulting NC file. // Create ncInput object. const ncInput: adsk.cam.NCProgramInput = cam.ncPrograms.createInput() // Set the value of scenario to: // 1 - post all // 2 - post the first setup, // 3 - post only the first operation of the first setup. const scenario = 1 // Adjust NC program parameters. ncInput.displayName = 'Sample NCProgram' // Embelish the nc filename to indicate chosen scenario and programming language. const programName = `${scriptParameters.ncProgramFilename}${scenario}`; const programfilename: adsk.cam.CAMParameter = ncInput.parameters.itemByName('nc_program_filename'); (<adsk.cam.StringParameterValue>(programfilename?.value)).value = programName // Provide a comment at the top of the file. const comment: adsk.cam.CAMParameter = ncInput.parameters.itemByName('nc_program_comment'); (<adsk.cam.StringParameterValue>(comment?.value)).value = "This is the Post Toolpaths API Sample NC Program"; // Setting the output folder parameters (<adsk.cam.BooleanParameterValue>(ncInput.parameters.itemByName("nc_program_postToFusionTeam")?.value)).value = true; // Setting Fusion Teams Output Folder Parameter (<adsk.cam.StringParameterValue>(ncInput.parameters.itemByName("nc_program_internal_fusion_team_output_folder")?.value)).value = getFolderId( app, scriptParameters.useParentFolder, scriptParameters.outputFolder, ); // Setting the Fusion Teams Output folder Project ID Parameter (<adsk.cam.StringParameterValue>(ncInput.parameters.itemByName("nc_program_fusion_team_target_project_id")?.value)).value = scriptParameters.targetProject; if (scenario === 1){ // ncInput.operations() expects a list of type 'OperationsBase': Operation, CAMFolder, CAMPattern, Setup // It will not accept CAMFolders, CAMPatterns or Setups (all plural) as they are derived from core.Base const opsBaseList: adsk.cam.OperationBase[] = [] const setups: adsk.cam.Setups = cam.setups for (let i: number; i < cam.setups.count; i++){ const setup = cam.setups.item(i) opsBaseList.push(setup) ncInput.operations = opsBaseList} // Include all setups} } else if (scenario === 2){ ncInput.operations = [cam.setups.item(0)] // Only include the first setup } else if (scenario === 3){ const firstSetup: adsk.cam.Setup = cam.setups.item(0) const firstOperation = firstSetup.allOperations.item(0) as adsk.cam.Operation if (firstOperation.hasToolpath){ ncInput.operations = [firstOperation]} // Only include the first operation of the first setup else { criticalError('Operation has no toolpath to post');} } // Create a new NC program using the current NC Program input including specified parameters and operations const newProgram: adsk.cam.NCProgram = cam.ncPrograms.add(ncInput) // Configure the post processor newProgram.postConfiguration = postConfig // Example of changing a post parameter. Parameters need to be declared as their correct type. const postParams: adsk.cam.CAMParameters = newProgram.postParameters // Parameter builtin_tolerance is of Type FloatParameterValue. const builtInTolerance: adsk.cam.CAMParameter = postParams.itemByName('builtin_tolerance'); (<adsk.cam.FloatParameterValue>(builtInTolerance.value)).value = 0; // Parameter showSequenceNumbers is of type ChoiceParameterValue so "false" is a string not a boolean. const showSequenceNumbers: adsk.cam.CAMParameter = postParams.itemByName('showSequenceNumber'); // Not all posts support SequenceNumbers // if (showSequenceNumbers){ // (<adsk.cam.ChoiceParameterValue>(showSequenceNumbers.value)).value = 'false'; // } // else{ // criticalError(`Parameter showSequenceNumbers cannot be modified for postprocessor: ${postRequired} - skipping`) // } // Update to apply changes. newProgram.updatePostParameters(postParams) // Finally post the process. const postOptions = adsk.cam.NCProgramPostProcessOptions.create() newProgram.postProcess(postOptions) // Waiting for the Posting to complete while (app.hasActiveJobs) { wait(4000); } wait(5000); } function getFolderId( app: adsk.core.Application, useParentFolder: boolean, outputFolder: string, ): string { if (useParentFolder) { return app.activeDocument.dataFile.parentFolder.id; } return outputFolder; } function getDocument( app: adsk.core.Application, useCurrentDocument: boolean, hubId: string, fileURN: string, ): adsk.core.Document { if (useCurrentDocument === true) { adsk.log(`Using currently open document: ${app.activeDocument.name}.`); return app.activeDocument; } if (hubId) { // Possible hubId formats: base64 encoded string, or business:<id>, // or personal:<id> (deprecated) const hub = app.data.dataHubs.itemById(hubId) || app.data.dataHubs.itemById(`a.${adsk.btoa(`business:${hubId}`, true)}`) || app.data.dataHubs.itemById(`a.${adsk.btoa(`personal:${hubId}`, true)}`); if (!hub) throw Error(`Hub with id ${hubId} not found.`); adsk.log(`Setting hub: ${hub.name}.`); app.data.activeHub = hub; } const file = app.data.findFileById(fileURN); if (!file) throw Error(`File not found ${fileURN}.`); adsk.log(`Opening ${file.name}`); const document = app.documents.open(file, true); if (!document) throw Error(`Cannot open file ${file.name}.`); return document; } function wait(ms: number) { const start = new Date().getTime(); while (new Date().getTime() - start < ms) adsk.doEvents(); } run();
///////////////////////////////////////////////////////////////////////////////////////////////// // For this sample script to run, the active Fusion document needs at least one CAM operation. // ///////////////////////////////////////////////////////////////////////////////////////////////// #include <Core/CoreAll.h> #include <CAM/CAMAll.h> #ifdef _WINDOWS #include <shlwapi.h> #else #include <stdlib.h> #endif using namespace adsk::core; using namespace adsk::cam; // Define a base class pointer for common usage. using CAMObjectPtr = Ptr<OperationBase>; // Function to ensure pathnames use forward slashes as required by the NC Program Output Folder. void replaceBackslashWithSlash(std::string& str) { for (char& ch : str) if (ch == '\\') ch = '/'; } // Customised messageBox to handle critical errors in one line void criticalError(Ptr<UserInterface> ui, const std::string& message) { ui->messageBox( message, "Critical Error", MessageBoxButtonTypes::OKButtonType, MessageBoxIconTypes::CriticalIconType); } extern "C" XI_EXPORT bool run(const char* context) { Ptr<Application> app = Application::get(); if (!app) return false; Ptr<UserInterface> ui = app->userInterface(); if (!ui) return false; Ptr<Document> doc = app->activeDocument(); if (!doc) return false; Ptr<Products> products = doc->products(); if (!products) return false; // Check if the document has a CAMProductType, abandon cleanly if not. std::string operationErrorMsg = "This script requires the active document to contain at least one CAM operation."; Ptr<CAM> camProduct = products->itemByProductType("CAMProductType"); if (!camProduct) { criticalError(ui, operationErrorMsg); return false; } // Initialize the CAM manager to access the library manager and the post processor library. Ptr<CAMManager> camManager = CAMManager::get(); Ptr<CAMLibraryManager> libraryManager = camManager->libraryManager(); Ptr<PostLibrary> postLibrary = libraryManager->postLibrary(); // Create a query to filter post processors from the Fusion library by the vendor "Autodesk". Ptr<PostConfigurationQuery> postQuery = postLibrary->createQuery(LibraryLocations::Fusion360LibraryLocation); postQuery->vendor("Autodesk"); // Set the post configuration to use based on Operation Type of the first Setup. Ptr<Setup> setup; Ptr<Setups> setups = camProduct->setups(); if (setups) { setup = setups->item(0); if (!setup) { criticalError(ui, operationErrorMsg); return false; } } OperationTypes opType = setup->operationType(); switch (opType) { case adsk::cam::MillingOperation: postQuery->capability(adsk::cam::PostCapabilities::Milling); break; case adsk::cam::TurningOperation: postQuery->capability(adsk::cam::PostCapabilities::Turning); break; case adsk::cam::JetOperation: postQuery->capability(adsk::cam::PostCapabilities::Jet); break; default: postQuery->capability(adsk::cam::PostCapabilities::Milling); break; } std::vector<Ptr<PostConfiguration>> postConfigs = postQuery->execute(); Ptr<URL> importedURL; std::string ncExtension; std::string postRequired = "RS-274D"; std::string postDescription = ""; // Find the required post in the post library and import it to local library. for (Ptr<PostConfiguration>& config : postConfigs) { if (config->description() == postRequired) { postDescription = postRequired; ncExtension = config->extension(); Ptr<URL> configUrl = URL::create("user://"); importedURL = postLibrary->importPostConfiguration(config, configUrl, "NCProgramSamplePost.cps"); break; } } // Check if the required post was found, abandon cleanly if not. if (postDescription.empty()) { criticalError(ui, "Unable to find postprocessor " + postRequired + "."); return false; } // Get the imported local post config. Ptr<PostConfiguration> postConfig = postLibrary->postConfigurationAtURL(importedURL); // Prompt the user with an option to view the resulting NC file. DialogResults dlgResults = ui->messageBox( "View nc file when done?", "Post-processing", MessageBoxButtonTypes::YesNoButtonType, MessageBoxIconTypes::QuestionIconType); bool viewResult = (dlgResults == DialogResults::DialogYes); // Create NCProgramInput object Ptr<NCProgramInput> ncInput = camProduct->ncPrograms()->createInput(); // Set the value of scenario to 1, 2 or 3 to post all, post the first setup, // or post only the first operation of the first setup. int scenario = 1; std::string message = "Yes \t- All toolpaths will be posted.\n\n" "No \t- Toolpaths in the first setup will be posted.\n\n" "Cancel\t- The first toolpath in the first setup will be posted.\n"; // Spaces appended to the title make the messageBox wider, preventing linw wrapping. DialogResults mbChoice = ui->messageBox( message, "Select what should be post-processed ", MessageBoxButtonTypes::YesNoCancelButtonType, MessageBoxIconTypes::QuestionIconType); if (mbChoice == DialogResults::DialogYes) { scenario = 1; } else if (mbChoice == DialogResults::DialogNo) { scenario = 2; } else { scenario = 3; } // Adjust NC program parameters. ncInput->displayName("Sample NCProgram"); Ptr<CAMParameters> ncParameters = ncInput->parameters(); Ptr<StringParameterValue> nc_program_filename = ncParameters->itemByName("nc_program_filename")->value(); // Embelish the nc filename to indicate chosen scenario and programming language. std::string programName = "NCProgramSampleCPP" + std::to_string(scenario); nc_program_filename->value(programName); // Provide a comment at the top of the file. Ptr<StringParameterValue> nc_program_comment = ncParameters->itemByName("nc_program_comment")->value(); std::string comment = "This is the Post Toolpaths API Sample NC Program"; nc_program_comment->value(comment); // Open nc file in editor if earlier requested. Ptr<BooleanParameterValue> nc_program_openInEditor = ncParameters->itemByName("nc_program_openInEditor")->value(); nc_program_openInEditor->value(viewResult); // Set temp directory as output directory. std::string outputFolder = camProduct->temporaryFolder(); // Variable outputFolder may contain backslashes but we need forward slashes. replaceBackslashWithSlash(outputFolder); Ptr<StringParameterValue> nc_program_output_folder = ncParameters->itemByName("nc_program_output_folder")->value(); nc_program_output_folder->value(outputFolder); // We have already declared a setups Ptr for all 3 scenarios. // Scenarios 2 and 3 use firstSetup. Ptr<Setup> firstSetup = setups->item(0); switch (scenario) { case 1: { // ncInput->operations() expects a list of type 'OperationBase'. // For example: Operation, CAMFolder, CAMPattern, Setup. // It will not accept CAMFolders, CAMPatterns or Setups (all plural) // as they are derived from core.Base. We make our own list instead. // Create a vector for the content of core.Base objects. std::vector<CAMObjectPtr> camObjects; for (size_t i = 0; i < setups->count(); ++i) { // Add the operation to the operations list. camObjects.push_back(setups->item(i)); } ncInput->operations({camObjects}); // Include all setups break; } case 2: { ncInput->operations({firstSetup}); // Only include the first setup break; } case 3: { Ptr<Operation> firstOperation = firstSetup->allOperations()->item(0); if (firstOperation->hasToolpath()) { ncInput->operations({firstOperation}); // First operation of first setup } else { criticalError(ui, "Operation has no toolpath to post"); return false; } break; } } // Create a new NC program using NC Program input and specified parameters and operations. Ptr<NCProgram> newProgram = camProduct->ncPrograms()->add(ncInput); // Configure the post processor newProgram->postConfiguration(postConfig); // Example of changing a post parameter. Parameters need to be declared as their correct type. Ptr<CAMParameters> postParams = newProgram->postParameters(); // Parameter builtin_tolerance is of Type FloatParameterValue. Ptr<FloatParameterValue> builtInTolerance = postParams->itemByName("builtin_tolerance")->value(); // Demonstrating how to check current parameter value and modify it. std::string previous = "Previous builtin_tolerance: " + std::to_string(builtInTolerance->value()); builtInTolerance->value(0.004); app->log(previous + "\tNew value: " + std::to_string(builtInTolerance->value())); // The next assignment returns null if you use a post-processor that does not support // block numbering - for example "XYZ" or "Generic 2D", however you will not need it in that case. Ptr<CAMParameter> showSequenceNumbersParam = postParams->itemByName("showSequenceNumbers"); if (showSequenceNumbersParam) { // Parameter showSequenceNumbers is of type ChoiceParameterValue so "false" is a string not a boolean. Ptr<ChoiceParameterValue> showSequenceNumbers = postParams->itemByName("showSequenceNumbers")->value(); // Demonstrating how to check current parameter value and modify it. previous = "Previous showSequenceNumbers: " + showSequenceNumbers->value(); showSequenceNumbers->value("false"); app->log(previous + "\tNew value: " + showSequenceNumbers->value()); } // Update to apply changes. newProgram->updatePostParameters(postParams); // Finally post the process. Ptr<NCProgramPostProcessOptions> postOptions = adsk::cam::NCProgramPostProcessOptions::create(); newProgram->postProcess(postOptions); // Activate CAM workspace if it is not the active one. if (ui->activeWorkspace()->name() != "Manufacture") { DialogResults result = ui->messageBox( "Activate the CAM Workspace?", "CAM Workspace Activate", MessageBoxButtonTypes::YesNoButtonType, MessageBoxIconTypes::QuestionIconType); if (result == DialogResults::DialogYes) { Ptr<Workspace> camWorkspace = ui->workspaces()->itemById("CAMEnvironment"); camWorkspace->activate(); } } // Indicate completion. ui->messageBox( "Post processing is complete. See file:\n" + outputFolder + "/" + programName + ncExtension, "Post Toolpath API Sample \t\t\t\t\t"); // Prevent line breaks return true; }
# For this sample script to run, the active Fusion document needs at least one CAM operation. import adsk.core, adsk.fusion, adsk.cam, traceback app = adsk.core.Application.get() ui = app.userInterface def criticalError(message:str): ''' Customised messageBox to handle critical errors in one line ''' ui.messageBox( message, 'Critical Error', adsk.core.MessageBoxButtonTypes.OKButtonType, adsk.core.MessageBoxIconTypes.CriticalIconType) def run(context): try: doc: adsk.core.Document = app.activeDocument products: adsk.core.Products = doc.products try: product: adsk.core.Product = products.itemByProductType('CAMProductType') except Exception: product = None # Check if the document has a CAMProductType, abandon cleanly if not. operationErrorMsg = 'This script requires the active document to contain at least one CAM operation.' if product == None: criticalError(operationErrorMsg) return cam = adsk.cam.CAM.cast(product) # Initialize the CAM manager to access the library manager and the post processor library. camManager = adsk.cam.CAMManager.get() libraryManager: adsk.cam.CAMLibraryManager = camManager.libraryManager postLibrary: adsk.cam.PostLibrary = libraryManager.postLibrary # Create a query to filter post processors from the Fusion library by the vendor "Autodesk". postQuery: adsk.cam.PostConfigurationQuery = \ postLibrary.createQuery(adsk.cam.LibraryLocations.Fusion360LibraryLocation) postQuery.vendor = "Autodesk" # Set the post configuration to use based on Operation Type of the first Setup. try: firstSetupOperationType: adsk.cam.OperationTypes = cam.setups.item(0).operationType except: criticalError(operationErrorMsg) return if firstSetupOperationType == adsk.cam.OperationTypes.MillingOperation: postQuery.capability = adsk.cam.PostCapabilities.Milling elif firstSetupOperationType == adsk.cam.OperationTypes.TurningOperation: postQuery.capability = adsk.cam.PostCapabilities.Turning elif firstSetupOperationType == adsk.cam.OperationTypes.JetOperation: postQuery.capability = adsk.cam.PostCapabilities.Jet postConfigs: list[adsk.cam.PostConfiguration] = postQuery.execute() # Check for post configs being available. if len(postConfigs) == 0: criticalError('No post-configurations found.') return # Find the post required in the post library and import it to local library. postRequired = "RS-274D" postDescription = None for config in postConfigs: if config.description == postRequired: postDescription = postRequired ncExtension = config.extension url = adsk.core.URL.create("user://") importedURL = postLibrary.importPostConfiguration(config, url, "NCProgramSamplePost.cps") break # Check if the required post was found, abandon cleanly if not. if not postDescription: criticalError(f'Unable to find postprocessor {postRequired}.') return # Get the imported local post config. postConfig: adsk.cam.PostConfiguration = postLibrary.postConfigurationAtURL(importedURL) # Prompt the user with an option to view the resulting NC file. dlgResults: adsk.core.DialogResults = ui.messageBox( 'View results when post is complete?', 'Post-processing', adsk.core.MessageBoxButtonTypes.YesNoButtonType, adsk.core.MessageBoxIconTypes.QuestionIconType) viewResult: bool = (dlgResults == adsk.core.DialogResults.DialogYes) # Create ncInput object. ncInput: adsk.cam.NCProgramInput = cam.ncPrograms.createInput() # Set the value of scenario to 1, 2 or 3 to post all, post the first setup, # or post only the first operation of the first setup. scenario = 1 # Spaces appended to the title make the messageBox wider, preventing linw wrapping. mbChoice: adsk.core.DialogResults = ui.messageBox( "Yes \t- All toolpaths will be posted.\n\n" \ "No \t- Toolpaths in the first setup will be posted.\n\n" \ "Cancel\t- The first toolpath in the first setup will be posted.\n", "Select what should be post-processed ", adsk.core.MessageBoxButtonTypes.YesNoCancelButtonType, adsk.core.MessageBoxIconTypes.QuestionIconType) if (mbChoice == adsk.core.DialogResults.DialogYes): scenario = 1 elif (mbChoice == adsk.core.DialogResults.DialogNo): scenario = 2 else: scenario = 3 # Adjust NC program parameters. ncInput.displayName = 'Sample NCProgram' # Embelish the nc filename to indicate chosen scenario and programming language. programName:str = f'NCProgramSamplePy{scenario}' programfilename: adsk.cam.CAMParameter = ncInput.parameters.itemByName('nc_program_filename') programfilename.value.value = programName # Provide a comment at the top of the file. comment: adsk.cam.CAMParameter = ncInput.parameters.itemByName('nc_program_comment') comment.value.value = "This is the Post Toolpaths API Sample NC Program" # Open nc file in editor if earlier requested. openInEditor: adsk.cam.CAMParameter = ncInput.parameters.itemByName('nc_program_openInEditor') openInEditor.value.value = viewResult # Set temp directory as output directory # Make the path valid for Fusion by replacing \\ to / in the path outputFolder = str(cam.temporaryFolder).replace('\\', '/') ncInput.parameters.itemByName('nc_program_output_folder').value.value = outputFolder if scenario == 1: # ncInput.operations() expects a list of type 'OperationsBase': Operation, CAMFolder, CAMPattern, Setup # It will not accept CAMFolders, CAMPatterns or Setups (all plural) as they are derived from core.Base opsBaseList: list[adsk.cam.OperationBase] = [] setups: adsk.cam.Setups = cam.setups for setup in setups: opsBaseList.append(setup) ncInput.operations = opsBaseList # Include all setups elif scenario == 2: ncInput.operations = [cam.setups.item(0)] # Only include the first setup elif scenario == 3: firstSetup: adsk.cam.Setup = cam.setups.item(0) firstOperation: adsk.core.Base = firstSetup.allOperations.item(0) if firstOperation.hasToolpath: ncInput.operations = [firstOperation] # Only include the first operation of the first setup else: ui.messageBox('Operation has no toolpath to post') return # Create a new NC program using the current NC Program input including specified parameters and operations newProgram: adsk.cam.NCProgram = cam.ncPrograms.add(ncInput) # Configure the post processor newProgram.postConfiguration = postConfig # Example of changing a post parameter. Parameters need to be declared as their correct type. postParams: adsk.cam.CAMParameters = newProgram.postParameters # Parameter builtin_tolerance is of Type FloatParameterValue. builtInTolerance: adsk.cam.FloatParameterValue = postParams.itemByName('builtin_tolerance') builtInTolerance.value.value = 0.004 # Parameter showSequenceNumbers is of type ChoiceParameterValue so "false" is a string not a boolean. showSequenceNumbers: adsk.cam.ChoiceParameterValue = postParams.itemByName('showSequenceNumbers') # Not all posts support SequenceNumbers if showSequenceNumbers: showSequenceNumbers.value.value = str('false') else: criticalError(f'Parameter showSequenceNumbers cannot be modified for postprocessor: {postRequired} - skipping!') # Update to apply changes. newProgram.updatePostParameters(postParams) # Finally post the process. postOptions = adsk.cam.NCProgramPostProcessOptions.create() newProgram.postProcess(postOptions) # Prompt user with an option to switch to the CAM workspace if it's not already active if ui.activeWorkspace.name != 'Manufacture': activateCAMWorkspace: adsk.core.DialogResults = ui.messageBox( f'Activate the CAM Workspace?','CAM Workspace Activate', adsk.core.MessageBoxButtonTypes.YesNoButtonType, adsk.core.MessageBoxIconTypes.QuestionIconType) if activateCAMWorkspace == adsk.core.DialogResults.DialogYes: camWorkspace: adsk.core.Workspace = ui.workspaces.itemById("CAMEnvironment") camWorkspace.activate() # Indicate completion. ui.messageBox(f'See file:\n{outputFolder}/{programName}{ncExtension}', 'Post processing is complete \t\t\t\t\t'); # Prevent line breaks of the pathname except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))