Demonstrates posting toolpaths in the active document using an NC program: import a post configuration from the post library, choose which setups or operations to include, set NC program and post parameters, and run NCProgram.postProcess.
Before running: Run from Scripts and Add-Ins with a design that contains at least one CAM setup with toolpaths. The script prompts for what to post (all setups, first setup, or first operation) and optionally opens the NC file when complete. It may offer to switch to the MANUFACTURE workspace.
/** * 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()))