Skip to main content

My First Drawing

Let's create your first drawing in DynaMaker!

In this tutorial, you will learn how to create and autogenerate drawings. As a product example, we will reuse the staircase from My First Assembly.

For this we will follow 5 steps:

  1. Set up Drawing Editor
  2. Projections
  3. Modify header
  4. BOM list
  5. Drawing format

Don't forget to check the common mistakes if you get stuck. Good luck!

In the previous tutorial, we worked just with components by using the Component Editor. For the drawings we will do something similar but with its own editor or Drawing Editor.

1. Set Up Drawing Editor

When you create a new project, you will find there is a section for creating drawing in Exporters, right below your components. If you create a new one (named e.g. DrawingTemplate) and open it you will see the Drawing Editor, a tool for creating custom drawings.

A. Drawing Editor Basics

Why using Drawing Editor? It provides several advantages compared to regular drawings from other known CAD software solutions:

  • Using the same template for different components.
  • Using the same template for different purposes with minor changes. For example:
    • DXF for laser cutting with scale 1 : 1.
    • PDF including dimensions for quotations with different scales and views.
  • Customizing drawing format and content depending on the component properties.
  • Testing your drawing with presets allows you to try specific values of the component properties without making changes in the app/component.
  • Testing is simple: just two buttons to download the drawing as PDF or DXF, and a third to switch between presets.
  • And others like:
    • Having multiple pages with different content.
    • Adding tables automatically (BOM list, header, etc.) with combined cells.
    • Changing color/style/scale of the content as desired.

This said, let's jump into it, but first we need to make sure we use the correct component.

B. Use Correct Component

Notice that DrawingTemplate is using a default geometry of a cube, so we need to make sure we import the component we want, i.e. Assembly.

  • In edit/hide imports... above the code editor, add Assembly from the imports dropdown. See how the #region import updates automatically.

Now we need to replace the old preset with the new one we want. See that both the function generateDrawing() in DRAWING and the presets are using a geometry as input. This is ok when you have to show a simple geometry in the drawing. Then the presets would look like the following:

Show drawing presets with geometry as input:
export const drawingPreset = new PRESET.PresetDrawing(DRAWING.generateDrawing)

const assemblyComponentA = new ASSEMBLY.Component()
drawingPreset.addCase([assemblyComponentA.generateGeometry()], { label: 'Default' })

const assemblyComponentB = new ASSEMBLY.Component()
assemblyComponentB.setProperties({ width: 2500, depth: 500, height: 3000 })
drawingPreset.addCase([assemblyComponentB.generateGeometry()], { label: 'W: 2500, D: 500, H: 3000' })

However, if you want to get more information from the component (e.g. size for dimensions, BOM list for a table, etc), it's best to send the component you want to make a drawing of as input. Since we need the component later in this tutorial, we will switch the input from geometry to Assembly component.

  • In DRAWING, make sure you have assemblyComponent as input and create the geometry out of it, since it's used for the default projections in the drawing template.

    export function generateDrawing(assemblyComponent: ASSEMBLY.Component) {
    const geometry = assemblyComponent.generateGeometry()

    // rest of logic
    }
  • In PRESETS, make sure to have some presets that cover the edge cases. As examples:

    export const drawingPreset = new PRESET.PresetDrawing(DRAWING.generateDrawing)

    const assemblyComponentA = new ASSEMBLY.Component()
    drawingPreset.addCase([assemblyComponentA], { label: 'Default' })

    const assemblyComponentB = new ASSEMBLY.Component()
    assemblyComponentB.setProperties({ width: 2500, depth: 500, height: 3000 })
    drawingPreset.addCase([assemblyComponentB], { label: 'W: 2500, D: 500, H: 3000' })
  • Keep adding more cases until you think you have covered the edge cases (e.g. smallest & biggest staircase possible, a wide but short one, a narrow but high one, etc)

  • Save & Update (Ctrl+S) to finally see the drawing with the chosen preset.
  • Try going through your presets and download the drawing as it as 📥 PDF and 📥 DXF. For the latter, you can try any available free online DXF viewer.

Great! We will polish and keep adding more details to the drawing, like:

  • adjusting the views or projections position, including dimensions and a third ISO view.
  • adding logo & new cells to the header
  • adding a bill of materials (BOM) as a table at the top-right corner, with some extra info.
  • changing the drawing content depending on the file format.

2. Projections

See that the default views need to be refined: they need more space in between, more dimensions and probably some extra space to make sure it does not collide with the header and the later BOM table. Also, we will change the position of the view so it follows the European standard for technical drawings (ISO, first angle projection) and we will add a third projection as an isometric view.

A. Adjust Position

Let's say we want two projections for the following front and side views:

In order to put these projections in the drawing we will go through some general tips that you can implement yourself before seeing the solution below:

  • A drawing contains pages with a defined size
  • For an easier placement, both projections will be placed in a single layout called e.g. contentLayout, so that it everything in it follows the same scale.
  • Projections as a SKYCAD.Layout can be done through SKYCAD.project(geometry, plane).
  • The content (layouts) added to a page is done through drawing.addContent(pageNr, layout), which includes some useful optional arguments:
    • fitInside as an object with bounds of the content to fit in, and validScales as a list of scales to apply
    • textSize of the text in your layout that ignores autoscaling (useful when you want all text presented in the drawing to be exactly 3-mm high as textSize: 3)
    • align as an object to autocenter your layout accordingly
  • drawing.addContent() returns scale as a number and scaleLabel as a string that can be used in other layouts or headers if needed.
  • A header is considered a layout that is always at the bottom-right of the drawing. Instead of placing it through the needed alignment, drawing.setHeader(layout) can be used instead.

Before seeing the solution below, you can try to implement these ideas yourself. In the end, you should end up having something similar to the following:

export function generateDrawing(assemblyComponent: ASSEMBLY.Component) {
const { width } = assemblyComponent.getProperties()
const geometry = assemblyComponent.generateGeometry()

// Drawing
const drawing = new SKYDRAWING.Drawing()
const pageSize = new SKYMATH.Vector2D(297, 210)
const margin = 10

// Page 1
let pageNr = 1
drawing.addPage(pageNr, {
pageHeight: pageSize.y,
pageWidth: pageSize.x,
margin,
})

// Content
const contentLayout = new SKYCAD.Layout()

// --- front view
const frontPlane = new SKYCAD.Plane(-1, 0, 0, 2000) // offset of 2000 should be enough not to collide with the geometry
const frontProjectionLayout = SKYCAD.project(geometry, frontPlane)
contentLayout.addLayout(frontProjectionLayout)

// --- side view
const sidePlane = new SKYCAD.Plane(0, 1, 0, 2000)
const sideProjectionLayout = SKYCAD.project(geometry, sidePlane)
contentLayout.addLayout(sideProjectionLayout, {
position: new SKYMATH.Vector2D(width + 500, 0),
})

// --- content in drawing
const contentBounds = new SKYCAD.Bounds2D( // adjusted so that it doesn't collide with the header
new SKYMATH.Vector2D(margin, margin),
new SKYMATH.Vector2D(0.65 * pageSize.x, pageSize.y - 3 * margin),
)

const validScales = [1]
for (let i = 0; i < 300; i++) validScales.push(1 / i)

const { scaleLabel } = drawing.addContent(pageNr, contentLayout, {
textSize: 3, // sets all text presented in the drawing to real size 3
fitInside: {
bounds: contentBounds,
validScales,
},
align: {
horizontal: 'center',
vertical: 'center',
ignoreAnnotations: false, // includes or not dimensions and text in the alignment
},
})

// Header
const headerLayout = generateHeaderLayout({
title: 'Staircase',
pageNr,
nPages: drawing.getPages().length,
scale: `${scaleLabel} (A4)`,
})
drawing.setHeader(pageNr, headerLayout)

return drawing
}

Notice that we have defined validScales as a list of scales from 1:1 to 1:300. If it's not defined it follows the ISO standard (certain set of values). If defined as an empty list [], it will find the exact value that makes the layout fit to the exact bounds, regardless of decimals - useful when scale doesn't need to be shown.

For simplicity, we have a layout (or sketch container) for each projection (frontProjectionLayout & sideProjectionLayout) since we want to add the dimensions later separately. Also, see that we have translated one of the projections with the width of the assembly, so the local coordinate system of both layouts stays in the bottom-left corner, making it easier to handle them later.

Finally, Save & Update (Ctrl+S) to see the staircase correctly placed in the drawing. The code above should result in something like this:

Good job. Don't worry about the header yet, we will go through it later. As a next step let's add the dimensions to the projection layouts

B. Add Dimensions

Before you add the layouts to the contentLayout, you can add some dimensions to the layouts between the start and end point. You can use some of the optional arguments:

  • texRotation to change the rotation of the text in the dimensions
  • decimals to set the number of decimals shown
  • offset of the dimension
  • extendLinesToTarget makes the dimension go the the exact point when true
  • continuousArrow places the text on top of the dimension when true
  • directionOfMeasurement defines the direction of measurement between the two points

Let's add the dimensions that clearly show the width, depth and height of the staircase in the projections.

export function generateDrawing(assemblyComponent: ASSEMBLY.Component) {
const { width, depth, height } = assemblyComponent.getProperties()
const geometry = assemblyComponent.generateGeometry()

// Drawing

// Page 1

// Content

// --- front view
const frontPlane = new SKYCAD.Plane(-1, 0, 0, 2000)
const frontProjectionLayout = SKYCAD.project(geometry, frontPlane)
frontProjectionLayout.addDimension(new SKYMATH.Vector2D(-depth, 0), new SKYMATH.Vector2D(-depth, height), {
textRotation: Math.PI / 2,
decimals: 0,
offset: 300,
extendLinesToTarget: true,
continuousArrow: true,
})
frontProjectionLayout.addDimension(new SKYMATH.Vector2D(-depth, 0), new SKYMATH.Vector2D(0, 0), {
textRotation: 0,
decimals: 0,
offset: -300,
extendLinesToTarget: true,
continuousArrow: true,
})
contentLayout.addLayout(frontProjectionLayout)

// --- side view
const sidePlane = new SKYCAD.Plane(0, 1, 0, 2000)
const sideProjectionLayout = SKYCAD.project(geometry, sidePlane)
sideProjectionLayout.addDimension(new SKYMATH.Vector2D(-width, height), new SKYMATH.Vector2D(0, 0), {
textRotation: 0,
decimals: 0,
offset: -300,
extendLinesToTarget: true,
continuousArrow: true,
directionOfMeasurement: new SKYMATH.Vector2D(1, 0),
},
)
contentLayout.addLayout(sideProjectionLayout, {
position: new SKYMATH.Vector2D(width + 500, 0),
})

// --- content to drawing

// Header

return drawing
}
  • Save & Update (Ctrl+S) to see the dimensions.

Depending on how realistic you want your drawings to be, you should follow a standard (e.g. ISO) that determines the rules behind dimensions, view placement, etc. Knowing the different parts of a dimension (i.e. dimension line, auxiliary or extension line, arrowheads, etc) these are some general tips and rules:

  • dimension lines should never cross each other or touch the projected geometry.
  • auxiliary or extension lines can cross each other and can go through the projected geometry.
  • dimensions should be placed so that the text can be read comfortably.
  • dimensions should not be redundant or confuse the reader.
  • dimensions should be placed in proper views so that they are shown clearly.
  • dimensions should be thinner that the lines of the projected geometry.

C. Line Thickness

Before adding the isometric view, let's change the line thickness of the layouts, so we follow the last tip mentioned above. You can do it by changing the argument of every layout used. However if all these are added to the same layout, you can change its optional arguments, overwriting the settings of all the sublayouts that don't use the default ones. So for that, let's modify the optional arguments of contentLayout:

export function generateDrawing(assemblyComponent: ASSEMBLY.Component) {
// Properties & geometry

// Drawing

// Page 1

// Content
const contentLayout = new SKYCAD.Layout({
defaultSketchLineThickness: 0.5,
defaultDimensionLineThickness: 0.001,
})

// --- front view

// --- side view

// --- content to drawing

// Header

return drawing
}
  • Save & Update (Ctrl+S) to see the dimensions thinner.

If you zoom-in in the drawing-preview downloaded as PDF, you will see the difference in line thicknesses:

And finally, let's add the isometric view on top of the header with a specific scale.

D. Isometric view

An isometric view is nothing more than another projection with a different direction. As you have noticed, projections are always orthographic, regardless of the component perspective view. Let's say we want to have a 1 : 80 scale for it and place it slightly above the header (which has 24 mm of height if you check its size by accessing the bounds of the layout through layout.getBounds().getSize()):

export function generateDrawing(assemblyComponent: ASSEMBLY.Component) {
// Properties & geometry

// Drawing

// Page 1

// Content

// --- front view

// --- side view

// --- content to drawing

// Isometric view
const isoScale = 1 / 80
const isoProjectionLayout = new SKYCAD.Layout({ defaultDimensionLineThickness: 0.3 })
const isoPlane = new SKYCAD.Plane(-1, 1, 1, 2000)
const isoProjection = geometry.generateProjection(isoPlane)
isoProjectionLayout.addSketch(isoProjection.visible)
const isoProjectionLayoutSize = isoProjectionLayout.getBounds().getSize()
isoProjectionLayout.addText(`1 : ${1 / isoScale}`, {
position: new SKYMATH.Vector2D(-isoProjectionLayoutSize.x / 2, -750),
align: 'center',
})

drawing.addContent(pageNr, isoProjectionLayout, {
position: new SKYMATH.Vector2D(pageSize.x - 2.5 * margin, 40),
scale: isoScale,
textSize: 3
})

// Header

return drawing
}

Ideally you could use the argument fitInside and extract scaleLabel to add it later as text. However, for simplicity of the tutorial see that we use a fixed scale of 1:80.

  • Save & Update (Ctrl+S) to see the isometric view above the default header.

In technical drawings, the standard says that layouts that don't follow the scale of the drawing should have their scale visible. E.g. in this case we added 1 : 80 below the only layout that is not scaled 1 : 26 as the drawing says.

Great! Now we can say we are done with the views and projections and we can move on with the header.

3. Modify Header

A header is nothing more than a table with rows and columns with the particularity that you can have different settings for each cell, e.g. like labels, row and column span, colors, etc. Here we will add a picture as a logo and add an extra column for the projection standard used and the revision number for example.

  • Download any picture you want for your logo. You can try with the DynaMaker logo.
  • Go back to the app dashboard.
  • Upload your picture under Files and give it the default name DYNAMAKER_LOGO_PNG.
  • Still in the dashboard, create an image under Images from that file, so its name results in DYNAMAKER_LOGO.
  • Go again into DrawingTemplate.
  • In edit/hide imports... (below the top tabs), make sure to import ASSETS (if you don't see it, try refreshing with the spinning arrow icon and now ASSETS should show up if you uploaded a file correctly)
  • In DRAWING, go the function generateHeaderLayout() and replace the logo definition (you can search withCtrl+F) with:
const logo = ASSETS.IMAGES.DYNAMAKER_LOGO
  • Save & Update (Ctrl+S) to see the DynaMaker logo in the header.

The logo becomes autoscaled to fit the maximum space possible in the cell due to the logic that is added right after this row. Of course, you can change the scale and remove the logic (or even just adjust the variable created for it named logoMaxWidth)

B. Add New Column

We will add an extra column to the table in the middle including two cells:

  • one with two rows for showing the projection standard with a picture, i.e. ISO for European.
  • one for the revision number, in case later manufacturing changes are approved.

Both functionalities will be added in the function generateHeaderLayout(). You can be creative in this part, e.g. you could end up having something like:

function generateHeaderLayout(args: {
scale?: string
nPages?: number
pageNr?: number
title?: string
} = {}) {
const scale = args.scale ?? '1:1'
const pageNr = args.pageNr ?? 1
const nPages = args.nPages ?? 1
const title = args.title ?? 'Staircase'

// Table
const defaultTextSize = 3
const rowHeight = 2 * defaultTextSize
const table = new SKYCAD.Table({
defaultTextSize: 3,
columnWidths: [60, 30, 20],
rowHeights: [rowHeight, rowHeight, rowHeight, rowHeight]
})

// First column
table.addText('', 0, 0, { rowspan: 3 })
table.addText(title, 3, 0, { label: 'Title' })

// Second column
table.addText('', 0, 1, { label: 'ISO', rowspan: 3 })
table.addText('1', 3, 1, { label: 'Revision' })

// Third column
table.addText('mm', 0, 2, { label: 'Units', })
table.addText(scale, 1, 2, { label: 'Scale' })
table.addText((new Date()).toISOString().split('T')[0], 2, 2, { label: 'Date' })
table.addText(`${pageNr} / ${nPages}`, 3, 2, { label: 'Page' })

// Logo
const logo = ASSETS.IMAGES.DYNAMAKER_LOGO
const logoCellPadding = 3
const logoCellWidth = logo.width - 2 * logoCellPadding
const logoCellHeight = 3 * rowHeight - 2 * logoCellPadding
const logoScale = Math.min(logoCellWidth / logo.width, logoCellHeight / logo.height)
const logoWidthScaled = logo.width * logoScale
const logoHeightScaled = logo.height * logoScale
table.setColumnWidth(0, logoWidthScaled + 2 * logoCellPadding)

// Table to Layout
const headerLayout = table.generateLayout()
const headerSize = headerLayout.getBounds().getSize()
headerLayout.addImage(logo, {
position: new SKYMATH.Vector2D(logoCellPadding, headerSize.y - logoCellPadding - (logoCellHeight + logoHeightScaled) / 2),
scale: logoScale
})
// headerLayout.addImage(ASSETS.IMAGES.ISO_STANDARD, { // use your own picture
// position: new SKYMATH.Vector2D(63, 9), // adjust according to your picture
// scale: 0.032 // adjust according to your picture
// })

return headerLayout
}

You could also reuse the logic used for autofitting the logo into the cell as done in the template. Here we simply write the numbers needed for the position & scale, since the header size won't be dynamic for simplicity of the tutorial.

  • Save & Update (Ctrl+S) to see your new header with an extra column.

See that some presets might collide with the header. In order to avoid that, you can adjust contentBounds. The following should be enough:

 const contentBounds = new SKYCAD.Bounds2D(
new SKYMATH.Vector2D(margin, 0.12 * pageSize.y),
new SKYMATH.Vector2D(0.65 * pageSize.x, pageSize.y - 3 * margin))

As for the images, you see that a cell with no text is added so that when the table is converted into a layout the image can be added to the layout with a certain position and scale. We are currently working on this so you could in the future add the images to the table directly as table.addImage().

Great. We will add another table at the top-right corner that contains the list of components intended for manufacturing, i.e. bill of materials (BOM).

4. BOM List

We will fetch the instances with their components so that we can display their name, size and quantity. This data could be created in the Assembly and then used in the drawing to create the table accordingly.

A. Components BOM

  • Go back to the app dashboard.
  • Go into the Assembly and go to COMPONENT.
  • Create a new function within the class Component (e.g. like generateGeometry()) that creates list of objects with properties name, size & qty:
export class Component extends STUDIO.BaseComponent<CONSTANTS.Properties> {
constructor() {
// logic of constructor()
}

update() {
// logic of update()
}

generateGeometry() {
// logic of generateGeometry()
}

getComponentsData() {
const { width, depth, height } = this.properties
// Steps
const steps = this.componentHandler.getInstances(STEP.Component)
const stepComponent = steps[0]!.getComponent()
const stepWidth = stepComponent.getProperty('width')
const stepThickness = stepComponent.getProperty('height')
const stepData = {
name: 'Step',
size: `${stepWidth}x${depth}x${stepThickness}`,
qty: steps.length,
}

// Railing
const railings = this.componentHandler.getInstances(RAILING.Component)
const railingComponent = railings[0]!.getComponent()
const railingHeight = railingComponent.getProperty('railingHeight')
const glassThickness = 15 // should be connected to a constant from Railing instead
const railingData = {
name: 'Railing',
size: `${width}x${height + railingHeight}x${glassThickness}`,
qty: railings.length,
}

return {
stepData,
railingData,
}
}
}
  • Save & Update and Publish your component to be able to use this function in DrawingTemplate.

Notice that in this case, all the instances share the same component (i.e. with the same properties). However, that's not usually the case. We might have steps which differ in size and therefore we should have a list with all stepData that includes all types of steps with different sizes, quantities, name, etc. For simplification, we have created 1 data for each type of component.

If you want to have a more robust way of creating a BOM, you can check the section BOM of this how-to example.

B. Add New Table

  • Good. Now go back to the dashboard and go into DrawingTemplate.
  • In DRAWING, create the function generateBomLayout() that generates a layout from a table (same as the header) that uses getComponentsData() from the component Assembly. Place it outside generateDrawing(). E.g.:
function generateBomLayout(assemblyComponent: ASSEMBLY.Component) {
const componentsData = assemblyComponent.getComponentsData() // Refresh the page (F5) to reload the Intellisense if this is still highlighted in red. Make sure you published Assembly.

const table = new SKYCAD.Table({
defaultTextSize: 3,
columnWidths: [15, 30, 10],
})

let rowNr = 0

// Title row
table.addText('Name', rowNr, 0)
table.addText('Size', rowNr, 1)
table.addText('Qty', rowNr, 2)
rowNr++

// Railing row
table.addText(`${componentsData.railingData.name}`, rowNr, 0)
table.addText(`${componentsData.railingData.size}`, rowNr, 1)
table.addText(`${componentsData.railingData.qty}`, rowNr, 2)
rowNr++

// Steps row
table.addText(`${componentsData.stepData.name}`, rowNr, 0)
table.addText(`${componentsData.stepData.size}`, rowNr, 1)
table.addText(`${componentsData.stepData.qty}`, rowNr, 2)

const layout = table.generateLayout()
return layout
}
  • In generateDrawing(), add this layout as content to the drawing in the top-right corner:
export function generateDrawing(assemblyComponent: ASSEMBLY.Component) {
// Properties & geometry

// Drawing

// Page 1

// Content (front view, side view, content to drawing)

// Isometric view

// BOM
const bomLayout = generateBomLayout(assemblyComponent)
drawing.addContent(pageNr, bomLayout, { align: { vertical: 'top', horizontal: 'right' } })

// Header

return drawing
}

function generateHeaderLayout(args) {
// logic of generateHeaderLayout()
}

function generateBomLayout(assemblyComponent: ASSEMBLY.Component) {
// logic of generateBomLayout()
}

Adding content with only align places the layout so that it's automatically moved to the drawing corners, making it ideal to place tables to the drawing. Alternatively, use position to place the content freely within the page.

  • Save & Update to see the BOM table at the top-right.

5. Drawing Format

As the last step, the drawing will change to scale 1 : 1 when it's for a DXF so that the customer has the design with real dimensions and can measure freely without any problem. For that, we will adjust some scales with simple if-statements in DrawingTemplate, remove the isometric view for the DXF, and adjust the page size accordingly. Also, presets will help to see the differences right away.

  • First off, let's add an argument in generateDrawing(), e.g. fileType, adjust the scale in the header, remove the isometric view and return a new drawing (trueSizeDrawing) that has the content scaled accordingly. You can create a variable enum FILE_TYPE to assist your coding.
export enum FILE_TYPE {
PDF = 'pdf',
DXF = 'dxf',
}

export function generateDrawing(
assemblyComponent: ASSEMBLY.Component,
{ fileType = FILE_TYPE.PDF } = {},
) {
// Properties & geometry

// Drawing

// Page 1

// Content

// --- front view

// --- side view

// --- content to drawing
const validScales = [1]
for (let i = 0; i < 300; i++) validScales.push(1 / i)
const { scale, scaleLabel } = drawing.addContent(pageNr, contentLayout, { // get scale to rescale true-size drawing
// rest of arguments as before
})

// Isometric view
if (fileType === FILE_TYPE.PDF){
// logic of isometric view
}

// BOM

// Header
const headerLayout = generateHeaderLayout({
title: 'Staircase',
pageNr,
nPages: drawing.getPages().length,
scale: fileType === FILE_TYPE.PDF ? `${scaleLabel} (A4)` : `1:1`,
})
drawing.setHeader(pageNr, headerLayout)

if (fileType === FILE_TYPE.PDF) {
return drawing
} else { // (fileType === FILE_TYPE.DXF)
const page1 = drawing.getPages()[0]!
const trueSizeLayout = page1.generateLayout()
trueSizeLayout.scale(1 / scale)
const trueSizeDrawing = new SKYDRAWING.Drawing()
const trueSizePageHeight = pageSize.y / scale
const trueSizePageWidth = pageSize.x / Scale
trueSizeDrawing.addPage(pageNr, {
pageHeight: trueSizePageHeight,
pageWidth: trueSizePageWidth,
})
trueSizeDrawing.addContent(pageNr, trueSizeLayout)
return trueSizeDrawing
}
}
It's up to you how you want to use if-statements:
  • in-line to save some space (suitable when only 2 alternatives):
const value = (condition) ? alternativeA : alternativeB

// same as:

const value = (condition)
? alternativeA
: alternativeB
  • most common way
let value = alternativeA
if (condition1) {
value = alternativeB
} else if (condition2) {
value = alternativeC
} else {
value = alternativeD
}
  • common way skipping {} (suitable for very short logic)
let value = alternativeA
if (condition) value = alternativeB
else if (condition2) value = alternativeC
else value = alternativeD
  • Secondly, try different presets so that they change fileType. In PRESETS add new components in new cases as:
export const drawingPreset = new PRESET.PresetDrawing(DRAWING.generateDrawing)

// assemblyComponentA

// assemblyComponentB

const assemblyComponentC = new ASSEMBLY.Component()
assemblyComponentC.setProperties({ width: 3000, depth: 1000, height: 4500 })
drawingPreset.addCase([assemblyComponentC, { fileType: DRAWING.FILE_TYPE.PDF }], {
label: 'PDF - W: 3000, D: 1000, H: 4500',
})

const assemblyComponentD = new ASSEMBLY.Component()
assemblyComponentD.setProperties({ width: 3000, depth: 1000, height: 4500 })
drawingPreset.addCase([assemblyComponentD, { fileType: DRAWING.FILE_TYPE.DXF }], {
label: 'DXF - W: 3000, D: 1000, H: 4500',
})
  • Save & Update to apply changes to the presets
  • Switch presets in the dropdown of the top-left corner of the preview section.

In a DXF editor that allows real measurements, you will see that new manual dimensions in the drawing will have the exact real measurements, since the scale is now 1:1, matching the predefined dimensions. Naturally, when having a PDF format, the dimensions will be scaled accordingly.

Remember that the buttons 📥 PDF and 📥 DXF at the top-left corner of the Drawing Editor download the preview-drawing that is currently shown as a PDF and DXF file respectively. It has nothing to do with the variable fileType, which is something that will be most likely used in the UI Editor (not covered in this tutorial). As always, we show the common example of use below.


Congratulations! You have created your first drawing. Having it in an app could look like this (check 📥 Export):


Now that you know how to autogenerate drawings dynamically, it is time to explain one more powerful feature before we dive into the app itself, and that is the configurator. Go on to the next tutorial Configurators to learn more!