I'm attempting to duplicate a selected body using the API. I've found that BRepBody supports cut and copy to the clipboard. But how do I then paste from the clipboard? I haven't found any access to the clipboard or any other way to paste.
Or is there some other way, using the API (Javascript preferably), to duplicate a body?
Thanks!
Solved! Go to Solution.
Solved by ekinsb. Go to Solution.
Hello Hans,
I have similar sniplet/script which makes new instance of component. If you will find it useful...
Regards
Jan Priban, Autodesk
//Author-JP
//Description-tocite schody
function run(context) {
"use strict";
if (adsk.debug === true) {
/*jslint debug: true*/
debugger;
/*jslint debug: false*/
}
var ui;
try {
var app = adsk.core.Application.get();
ui = app.userInterface;
var product = app.activeProduct;
var design = adsk.fusion.Design(product);
if (!design) {
ui.messageBox('No active Fusion design', 'No Design');
return;
}
// Get the root component of the active design.
var rootComp = design.rootComponent;
var occs = rootComp.allOccurrences;
// Gather information about each unique component
var count = occs.count;
ui.messageBox(count.toString(), 'count');
//var comp = occs.item(0).component;
//var jmeno = comp.name
//ui.messageBox(jmeno,'name');
// Create a new occurrence.
var trans = adsk.core.Matrix3D.create();
// Create a new occurrence for the component, offset by 15 cm in the X direction.
trans.setCell(0, 3, 15.0);
var newOcc = rootComp.occurrences.addExistingComponent(occs.item(0).component, trans);
//ui.messageBox('Hello script');
}
catch (e) {
if (ui) {
ui.messageBox('Failed : ' + (e.description ? e.description : e));
}
}
adsk.terminate();
}
I thought this might be a workaround but it doesn't quite work. The BrepBody object does support a copy method which copies it to the clipboard but there's not a paste method anywhere. I thought I could just invoke the "Paste" command, which I can but doing a past of a body also puts you into the move UI so it doesn't work as expected. Anytime you start mixing the API with normal commands and the UI you never know what will happen. I think we need to add something like a copoyTo method on the body where you can specify the component you want to copy to. A general copy and paste functionality isn't all that useful through an API because of it's context sensitivity.
The code below does create a copy but I also wanted to get that copy and then perform some other operation, a move in this case.
function run(context) { "use strict"; if (adsk.debug === true) { /*jslint debug: true*/ debugger; /*jslint debug: false*/ } var ui; try { var app = adsk.core.Application.get(); ui = app.userInterface; // Have a body selected. var body = ui.selectEntity('Select a body', 'SolidBodies').entity; // Copy the body to the clipboard. body.copy(); // Call the paste command. var pasteCmd = ui.commandDefinitions.itemById('PasteCommand'); pasteCmd.execute(); // Start the select command to exit out of the move command that was started automatically // as a result of the paste. var selectCmd = ui.commandDefinitions.itemById('SelectCommand'); selectCmd.execute(); // Get the last body created in the active component. var comp = app.activeEditObject; var newBody = comp.bRepBodies.item(comp.bRepBodies.count-1); ui.messageBox(newBody.name); // Move the body. var input = adsk.core.ObjectCollection.create(); input.add(newBody); var transform = adsk.core.Matrix3D.create(); transform.translation = adsk.core.Vector3D.create(10,0,0); var moveFeatures = comp.features.moveFeatures; var moveInput = moveFeatures.createInput(input, transform); moveFeatures.add(moveInput); } catch (e) { if (ui) { ui.messageBox('Failed : ' + (e.description ? e.description : e)); } } adsk.terminate(); }
Ok, I'll take a look at this solution and see if it will work.
Is there any update on this issue? I am trying to make add-in to duplicate selected object by specified patterns. I wrote simple python scripts to duplicate selected object by reference to ekinsb's javascript code as follows.
bodyInput = cmd.commandInputs.itemById('SolidBodySelect') body = bodyInput.selection(0).entity bodyName = body.name # Copy body to clipboard body.copy() pasteCmd = ui.commandDefinitions.itemById('PasteCommand') pasteCmd.execute() selectCmd = ui.commandDefinitions.itemById('SelectCommand') selectCmd.execute() comp = app.activeEditObject newBody = comp.bRepBodies.item(comp.bRepBodies.count-1) ui.messageBox(str(comp.bRepBodies.count)) ui.messageBox(newBody.name) # Create collection col = adsk.core.ObjectCollection.create() col.add(newBody) # Apply Move vector = adsk.core.Vector3D.create(0, 1, 0) transform = adsk.core.Matrix3D.create() transform.translation = vector moveFeats = app.activeProduct.rootComponent.features.moveFeatures moveFeatureInput = moveFeats.createInput(col, transform) moveFeats.add(moveFeatureInput)
When I run this code, the move operation is executed before the paste operation. I guess this is because the paste operation is executed asynchronously while the move operation is asynchronously. Is it right?
It would be great if you could teach me how to duplicate and move object propery using API.
Thanks 🙂
Since I wrote the original response the API has been enhanced and you can now directly copy a body. The code below demonstrates this by copying the selected body 5 times in the model X direction.
def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface des = adsk.fusion.Design.cast(app.activeProduct) root = des.rootComponent body = adsk.fusion.BRepBody.cast(ui.selectEntity('Select a body', 'Bodies').entity) # Check to see if the body is in the root component or another one. target = None if body.assemblyContext: # It's in another component. target = body.assemblyContext else: # It's in the root component. target = root # Get the xSize. xSize = body.boundingBox.maxPoint.x - body.boundingBox.minPoint.x # Create several copies of the body. currentX = 0 for i in range(0,5): # Create the copy. newBody = body.copyToComponent(target) # Increment the position. currentX += xSize * 1.1 trans = adsk.core.Matrix3D.create() trans.translation = adsk.core.Vector3D.create(currentX, 0, 0) # Move the body using a move feature. bodyColl = adsk.core.ObjectCollection.create() bodyColl.add(newBody) moveInput = root.features.moveFeatures.createInput(bodyColl, trans) moveFeat = root.features.moveFeatures.add(moveInput) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
This works for bodies, but how would that work form components and sketches.
Any help on that, how do i change the ObjectType
When creating a copy of a component you're actually creating a new occurrence. The way to do that is demonstrated in the second post above. As far as copying sketches, it's only possible to copy sketches when working in Direct modeling model ("Do not capture design history"). The primary focus of the API has been on Parametric mode since that's what's used the most and the API doesn't currently support the ability to copy a sketch.