Skip to main content

What's New

Here you can read about major upgrades to the DynaMaker platform. If you experience any problems, let us know at support@dynamaker.com.


Update 2021-11-04

Simplified SKYMATH API

The SKYMATH module has been reworked to be easier to understand and use! Many existing functions have been deprecated and will show up as strikethorugh in the code. We recommend that you start using the new functions, but the deprecated function will continue to work as before.

Strikethrough code example

The deprecation message (highlighted in the image above) will give you a hint of what function you can use instead of the deprecated one. In this example, you can replace the call to SKYMATH.addVectors2D(v1, v2) with SKYMATH.add(v1, v2).

Many of the new functions have overload signatures, which means that the same function can work with different input. For example, the new SKYMATH.add() works in both 2D and 3D and replaces both SKYMATH.addVectors2D() and SKYMATH.addVectors3D(). It can also add two instances of the new SKYMATH.Matrix class!

SKYMATH.add(new SKYMATH.Vector2D(1, 2), new SKYMATH.Vector2D(2, 1)) // returns new SKYMATH.Vector2D(3, 3)
SKYMATH.add(new SKYMATH.Vector3D(1, 2, 3), new SKYMATH.Vector3D(3, 2, 1)) // returns new SKYMATH.Vector2D(4, 4, 4)

You can see all the overloads by clicking the arrows (or using the up and down arrows on your keyboard) next to the function signature in the code editor.

View overloads in the editor

You can read more about function overloads in the official TypeScript handbook.

Update 2021-10-21

Geometry loading effect

When geometry is being updated, after a Studio.requestGeometryUpdate(), the previous geometry will become blurred to indicate to the user that an update is running.

You can change this loading effect using CSS. For example, to make the geometry 50% grayscale in addition to the blur effect, add the following to the STYLE tab:

canvas.loading {
filter: blur(2px) grayscale(50%);
}

Applications created before this change was released can opt-in by adding a style rule in the STYLE tab. Here is the default rule used in new applications:

canvas.loading {
filter: blur(2px);
}

You can opt-out of this change altogether in the ADVANCED tab:

export function productConfigurationFactory(): STUDIO.IProductConfiguration {
return {
disableLoadingEffectOnGeometryUpdate: true,
// other settings...
}
}

Update 2021-10-07

Simplified camera API

The functions used for handling the camera have been reworked and many existing functions have been deprecated. Although we recommend that you start using the new camera functions, the deprecated function will continue to work as before, but will show up as strikethorugh in the code:

Strikethrough code example

There are now four main camera functions:

Studio.setCameraToFitBounds()
Studio.setCameraPosition()
Studio.setCameraTarget()
Studio.updateCameraSettings()

You can read more about the new camera API here!

Update 2021-08-30

Editor layout change

We have simplified the layout of how you access the different files in the code editor. By flattening the file menu to a single list on the right hand side, you can open any file in the editor with one click.

Flat file menu in code editor

Easier access to the Studio service when working in UI

The UI template has been updated so that the Studio service is global in the UI file. This only applies to new projects that you create from this update and forward. If you want you can create a new project and copy-paste this change into your existing project.

Studio global in the UI file

Update 2021-06-20

Some CAD-related classes and functions have been moved from SKYMATH to SKYCAD. Your code has been automatically updated to reflect these changes.

RefPlane moved and renamed

SKYMATH.RefPlane is now SKYCAD.Plane.

Bounds moved

SKYMATH.Bounds2D and SKYMATH.Bounds3D are now SKYCAD.Bounds2D and SKYCAD.Bounds3D respectively.

Update 2021-06-01

This update to DynaMaker simplifies working with the CAD libraries by merging the whole SKYSKETCH namespace into the SKYCAD namespace.

How does this update affect existing projects?

All references to SKYSKETCH have been changed to SKYCAD, so this update should be non-breaking. Your projects will work just like before, but instead of writing new SKYSKETCH.Layout() to create a new Layout, you write new SKYCAD.Layout() instead.

Update 2021-02-17

This update to DynaMaker, which should not break any existing projects, makes it easier to use the ComponentHandler and brings out-of-the-box support for save and load.

How does this update affect existing projects?

This update introduces a new pattern of interacting with the ComponentHandler. Existing projects may choose to continue using the old pattern and can ignore the changes described below. If you create a new component in an existing project, you may have to update it manually to make it look like before. Another way, which may be easier, is to fork an existing component in your project and build from there.

Changes to the ComponentHandler

Define components

The ComponentHandler function defineComponent() is no longer needed and should not be used.

Add components

You no longer have to add a type string when adding components to the ComponentHandler.

// old
componentHandler.add('accessory', new ACCESSORY.Component())

// new
componentHandler.add(new ACCESSORY.Component())

If you need to separate the same component class into logical groups, you may do so using tags.

// old
componentHandler.add('accessory-top', new ACCESSORY.Component())
componentHandler.add('accessory-bottom', new ACCESSORY.Component())
const topAccessories = componentHandler.getInstances('accessory-top')

// new
componentHandler.add(new ACCESSORY.Component(), { tags: ['top'] })
componentHandler.add(new ACCESSORY.Component(), { tags: ['bottom'] })
const topAccessories = componentHandler
.getInstances(ACCESSORY.Component)
.filter(inst => inst.hasTag('top'))

Get components, instances and bundles

// old
componentHandler.getInstances('accessory')
componentHandler.getComponents('accessory')
componentHandler.getBundles('accessory')

// new (provides code completion!)
componentHandler.getInstances(ACCESSORY.Component)
componentHandler.getComponents(ACCESSORY.Component)
componentHandler.getBundles(ACCESSORY.Component)

Clear a specific component

// old
componentHandler.clear('accessory')

// new, by class
componentHandler.clear(ACCESSORY.Component)
// new, by tag
componentHandler.clear('my-tag')

New application and component templates

When you create a new project or component, you might notice that the template has changed with this update.

Component

  • Extending STUDIO.BaseComponent

Components now extend the STUDIO.BaseComponent class, which adds functionality such as the getProperty function to your component automatically.

Extending STUDIO.BaseComponent

  • Constructor arguments

It is best practice to have a Component constructor without input arguments. If you need to change the values of the properties you should call component.setProperties({ ... }) after creating the component. The template has been updated to reflect this.

// old
constructor(args: Partial<CONSTANTS.Properties> = {}) {
const width = args.width ?? 100
const depth = args.depth ?? 100
const height = args.height ?? 100

this.properties = { width, depth, height }
}

// new
constructor() {
super()

this.setProperties({
depth: 100,
height: 100,
width: 100,
})
}

Save and load

If your project has authentication such as JSON Web Tokens or Auth0 enabled, the new application template together with the updated ComponentHandler allows for saving and loading configurations in your deployed project by default.

While developing

You can now test save and load directly in the application-maker editor.

Save and load in editor


Update 2020-10-20

This update to DynaMaker, which should not break any existing projects, makes it easier to create and use geometry.

Deprecations

You will notice that some classes and functions that you've used previously have been deprecated. Deprecated classes and functions still work, but should be avoided in new code that you write.

Deprecation Example Deprecated classes and functions will appear as strikethrough in the editor

Action Events

The way that actions related to the product are called from the UI code has changed for new projects. The new way brings a better developer experience through code completion and type checking.

// old way
Studio.actionEvent('generate-configurator')

// new way
ACTIONS.generateConfigurator()

The Geometry API

The way that we create and group geometry (models and sketches) has changed with this update.

  • The new class SKYCAD.GeometryGroup should be used for grouping geometry (parent-child structure)
  • SKYCAD.ModelInstance should no longer be used as a parent of other models via addChildInstance()
  • ComponentInstance.getModelInstance() is replaced by ComponentInstance.generateGeometry() and now returns a SKYCAD.GeometryGroup
  • SKYCAD.GeometryOnPlane has been deprecated in favor of the similar SKYCAD.LayoutOnPlane
  • SKYCAD.Model has been renamed to SKYCAD.ParametricModel to differentiate it from SKYCAD.MeshModel
  • SKYCAD.ModelMaterial has been renamed to SKYCAD.Material

Geometry And The Component Handler

The component handler has been updated with some new functionality that makes it simple to gather all the geometry from your components!

componentHandler.generateAllGeometry(): SKYCAD.GeometryGroup
componentHandler.generateGeometry(componentType: string): SKYCAD.GeometryGroup
componentHandler.generateAllLightweightGeometry(): SKYCAD.GeometryGroup
componentHandler.generateLightweightGeometry(componentType: string): SKYCAD.GeometryGroup

These functions position the geometry for each component instance. They require that your components implement the generateGeometry() and generateLightweightGeometry() functions respectively.

Updating The Scene

For new projects, getModels() and getSketches() in the COMPONENTS tab of the application-maker have been replaced by updateGeometry() and updateLightweightGeometry(), to give you more fine-grained control over what geometry should update and when.

// the old way

export function getModels(manager: STUDIO.Manager) {
// ...
}

export function getSketches(manager: STUDIO.Manager) {
// ...
}
// the new way

/**
* Add new Geometry to the scene depending on app state
*/
export function updateGeometry(data: STUDIO.DataForUpdateGeometry, worldControls: STUDIO.WorldControls) {
const geometryGroup = new SKYCAD.GeometryGroup()

switch (data.designStep) {
case CONSTANTS.DESIGN_STEP.PRODUCT:
geometryGroup.addGeometry(data.componentHandler.generateGeometry(CONSTANTS.COMPONENT_TYPE.MAIN))
break
case CONSTANTS.DESIGN_STEP.EXPORT:
geometryGroup.addGeometry(data.componentHandler.generateGeometry(CONSTANTS.COMPONENT_TYPE.MAIN))
break
}

worldControls.updateGeometry(geometryGroup, { groupId: 'primary' })
}

/**
* Optional lightweight geometry
*/
export function updateLightweightGeometry(data: STUDIO.DataForUpdateGeometry, worldControls: STUDIO.WorldControls) {
const geometry = data.componentHandler.generateAllLightweightGeometry()
worldControls.updateGeometry(geometry, { groupId: 'lightweight' })
}

Instead of calling Studio.update() you should use Studio.requestGeometryUpdate() and Studio.requestLightweightGeometryUpdate() together with this new update geometry pattern.

Components And The Configurator

New components created from this point forward have a new pattern for generating their configurator(s). Instead of implementing the configure() function on the component, you should export one or more functions from the

PARAMETERS tab in the component-maker.

Generate Configurator Functions You can switch between different configurators with the dropdown in the upper left corner

In the application, use the generator functions to generate the configurator instead of calling configure().

// old way
export function actionEvent(type: string, args: any, manager: STUDIO.Manager) {
// ...

switch (type) {
case 'configure-component': return component.configure()
}
}

// new way
export function configureMainComponent() {
const component = getMainComponent()
return COMPONENT1.generateConfigurator(component)
}