In this lesson, we’ll create a simple shoebox with two parts: a lid and a bottom box.

The sample code for C++, Python and Typescript are available.
Let’s begin with the bottom box first. We’ll create a data object for storing the parameters.
@dataclass
class BoxParameters:
border_thickness : float
bottom_thickness : float
inner_width : float
inner_length : float
inner_height : float
fillet_size : float
def __init__(self, border_thickness: float, bottom_thickness:float, inner_width:float, inner_length:float, inner_height:float, fillet_size:float):
self.border_thickness = border_thickness
self.bottom_thickness = bottom_thickness
self.inner_width = inner_width
self.inner_length = inner_length
self.inner_height = inner_height
self.fillet_size = fillet_size
typedef struct
{
double borderThickness;
double bottomThickness;
double innerWidth;
double innerLength;
double innerHeight;
double filletSize;
} BoxParameters;/pre>
class BoxParameters {
public border_thickness : number;
public bottom_thickness : number;
public inner_width : number;
public inner_length : number;
public inner_height : number;
public fillet_size : number;
constructor(border_thickness: number, bottom_thickness:number, inner_width:number, inner_length:number, inner_height:number, fillet_size:number, input_units:string){
this.border_thickness = border_thickness;
this.bottom_thickness = bottom_thickness;
this.inner_width = inner_width;
this.inner_length = inner_length;
this.inner_height = inner_height;
this.fillet_size = fillet_size;
}
}
We have six parameters here: height/width/length of the box; the thickness for the box’s border and bottom sides and the fillet size. We’ll create two boxes, since they only have a few dimension differences, we want to reuse our codes if possible, so we’ll create a function for creating a box. There will be a space between two parts, so we’ll also have a margin parameter.
def create_box(design: adsk.fusion.Design, parameter: BoxParameters, margin: float, body_name:str, component_name:str)->adsk.fusion.Component:
input_units = 'mm'
border_thickness = parameter.border_thickness
bottom_thickness = parameter.bottom_thickness
inner_width = parameter.inner_width
inner_length = parameter.inner_length
inner_height = parameter.inner_height
fillet_size = parameter.fillet_size
Ptr<Component> createBox(Ptr<Design> design, const BoxParameters ¶meters, double margin, const std::string&
bodyName, const std::string& componentName)
{
const std::string inputUnits("mm");
double borderThickness = parameters.borderThickness;
double bottomThickness = parameters.bottomThickness;
double innerWidth = parameters.innerWidth;
double innerLength = parameters.innerLength;
double innerHeight = parameters.innerHeight;
double filletSize = parameters.filletSize;
function createBox(design: adsk.fusion.Design, parameter: BoxParameters, margin: number, body_name:string, component_name:string): adsk.fusion.Component | null {
const input_units = 'mm';
var border_thickness = parameter.border_thickness;
var bottom_thickness = parameter.bottom_thickness;
var inner_width = parameter.inner_width;
var inner_length = parameter.inner_length;
var inner_height = parameter.inner_height;
var fillet_size = parameter.fillet_size;
Before creating the boxes, let convert our units to the one active in Fusion. My default parameters are using millimeter of metric system. We’ll convert it to the one Fusion using.
# We may take different input units than default units in Fusion. We'll need to convert them first.
units_manager = design.fusionUnitsManager
default_units = units_manager.internalUnits
border_thickness = units_manager.convert(border_thickness, input_units, default_units)
bottom_thickness = units_manager.convert(bottom_thickness, input_units, default_units)
inner_width = units_manager.convert(inner_width, input_units, default_units)
inner_length = units_manager.convert(inner_length, input_units, default_units)
inner_height = units_manager.convert(inner_height, input_units, default_units)
fillet_size = units_manager.convert(fillet_size, input_units, 'mm')
margin = units_manager.convert(margin, input_units, default_units)
// We may take different input units than default units in Fusion. We'll need to convert them first.
Ptr<UnitsManager> unitsManager = design-<fusionUnitsManager();
const std::string defaultUnits = unitsManager-<internalUnits();
borderThickness = unitsManager->convert(borderThickness, inputUnits, defaultUnits);
bottomThickness = unitsManager->convert(bottomThickness, inputUnits, defaultUnits);
innerWidth = unitsManager->convert(innerWidth, inputUnits, defaultUnits);
innerLength = unitsManager->convert(innerLength, inputUnits, defaultUnits);
innerHeight = unitsManager->convert(innerHeight, inputUnits, defaultUnits);
// I'll keep fillet using mm since 0.5mm is hard to read when it converts to inches.
filletSize = unitsManager->convert(filletSize, inputUnits, std::string("mm"));
margin = unitsManager->convert(margin, inputUnits, defaultUnits);
// We may take different input units than default units in Fusion. We'll need to convert them first.
const units_manager = design.fusionUnitsManager;
const default_units = units_manager.internalUnits;
border_thickness = units_manager.convert(border_thickness, input_units, default_units);
bottom_thickness = units_manager.convert(bottom_thickness, input_units, default_units);
inner_width = units_manager.convert(inner_width, input_units, default_units);
inner_length = units_manager.convert(inner_length, input_units, default_units);
inner_height = units_manager.convert(inner_height, input_units, default_units);
fillet_size = units_manager.convert(fillet_size, input_units, default_units);
margin = units_manager.convert(margin, input_units, default_units);
Now, we can begin to create boxes. We'll create it under root components.
There are multiple ways to create the box, for example, we can create box and use shell feature; or we can create a sketch and extrude.
In this to tutorial, we'll create sketches and use extrude feature to create boxes.
First, let's create a sketch. We'll draw it on the XZ plane using rectangle.
# Get root component
rootComponent = design.rootComponent
# Get references to the sketches and plane
sketches = rootComponent.sketches
xzPlane = rootComponent.xZConstructionPlane
# Create a new sketch and get lines reference
sketch_outer_base = sketches.add(xzPlane)
base_width_total = border_thickness * 2.0 + inner_width
base_length_total = border_thickness * 2.0 + inner_length
pointOne = adsk.core.Point3D.create(margin + -base_width_total / 2.0,-base_length_total / 2.0, 0)
pointTwo = adsk.core.Point3D.create(margin + base_width_total / 2.0, base_length_total / 2.0, 0)
# Create a rectangle sketch
rectangles = sketch_outer_base.sketchCurves.sketchLines
rectangles.addTwoPointRectangle(pointOne, pointTwo)
// Get root component
Ptr<Component> rootComponent = design->rootComponent();
// Get references to the sketches and plane
Ptr<Sketches> sketches = rootComponent->sketches();
Ptr<ConstructionPlane> xzPlane = rootComponent->xZConstructionPlane();
// Create a new sketch and get lines reference
Ptr<Sketch> sketchOuterBase = sketches->add(xzPlane);
double baseWidthTotal = borderThickness * 2.0 + innerWidth;
double baseLengthTotal = borderThickness * 2.0 + innerLength;
Ptr<Point3D> pointOne = Point3D::create(margin - baseWidthTotal / 2.0, -baseLengthTotal / 2.0, 0);
Ptr<Point3D> pointTwo = Point3D::create(margin + baseWidthTotal / 2.0, baseLengthTotal / 2.0, 0);
// Create a rectangle sketch
Ptr<SketchLines> rectangles = sketchOuterBase->sketchCurves()->sketchLines();
rectangles->addTwoPointRectangle(pointOne, pointTwo);
// Get root component
const rootComponent = design.rootComponent;
// Get references to the sketches and plane
const sketches = rootComponent.sketches;
const xzPlane = rootComponent.xZConstructionPlane;
// Create a new sketch and get lines reference
const sketch_outer_base = sketches.add(xzPlane)!;
var base_width_total = border_thickness * 2.0 + inner_width;
var base_length_total = border_thickness * 2.0 + inner_length;
var pointOne = adsk.core.Point3D.create(margin + -base_width_total / 2.0,-base_length_total / 2.0, 0)!;
var pointTwo = adsk.core.Point3D.create(margin + base_width_total / 2.0, base_length_total / 2.0, 0)!;
// Create a rectangle sketch
var rectangles = sketch_outer_base.sketchCurves.sketchLines;
rectangles.addTwoPointRectangle(pointOne!, pointTwo!);
Now, we'll extrude it. After multiple geometries are drawn, there could be multiple ways to form a drawing. They are profiles, we can use profiles in the sketch to get them. Since we only have one drawing now, it is profile 0.
# Create extrusion input
base_sketch_profile = sketch_outer_base.profiles.item(0)
extrudes = rootComponent.features.extrudeFeatures
base_extrude_newbody = extrudes.createInput(base_sketch_profile, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
# Define that the extent is a distance of bottom thickness + inner height.
# Our input unit is mm, API is using cm. So, we'll need to convert it into cm.
base_extrude_distance = adsk.core.ValueInput.createByReal((bottom_thickness + inner_height))
base_object_extend_definition = adsk.fusion.DistanceExtentDefinition.create(base_extrude_distance)
base_extrude_newbody.setOneSideExtent(base_object_extend_definition, adsk.fusion.ExtentDirections.PositiveExtentDirection)
base_extrude_newbody.isSolid = True
new_extrude_feature = extrudes.add(base_extrude_newbody)
// Create extrusion input
Ptr<Profile> baseSketchProfile = sketchOuterBase->profiles()->item(0);
Ptr<ExtrudeFeatures> extrudes = rootComponent->features()->extrudeFeatures();
Ptr<ExtrudeFeatureInput> baseExtrudeNewBody = extrudes->createInput(baseSketchProfile, FeatureOperations::NewBodyFeatureOperation);
// Define that the extent is a distance of bottom thickness + inner height.
// Our input unit is mm, API is using cm. we'll need to convert it into cm.
Ptr<ValueInput> baseExtrudeDistance = ValueInput::createByReal(bottomThickness + innerHeight);
Ptr<DistanceExtentDefinition> baseObjectExtendDefinition = DistanceExtentDefinition::create(baseExtrudeDistance);
baseExtrudeNewBody->setOneSideExtent(baseObjectExtendDefinition, ExtentDirections::PositiveExtentDirection);
baseExtrudeNewBody->isSolid(true);
Ptr<ExtrudeFeature> newExtrudeFeature = extrudes->add(baseExtrudeNewBody);
// Create extrusion input
const base_sketch_profile = sketch_outer_base.profiles.item(0)!;
const extrudes = rootComponent.features.extrudeFeatures;
var base_extrude_newbody = extrudes.createInput(base_sketch_profile, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)!;
// Define that the extent is a distance of bottom thickness + inner height.
// Our input unit is mm, API is using cm. we'll need to convert it into cm.
const base_extrude_distance = adsk.core.ValueInput.createByReal((bottom_thickness + inner_height))!;
const base_object_extend_definition = adsk.fusion.DistanceExtentDefinition.create(base_extrude_distance)!;
base_extrude_newbody.setOneSideExtent(base_object_extend_definition, adsk.fusion.ExtentDirections.PositiveExtentDirection);
base_extrude_newbody.isSolid = true;
var new_extrude_feature = extrudes.add(base_extrude_newbody)!;
Now, we'll dig a hole in the box. Let's find the top face of new created body first.
We'll need two points to find a face, let's define them first.
# Let's dig a hole in the new created box.
# We need two points to find a face. We want to find top and bottom face as beginning and end here.
base_top_point1 = adsk.core.Point3D.create(margin + -base_width_total / 2.0, bottom_thickness + inner_height, -base_length_total / 2.0)
base_top_point2 = adsk.core.Point3D.create(margin + base_width_total / 2.0, bottom_thickness + inner_height, base_length_total / 2.0)
base_bottom_point1 = adsk.core.Point3D.create(margin + -base_width_total / 2.0, 0.0, -base_length_total / 2.0)
base_bottom_point2 = adsk.core.Point3D.create(margin + base_width_total / 2.0, 0.0, base_length_total / 2.0)
// Let's dig a hole in the new created box.
// We need two points to find a face. We want to find top and bottom face as beginning and end here.
Ptr<Point3D> baseTopPoint1 = Point3D::create(margin - baseWidthTotal / 2.0, bottomThickness + innerHeight, -baseLengthTotal / 2.0);
Ptr<Point3D> baseTopPoint2 = Point3D::create(margin + baseWidthTotal / 2.0, bottomThickness + innerHeight, baseLengthTotal / 2.0);
Ptr<Point3D> baseBottomPoint1 = Point3D::create(margin - baseWidthTotal / 2.0, 0.0, -baseLengthTotal / 2.0);
Ptr<Point3D> baseBottomPoint2 = Point3D::create(margin + baseWidthTotal / 2.0, 0.0, baseLengthTotal / 2.0);
// Let's dig a hole in the new created box.
// We need two points to find a face. We want to find top and bottom face as beginning and end here.
const base_top_point1 = adsk.core.Point3D.create(margin -base_width_total / 2.0, bottom_thickness + inner_height, -base_length_total / 2.0)!;
const base_top_point2 = adsk.core.Point3D.create(margin + base_width_total / 2.0, bottom_thickness + inner_height, base_length_total / 2.0)!;
const base_bottom_point1 = adsk.core.Point3D.create(margin -base_width_total / 2.0, 0.0, -base_length_total / 2.0)!;
const base_bottom_point2 = adsk.core.Point3D.create(margin + base_width_total / 2.0, 0.0, base_length_total / 2.0)!;
Now, we'll find top and bottom faces with these points and draw a rectangle on the top face for cutting later.
# Let's get the new body
base_extrude_item = new_extrude_feature
base_extrude_body = base_extrude_item.bodies.item(0)
# Find the faces.
bottom_face = None
sketch_inner_base = None
for face in base_extrude_body.faces:
top_point1_flag = face.isPointOnFace(base_top_point1, epsilon)
top_point2_flag = face.isPointOnFace(base_top_point2, epsilon)
bottom_point1_flag = face.isPointOnFace(base_bottom_point1, epsilon)
bottom_point2_flag = face.isPointOnFace(base_bottom_point2, epsilon)
if top_point1_flag and top_point2_flag:
sketch_inner_base = sketches.add(face)
pointOne = adsk.core.Point3D.create(-inner_length / 2.0,margin -inner_width / 2.0, 0)
pointTwo = adsk.core.Point3D.create(inner_length / 2.0, margin + inner_width / 2.0, 0)
rectangles = sketch_inner_base.sketchCurves.sketchLines
rectangles.addTwoPointRectangle(pointOne, pointTwo)
if bottom_point1_flag and bottom_point2_flag:
bottom_face = face
// Let's get the new body
Ptr<ExtrudeFeature> baseExtrudeItem = newExtrudeFeature;
Ptr<BRepBody> baseExtrudeBody = baseExtrudeItem->bodies()->item(0);
// Find the faces.
Ptr<BRepFace> bottomFace = nullptr;
Ptr<Sketch> sketchInnerBase = nullptr;
Ptr<BRepFaces> faces = baseExtrudeBody->faces();
for (unsigned i = 0; i < faces->count(); ++i)
{
Ptr<BRepFace> face = faces->item(i);
bool topPoint1Flag = face->isPointOnFace(baseTopPoint1, epsilon);
bool topPoint2Flag = face->isPointOnFace(baseTopPoint2, epsilon);
bool bottomPoint1Flag = face->isPointOnFace(baseBottomPoint1, epsilon);
bool bottomPoint2Flag = face->isPointOnFace(baseBottomPoint2, epsilon);
if (topPoint1Flag && topPoint2Flag)
{
sketchInnerBase = sketches->add(face);
pointOne = Point3D::create(-innerLength / 2.0, margin - innerWidth / 2.0, 0);
pointTwo = Point3D::create(innerLength / 2.0, margin + innerWidth / 2.0, 0);
rectangles = sketchInnerBase->sketchCurves()->sketchLines();
rectangles->addTwoPointRectangle(pointOne, pointTwo);
}
if (bottomPoint1Flag && bottomPoint2Flag)
{
bottomFace = face;
}
}
// Let's get the new body
const base_extrude_item = new_extrude_feature;
var base_extrude_body = base_extrude_item.bodies.item(0)!;
// Find the faces.
var bottom_face: adsk.fusion.BRepFace | null = null;
var sketch_inner_base: adsk.fusion.Sketch | null = null
for (var i = 0; i < base_extrude_body.faces.count; ++i) {
const face = base_extrude_body.faces.item(i)!;
const top_point1_flag = face.isPointOnFace(base_top_point1, epsilon)!;
const top_point2_flag = face.isPointOnFace(base_top_point2, epsilon)!;
const bottom_point1_flag = face.isPointOnFace(base_bottom_point1, epsilon)!;
const bottom_point2_flag = face.isPointOnFace(base_bottom_point2, epsilon)!;
if (top_point1_flag && top_point2_flag){
sketch_inner_base = sketches.add(face)!;
pointOne = adsk.core.Point3D.create(-inner_length / 2.0,margin -inner_width / 2.0, 0)!;
pointTwo = adsk.core.Point3D.create(inner_length / 2.0, margin + inner_width / 2.0, 0)!;
rectangles = sketch_inner_base.sketchCurves.sketchLines
rectangles.addTwoPointRectangle(pointOne, pointTwo);
}
if (bottom_point1_flag && bottom_point2_flag){
bottom_face = face;
}
}
If we have found the faces and finished drawing. Since our new rectangle is smaller than the original one, it will create two profiles.
One is the rectangle itself, another one is the part between the previous rectangle and the new one. We'll use the second one to extrude.
We'll create a cut operation with ToEntityExtent using distance to the bottom face.
# Have we found top face and bottom face?
if (bottom_face is not None) and (sketch_inner_base is not None):
# There are two profiles
# The first one is the border between the new sketch and first sketch
# The second one is the sketch we've just drawn.
# We'll need the second one here.
base_inner_profile = sketch_inner_base.profiles.item(1)
bottom_object_extend_definition = adsk.fusion.ToEntityExtentDefinition.create(bottom_face, False, adsk.core.ValueInput.createByReal(-bottom_thickness))
base_extrude_cut = extrudes.createInput(base_inner_profile, adsk.fusion.FeatureOperations.CutFeatureOperation)
base_extrude_cut.setOneSideExtent(bottom_object_extend_definition, adsk.fusion.ExtentDirections.NegativeExtentDirection)
base_extrude_cut.isSolid = True
extrudes.add(base_extrude_cut)
// Have we found top face and bottom face?
if (bottomFace != nullptr && sketchInnerBase != nullptr)
{
// There are two profiles
// The first one is the border between the new sketch and first sketch
// The second one is the sketch we've just drawn.
// We'll need the second one here.
Ptr<Profile> baseInnerProfile = sketchInnerBase->profiles()->item(1);
Ptr<ToEntityExtentDefinition> bottomObjectExtendDefinition = ToEntityExtentDefinition::create(bottomFace, false, ValueInput::createByReal(-bottomThickness));
Ptr<ExtrudeFeatureInput> baseExtrudeCut = extrudes->createInput(baseInnerProfile, FeatureOperations::CutFeatureOperation);
baseExtrudeCut->setOneSideExtent(bottomObjectExtendDefinition, ExtentDirections::NegativeExtentDirection);
baseExtrudeCut->isSolid(true);
extrudes->add(baseExtrudeCut);
}
// Have we found top face and bottom face?
if (bottom_face != null && sketch_inner_base != null){
// There are two profiles
// The first one is the border between the new sketch and first sketch
// The second one is the sketch we've just drawn.
// We'll need the second one here.
const base_inner_profile = sketch_inner_base.profiles.item(1)!;
const bottom_object_extend_definition = adsk.fusion.ToEntityExtentDefinition.create(bottom_face, false, adsk.core.ValueInput.createByReal(-bottom_thickness)!)!;
const base_extrude_cut = extrudes.createInput(base_inner_profile, adsk.fusion.FeatureOperations.CutFeatureOperation)!;
base_extrude_cut.setOneSideExtent(bottom_object_extend_definition, adsk.fusion.ExtentDirections.NegativeExtentDirection)!;
base_extrude_cut.isSolid = true;
extrudes.add(base_extrude_cut)
}
At last, we'll create a fillet operation on all edges.
We'll need to create an object collection and add all the edges to it. It'll be used for the fillet operation.
# Let's add fillet feature
fillet_features = rootComponent.features.filletFeatures
fillet_input = fillet_features.createInput()
fillet_edges = adsk.core.ObjectCollection.create()
for edge in base_extrude_body.edges:
fillet_edges.add(edge)
fillet_size_value_input = adsk.core.ValueInput.createByString(f'{fillet_size} mm')
fillet_input.edgeSetInputs.addConstantRadiusEdgeSet(fillet_edges, fillet_size_value_input, False)
fillet_features.add(fillet_input)
// Let's add fillet feature
Ptr<FilletFeatures> filletFeatures = rootComponent->features()->filletFeatures();
Ptr<FilletFeatureInput> filletInput = filletFeatures->createInput();
Ptr<ObjectCollection> filletEdges = ObjectCollection::create();
for (unsigned i = 0; i < baseExtrudeBody->edges()->count(); ++i)
{
Ptr<BRepEdge> edge = baseExtrudeBody->edges()->item(i);
filletEdges->add(edge);
}
char buffer[128];
snprintf(buffer, sizeof(buffer), "%.2f mm", filletSize);
Ptr<ValueInput> filletSizeValueInput = ValueInput::createByString(buffer);
filletInput->edgeSetInputs()->addConstantRadiusEdgeSet(filletEdges, filletSizeValueInput, false);
filletFeatures->add(filletInput);
// Let's add fillet feature
const fillet_features = rootComponent.features.filletFeatures;
var fillet_input = fillet_features.createInput()!;
var fillet_edges = adsk.core.ObjectCollection.create()!;
for (var i = 0; i < base_extrude_body.edges.count; ++i){
const edge = base_extrude_body.edges.item(i)!;
fillet_edges.add(edge);
}
const fillet_size_value_input = adsk.core.ValueInput.createByString(`${fillet_size} mm`)!;
fillet_input.edgeSetInputs.addConstantRadiusEdgeSet(fillet_edges, fillet_size_value_input, false);
fillet_features.add(fillet_input);
Finally, let's make our new box a component and rename it.
base_extrude_body.name = body_name
new_body = base_extrude_body.createComponent()
component = new_body.parentComponent
component.name = component_name
return component
baseExtrudeBody->name(bodyName);
Ptr<BRepBody> newBody = baseExtrudeBody->createComponent();
Ptr<Component> component = newBody->parentComponent();
component->name(componentName);
return component;
base_extrude_body.name = body_name;
const new_body = base_extrude_body.createComponent()!;
const component = new_body.parentComponent;
component.name = component_name;
return component;
Now, we'll add call create boxes in the run function.
We'll add the border size to the width/length/height. The lid box should be bigger than the bottom box.
The margin are the distance between two boxes, it is 50mm here.
# Units are in mm
bottom_box_parameters = BoxParameters(4.0, 4.0, 190.0, 390.0, 110.0, 0.5)
# The bottom, I need to add the border thickness to the inner width/length
top_box_parameters = BoxParameters(4.0, 4.0, 198.0, 398.0, 30.0, 0.5)
# I want to put it a base margin of 50mm between each box in the design view.
base_margin = 50.0
"""This function is called by Fusion when the script is run."""
default_units = None
try:
# Get the design through active product
design = adsk.fusion.Design.cast(app.activeProduct)
if not design:
ui.messageBox("The DESIGN workspace must be active when running this command.")
return
create_box(design, bottom_box_parameters, (-bottom_box_parameters.inner_width - bottom_box_parameters.border_thickness) / 2.0 - base_margin, "bottom_body", "box")
create_box(design, top_box_parameters, base_margin + (top_box_parameters.border_thickness + top_box_parameters.inner_width) / 2.0, "top_body", "lid")
BoxParameters bottomBoxParameters;
bottomBoxParameters.borderThickness = 4.0;
bottomBoxParameters.bottomThickness = 4.0;
bottomBoxParameters.innerWidth = 190.0;
bottomBoxParameters.innerLength = 390.0;
bottomBoxParameters.innerHeight = 110.0;
bottomBoxParameters.filletSize = 0.5;
BoxParameters topBoxParameters;
topBoxParameters.borderThickness = 4.0;
topBoxParameters.bottomThickness = 4.0;
topBoxParameters.innerWidth = 198.0;
topBoxParameters.innerLength = 398.0;
topBoxParameters.innerHeight = 30.0;
topBoxParameters.filletSize = 0.5;
const double baseMargin = 50.0;
Ptr<Design> design = app->activeProduct();
if (!design)
{
ui->messageBox("The DESIGN workspace must be active when running this command.");
return false;
}
createBox(design, bottomBoxParameters, (-bottomBoxParameters.innerWidth - bottomBoxParameters.borderThickness) / 2.0 - baseMargin, "bottom_body", "box");
createBox(design, topBoxParameters, baseMargin + (topBoxParameters.borderThickness + topBoxParameters.innerWidth) / 2.0, "top_body", "lid");
return true;
}
When running TypeScript locally, it could read parameter from ProjectName.json file. We'll put our default parameters in it.
{
"border_thickness": 0.15748031496062992,
"bottom_thickness" : 0.15748031496062992,
"inner_width": 7.480314960629921,
"inner_length" : 15.354330708661418,
"bottom_inner_height" : 4.330708661417323,
"lid_inner_height" : 1.1811023622047245,
"fillet_size" : 0.01968503937007874,
"input_units" : "in"
}
Here is the code in the run method.
// Get the parameters
const scriptParameters = JSON.parse(adsk.parameters);
if (!scriptParameters)
{
throw Error("Invalid parameters.");
}
adsk.log(`Running script with parameters: ${JSON.stringify(scriptParameters)}`);
const border_thickness : number = scriptParameters.border_thickness;
const bottom_thickness : number = scriptParameters.bottom_thickness;
const inner_width : number = scriptParameters.inner_width;
const inner_length : number = scriptParameters.inner_length;
const bottom_inner_height : number = scriptParameters.bottom_inner_height;
const lid_inner_height : number = scriptParameters.lid_inner_height;
const fillet_size : number = scriptParameters.fillet_size;
const input_units : string = scriptParameters.input_units;
// I want to put it a base margin of 50mm between each box in the design view.
let base_margin = 50.0;
const design = app.activeProduct as adsk.fusion.Design;
const top_enlarge_size = border_thickness * 2
// Let's create our input parameters based on the input
const bottom_box_parameters = new BoxParameters(border_thickness,
bottom_thickness,
inner_width,
inner_length,
bottom_inner_height,
fillet_size,
input_units);
const top_box_parameters = new BoxParameters(border_thickness,
bottom_thickness,
inner_width + top_enlarge_size,
inner_length + top_enlarge_size,
lid_inner_height,
fillet_size,
input_units);
const units_manager = design.fusionUnitsManager;
base_margin = units_manager.convert(base_margin, "mm", input_units);
createBox(design, bottom_box_parameters, (-bottom_box_parameters.inner_width - bottom_box_parameters.border_thickness) / 2.0 - base_margin, "bottom_body", "box");
createBox(design, top_box_parameters, base_margin + (top_box_parameters.border_thickness + top_box_parameters.inner_width) / 2.0, "top_body", "lid" );
In the next part we'll make our script an add-in. It will show a dialog and accept user inputs.

Leave a Reply