Roomle Configuration Catalog Structure Format
Kernelversion 2.24.0
Definitions
Catalogs
A catalog consists of items, components, tags and materials. It can be private (visible only to selected users and the owner) or public (available for all Roomle users).
Tag
Tags are the way items are organized in catalogs. Each catalog must have at least one root-tag. Tags can be structured hierarchically and one tag can be a child of multiple other tags. Each Tag is linked to one catalog and must have a (globally) unique identifier.
Item
An item is an object that can be added to a plan or loaded into a configurator. This can be a normal 3D object or a pre-defined configuration of components. Each item belongs to exactly one catalog but can be linked to multiple tags. Items which are not linked to any tag are not visible to the user. Every item must have a unique SKU (within the catalog). The terms item and product refer to the same thing and can be used interchangeably.
Component
A component is the basic element used for configurable objects. Each component contains a definition on how this component can be configured and used within configurations. Similar to items, components can be linked to multiple tags. Every component must have a unique identifier (within the catalog).
Mesh
Within each catalog you can define meshes to be used in the geometry-script of a component. Each mesh can have data for different formats and quality levels. At the moment only CRT (Corto compressed meshes) with Realtime quality (level 50) is used. Within the script the mesh can be inserted with the AddExternalMesh command. The MeshId is the combined id <catalogId>:<meshId>.
Defined meshes (external meshes in the script) improve loading performance since only those meshes are loaded that are currently needed. In contrast to scripted meshes where the whole mesh is part of the script and needs to be interpreted even if not shown. Furthermore defined meshes provide the client with the ability to reuse the mesh (since defined meshes have an id and are const by definition) within the scene which also improves performance and memory usage.
Material
Within each catalog you can define materials that can be used in the geometry script of a component. Each material can have no or multiple textures assigned to it for use. Each material must have a unique identifier (within the catalog).
Configurations
When talking about configurable items you must distinguish between what we call "configuring variants" (which is basically just changing colors, product dimensions, etc.) and "combining components to one object" (creation of new objects and products - real configuration). Components can be seen as templates for the basic elements of configurable objects. A component itself can not be used within a plan. To use a component within a plan it must be embedded into a configurated item, which is an item with a given configuration. The configuration (see section configuration format) defines the actual variant of the involved components used in the configuration.
Configuring variants
An example for configuring variants is a table where you can change the dimensions and the material of the surface. In Roomle this can be modeled as one component with parameters for the dimensions and the material. This table within a plan is defined through a configuration containing only one component.
Combining components
More complex configurations arise when multiple components can be combined together, e.g. a frame with different possible shelves that can be added. Every configuration must have exactly one root-component. Details on docking components can be found in 2.5{reference-type="ref" reference="dockingComponents"}
Roomle Configuration Format
The Roomle Configuration Format is serialized as JSON file.
Coordinate system
The coordinate system within the Roomle ConfigurationScript is a left-handed cartesian coordinate system with +Z
as the up vector and +Y
as the forward direction of the model. In the 3d file 1 Model Unit
has to correspond to 1mm
real world size of the object.
Component definition
The component definition defines how a component should be displayed, which parameters are possible and the interaction with other components. It includes all information needed within the configurator. This includes:
A condition when the component is considered valid. This can be used for Components who must have specific parameters/dockings set to be valid.
A list of possible parameters including the possible values and a default value per parameter
A list of possible ParentDockings and ChildDockings. These are the connectors to combine different components.
A list of possible SiblingPoints. These are connectors throu which components can transfer data (e.g. parameter values) regardless of the parent-child connection.
A list of possible AddOnSpots. These are visual aids for the User.
A list of possible Subcomponents which can be used within the geometry script and will be displayed in the partlist
The article number script written in RoomleScript
The geometry script written in RoomleScript
The geometryHD script written in RoomleScript. This version is used in special clients for higher resolution and quality. Besides thatit follows the same logic and definitions as the geometry script. Everything that can be done in the geometry script can be done in geometryHD too.
The previewGeometry script written in RoomleScript. When provided, this geometry is used to preview objects during adding of new children. If not provided, the geometry script is used. All geometry-script functions work the same in the previewGeometry. If provided the previewGeometry script should be less complex than the real geometry script to improve performance during the insertion.
The boundingGeometry is intended to define the simplified boundaries of the components geometry that can be used for collision detection and cutting holes of construction objects in walls.
The boundingGeometry script written in RoomleScript.
The packageSize contains a Array<int>, these are all the numbers of packages which are allowed for this component
The packaging contains a list of sizes with conditions for adding certain sizes if needed
The price calculation written in RoomleScript
an onUpdate RoomleScript which is executed everytime something changes within the component. Within this script even parameters of the component may be changed.
Parameters
A component is completely defined by the values of its parameters. Parameters have multiple ways to control where and how it is shown and behaves.
If all connected parameters behind a global parameter have the same value, the global parameter is automatically set to this value.
visible: shown to the user as part of the component. Default value
true
.enabled: user can modify the value. Default value
true
.global: all global parameters with the same key within a configuration are combined together and shown globally. The global value for a parameter-key may differ from the actual value on the component (if the component-parameter is changed after the global value is set). New components get the global value assigned automatically on dock. If all connected parameters behind a global parameter have the same value, the global parameter is automatically set to this value. Default value
false
.volatile: If this property is set, the parameter is not stored in the configuration. Default value
false
.visibleAsGlobal: the global parameter is shown if any of the connected component parameters is set as "visibleAsGlobal", otherwise its invisible globally. visible and visibleAsGlobal can be completely independent. Default value
true
.visibleInPartlist: if this parameter should be shown in the partlist. parameters not visible in the partlist are also ignored in the aggregation of components in the partlist. Default value
true
.userTriggeredChange: is set to true, if onValueChange is triggered from user. Then for corresponding key respective values fetched from json will be set. if onValueChange is internal trigger, values are ignored.
an onValueChange RoomleScript which can be provided for every Parameter and is executed on startup (change from no value to the first/default value) and every time this parameter changes.
visibleInPlanner: If the parameter is "global" and "visibleInPlanner", the object parameter is delivered with the PlanObject when a plan overview or an individual plan object is requested. If the "visibleInPlanner" property of the parameter is set but not the "global" property, then a warning is generated when the component is read and the parameter is treated as if "visibleInPlanner" would be "false".
Parameter and possible children level
The visibility of parameters and possible children are restricted and are only visible if the user level exceeds the restriction. Therefore the property level
needs to be added to parameters or possible children. The value of the property can only be an integral constant. The default restriction level is 0, so these parameters are visible to all users. The user level is set via an environment variable and is 0 by default. The core only populates the parameters and possible children that the user can access. Thus, a user with a higher level can access more parameters and more restricted parameters can be accessed by fewer users. As the default level of each parameter is 0, this new feature has no impact on the live content, as any user can access parameters with level 0 (unrestricted).
Subcomponents
Every component can contain multiple subcomponents. A subcomponent references a component with all of its scripts and computations. The main component may set parameters of the subcomponents via assignments. It's also possible for the main component to define one or more subcomponents as active. If defined, the main component can take parameters of the active subcomponents to supersede its own.
Supersedings
For active subcomponents the main component may define supersedings. If a superseding parameter is defined, it completly replaces the parameter of the main component with the same key if one exists. This means that from outside it behave as if the parameter were the parameter of the main component itself although the validValues and all calculations are done in the subcomponent.
This is specially useful for cases where the main component acts as a metacomponent which only decides which subcomponent is used. In this case all calculations can stay subcomponent specific without the need to copy them to the main component while still having all logic available.
The values of the superseded parameters are also available in the main component (and may override existing values in the main component) and can be used in geometry, docking etc. Be aware that the values of the superseding parameters may not be available on the initial executions of "onUpdate" since the component needs to initialize itself before knowing what parameters will be superseded. Consider using ifnull in such a case.
Optionally, the key used to access the substituted parameters in the component can be specified by adding an override object with a key attribute. This is useful for avoiding parameter shadowing in the main component and for superseding parameters with the same name from different subcomponents. In the script, the substituted parameter can be used just as if there were a parameter with the used override key.
By default, the substituted parameter maps to the same group specified in the subcomponent. This default behavior can be changed by setting an override group. Membership in a group can even be removed by assigning an empty string to the override group.
Plan interaction
Information about how the object interacts with the plan, such as the intersection of the PlanComponent with walls.
Data
Getting data
Static JSON data that can be queried in RoomleScript with the functions getData
, getDataOrNull
or getDataWithDefault
. While getData
generates an error if the data is not found, getDataOrNull
and getDataWithDefault
never generate an error and always return a valid value. getDataOrNull
returns null
if the data is not found, while getDataWithDefault
has an additional default argument that is returned if the data is not found. The default argument is only evaluated if the data is not found.
The getData*
can return not only values, but also objects and arrays. The elements of the objects can be accessed with the .
(member access) operator. Multidimensional arrays or lists of arrays are not supported because the RoomleScript does not support multidimensional arrays at all, not even for basic data types.
Example
getData*
returns a copy of the data. The elements of objects can also be assigned. Note that this only changes the data in the variable, but of course not the data in the component.
In the Roomle script, the names of the variables can also be self
, other
, child
, parent
, sibling
, connection
, other_connection
, parameter
and object
. Despite the fact that this is a bad style, it does not contradict the corresponding context names. However, if such a variable is an object, the context must be explicitly specified when accessing the object's members.
Elements of arrays of objects can be accessed with the get
function:
Elements of arrays of objects can be overwritten with the set
function:
As for any other array, the length of an array of objects can be get with the length
function:
Evaluating data
In addition to the gerData*
functions, there are evaluateData
, evaluateDataOrNull
or evaluateDataWithDefault
. These functions work exactly like the corresponding getData*
functions, however, if the data is a string, the string is treated as an expression and evaluated. The expressions in the data are not parsed when the component is loaded, but only at runtime when the particular element in "data" is evaluated for the first time. Note that to prevent recursion, it is not allowed to call a getData*
or evaluateData*
function again within a data expression.
Example
With the functions getSubComponentData
, getSubComponentDataOrNull
, getSubComponentDataWithDefault
, evaluateSubComponentData
, evaluateSubComponentDataOrNull
and evaluateSubComponentDataWithDefault
data from subcomponents can be accessed. The functions work exactly like the corresponding getData*
and evaluateData*
functions, but have an additional argument at the beginning, which is the internal ID of the subcomponent.
Example
Finding data
In addition to getting or evaluating data, the data can also be filtered using the findData
, findSubComponentData
, findAndEvaluateData
, and findAndEvaluateSubComponentData
functions. findData" returns the filtered objects and values as they are. findAndEvaluateData
treats expressions as strings and evaluates them before filtering. With the functions findSubComponentData
, and findAndEvaluateSubComponentData
data from subcomponents can be accessed.
The last arguments of this functions is the filter functions, which can be a script function ot a component function. The function must have exactly 2 arguments, the key and the value of the data object and The function must return a boolean value. If an array is searched, the key is a 'Decimal' number with the index of the element. If an object is searched for, the key is a "String" value with the key of the data object. All functions return an array with the matches. If no value matches the filter, an empty array is returned. If an object is searched for, the returned array contains objects with 2 properties. The name of the first property is "key" and contains the key of the matching object. The name of the second property is "value" and contains the value of the matching object.
If the functions are used with a component function, the first argument of the component function must be the key and the second argument of the function must be the value. The values are passed to the function in the order of the arguments, not in the order of the keys. So if the name of the first argument is "value" and the name of the second argument is "key", this is just bad naming, but it does not change the order of the arguments. Default values of the arguments are of no use:
If the functions are used to look up array data, all the values that match the filter are returned in an array. If no value matches the filter, an empty array is returned. Regardless of whether you search in objects or arrays, arrays with key value pairs are always returned. If you search in arrays, the "key" is the index of the element found. The indices of course start with 0. When searching in objects, the "key" is the name of the property found. "value" is the element found.
The content of valueA
is an array with 2 object:.
The content of valueB
is an array with 2 objects:
The content of valueC
is an empty array with 2 objects with the properties "key" and "value":
If no value matches the filter, an empty array is returned.
The content of valueD
is an empty array []
.
The data is evaluated prior to filtering:
The content of valueE
is an array with 3 objects:
With findDataKey
and findSubComponentDataKey
it is also possible to search only for indices and keys of objects and values. The functions work exactly like the corresponding findData
and findSubComponentData
functions, but return only the keys or indices of the matching objects and values instead of key-value pairs.
The content of valueA
is an array with 2 indices: [2, 3]
.
The content of valueB
is an array with 2 indices: [2, 3]
.
The content of valueC
is an empty array with 2 keys ['key3', 'key4']
.
If no value matches the filter, an empty array is returned.
The content of valueD
is an empty array []
.
Plugin Data
It is possible to add plugin-data to the component-definition. Only data of well known plugins is considered. The details on the json structure can be found below. More details about the concepts and usage can be found in Plugin Documentation
imos
To transfer structural data from rml-configurations to imos, the components need additional information:
the zones for the imos topology
dividers to split up the zones
elements to be used in the zones with well known CP_PART_NAME (those need to exist in imos already)
for the main component (the root element) we also need the dimensions (width/depth/height) of the furniture, the rootzone and possible other attributes to be added to the main article.
The definition of a rootzone within the plugin-data of a component defines the start of a new article. All child- and subcomponents of this component will be added to this article. That is the zones, divisions and elements of those components. Until a new root-zone is found which triggers the next article.
Every element in the imos plugindata is interpreted as an expression and executed within the context of the component before put into the pxm export.
Every part within the imos plugindata (zone,division,element) can contain an "active" node which is interpreted as boolean expression. If this expression is present and evaluates to false, the part is not added to the pxm-export. an articleDescription with no active zone, is completly ignored for the export.
sample json part:
Sample file
id
string
the global unique id of the component. It is combined from the unique id of the catalog and an unique id of the component within the catalog
onUpdate
Script
a Script being executed on every changes. Setting of parametervalues within this script persist.
valid
Script
a condition to evaluate if the component is considered valid.
label
Script
A script being executed when the label is requested. Once preset, the label map ("labels") is ignored.
labels
map
a map containing key-value pairs for the label of this component. The keys are the isocodes of the language. The values are the labels to be used.
parameters
array
list of the possible parameters of this component
parameterGroups
array
list of the possible parameterGroups of this component.
possibleChildren
array
list of the possibleChild objects defining possible children for this component. Each child must have either itemId or componentId. Items must be configurable. Can have a script defining if it is the default. If multiple possible children evaluate default to true, its undefined which one is taken as the default child.
parentDockings
map
contains the definitions for all possible dockings where other components can be docked to this component as children. There can be points, lines, ranges (of points) and lineRanges.
childDockings
map
contains the definitions of all possible dockingPoints where this component can be docked to another component as a child. This contains only points.
addOnSpots
array
contains the definitions of all possible addOnSpots.
subComponents
array
list of possible subcomponents of this component. They can be referenced from the geometryScript and the previewGeometry by the internalId. If the component itself should appear in the partlist additionally to the subcomponents, a backreference is possible.
articleNr
string
the script to calculate the articleNr that should be displayed in the partlist. If the script contains only a string, this string is used as the articleNr. Otherwise the content of the variable "articleNr" is used.
packageSizes
array
list of numbers of packages which are allowed for this component
packaging
array
list of sizes with conditions for adding certain sizes if needed
dimensionings
array
list of all dimensionings that might be used.
siblings
array
contains the definitions of all possible siblingPoints.
geometry
string
the geometry script for this component. For details see the RoomleScript chapter.
geometryHD
string
the geometry script for higher quality of this component. For details see the RoomleScript chapter.
previewGeometry
string
the geometry script for this component in previewmode. For details see the RoomleScript chapter.
environmentGeometry
string
the geometry script for the environment of this component
boundingGeometry
string
the geometry script for the bounds of this component
planInteraction
object
definition about how the object interacts with the plan
data
object
contains the subobject with plugin-specific data
plugin-data
object
data that can be queried with the function getData
, getDataOrNull
or getDataWithDefault
Measuring of Components
By default the Configurator takes the real bounding box of the geometry as the measurements. If necessary the scripter can provide a custom definition for the shown measurements with the setBoxForMeasurement command in the onUpdate script. When the command is called, the display of the measurements behaves as if the component would consist only of a simple Cube with the size and offset as given in the command.
Combining Components
Components can be docked to each other via dockpoints. Each Component can have at most one parent which leads to a parent-child treehierachy. It is possible to transfer data from one component to another. Either directly via the Dockingconnection or via Siblingconnections which can be created between any two components. Data is transfered via assignments.
Labels
Components, Parameters, Parameter Groups and Value objects can have a label. A Label is a user friendly name used to represent the object in the user interface. Labels can be defined with either a language map or a script. A label map is a collection of language and label pairs. If the label for a requested language does not exist in a label map, the English label is used. If the English label is requested but does not exist, the key or value of the object is used instead of the label. In a label script, a label will be generated completely dynamically. Once a label script is preset, the label map is ignored. However, the label from the labels
map is the input label of the label script.
Label map exsample:
Label script examples:
Value object label scripts can be combined with the automatically unit formatted values. In the example below, the values label of the "size" parameter is "ø 100 cm" if isRound
and "100 cm" otherwise.
Docking
Each component can define dockingPoints and dockingLines where other components can be docked to (called ParentDockings) and dockingPoints (called ChildDockings) through which this component can be docked to the ParentDockings of other components. Components which are docked to another component A are called the children of A. Through the docking connection the parent can set parameters of the child, e.g. the width of a shelf can be set by the parent frame. The child can also set parameters of the parent. There are three types of assignments: onDock, onUpdate and onUndock.
When a new component is docked the assignments are always first executed on the parent side. Meaning
assignmentOnDock in parentDocking
assignmentOnDock in childDocking
assignmentOnUpdate in parentDocking
assignmentOnUpdate in childDocking
Assignments in the onDock Block doesn't trigger recursive onUpdate actions themself.
On configuration changes, only the update assignments from the changed component are executed.
On Undock the order is reversed:
assignmentOnUnDock in childDocking
assignmentOnUnDock in parentDocking
One ParentDockPoint can only be used by one ChildDockPoint, on the other hand one ParentDockLine can be used by multiple ChildDockPoints at once. The maximum possible Children on a DockLine can be set via the maxChildren property.
Dynamically change docking
If an existing dock-connection and the parent-child relationship becomes invalid (due to a changed condition or changed masks), the child is undocked from their parent. In principle and dogmatically, an undocked child (a child without a parent) and all of its children (the entire child tree) are deleted immediately. However, in order to prevent unnecessary deletion, an alternative docking between the child and the parent is sought and, if found, established (docked) before the children are deleted. This feature enables completely dynamic changes of docking points. When the docking is changed, the child's position is recalculated and automatically changed depending on the new position and rotation, whereby the distance from the new to the old position is not restricted. If there is more than 1 possible new docking position, the position that causes the smallest translation of the child component is selected.
Delete PlanComponent and try to keep the children
If a PlanComponent is deleted and the children of the deleted PlanCmponent should be kept, it must be attempted to dock the children to the parent. A child can only be kept if it can be docked to the parent. Therefore, a matching docking point with a mask that matches the parent's mask must be found. Which child has priority when docking to the parent depends on the "persistent" and "priority" properties of the "parentDockings" to which the children are currently docked. This means that the PlanComponet to be deleted decides via the "persistent" and "priority" properties of the "parentDockings" which children are retained. If "persistent" is set to "false", a child element cannot be docked at all to the parent of its parent. The default value for "persistent" is "true". All chides that may be docked to the parent of their parent are sorted by the attribute "priority" and are attempted to dock in this order. If the attribute "Priority" is not set, this means the lowest priority.
In the following example, component "A" has a child "B". "B" itself has three children "C1", "C2" and "C3". For the parent docking of "B" to "C1", the attribute "persistent" is set to "false". The parent docking of "B" to "C2" has set the attribute "persistent" to "true" and "priority" 1. The parent docking of "B" to "C3" has set the attribute "persistent" to "true" and "priority" 1.
PlanComponent "B" is deleted. The root PlanComponent can only take over one of the 3 children because it has only one docking point. The PlanComponent "C1" is not "persistent", so it is not docked to the root PlanComponent. "C1" is automatically deleted. "C2" has the higher priority than "C3", so that "C2" is docked to the root PlanComponent and "C3" is automatically deleted.
Collision detection of docked components
Sometimes a newly added component would collide with an existing one. In some cases this is the expected behavior but in other scenarios the collision should not be allowed. It is possible to define a collisionCondition
script for DockingPoints, DockingLines, DockingPointRanges and DockingLineRanges. The collisionCondition
script defines if a collision with another component is allowed for the corresponding docking. If the collisionCondition
script evaluates to false
all docking previews of colliding components get discarded, so it is not possible to add a component there. A list (array) of all colliding components can be retrieved inside of the collisionCondition
script via collidingComponentIDs
. It is an array which contains the IDs of all colliding components, ordered by their overlapping volume from largest to smallest. There are also some additional functions available inside the collisionCondition
script:
getComponentProperty(key:string, *componentId:int)
getBoxOrigin(*componentId:int)
getBoxSize(*componentId:int)
getBoxForMeasurementOrigin(*componentId:int)
getBoxForMeasurementSize(*componentId:int)
These functions have been extended and optionally accept an additional parameter to retrieve the corresponding data from a specific component via its ID. The IDs inside the collidingComponentIDs
variable can be used in this case.
The calculation of the collision detection is based on axis aligned bounding box calculations. So for determination if something is colliding or not the BoundingBox
or BoxForMeasurement
(if available) get used. This is a very fast and performant calculation but has the drawback that sometimes components can get detected as colliding, even if they aren't, just because their bounding boxes are colliding but not the 3D objects themselves. This is especially the case if 3D objects get rotated.
If the object has a BoundingGeometry
defined this geometry gets used and a more complex mesh intersection calculation is taking place which checks if the 3D objects are intersecting each other. This is an exact calculation that checks exactly the 3D meshes against each other, and so is a bit slower but far more precise. If only one of the objects has a BoundingGeometry
defined the BoundingBox
of the other object gets used for calculation. Be aware that if the component to be docked has a BoundingGeometry
defined, the more complex mesh intersection calculation will always take place at docking preview generation.
In the case of DockingLines and DockingLineRanges, the generated lines are clipped based on the projection of the bounding box of the colliding geometry onto the line. This means that the line is segmented and shortened depending on the collisions detected. If none of the remaining line segments is large enough to dock the component in its full size, the line is completely discarded.
Locking of parent dockings
With the property childDeletionLocked
it is possible to prevent deletion of child components on a specific parent docking. If this property is set to true it will not be possible to delete the child component docked at this docking. But if the parent component itself gets deleted, the docked child will also get deleted, even if the childDeletionLocked
property is set to true. childDeletionLocked
supports simple expression/condition scripts.
Siblings
Additionaly to assignments throu parent/child connections, components can transfer Data via Siblingpoints. Siblingpoints connect to any other siblingpoint with the same mask and same position somewhere within the object. Therefor its possible to transfer data (parametervalues) directly between two childcomponents on completly seperated branches in the parent-child-hierachy. Like Dokcings, Siblingpoints have onDock, onUpdate and onUndock assignments. Regarding the executionorder during the docking process the logic follows the same rules as with Dockingpoints: first the assignments from the currently existing Component, then the assignment from the newly docked one. First both onDock, then onUpdate. On undock the order is reversed, same as with the DockingPoints.
Docking assigments are always executed prior to sibling assignments.
Self Assignments
Normal assignments (either on docking or siblings) sets the value of a parameter on the other side of the connection. With self assignments one can set values on parameters of the component of the docking/sibling.
Self assignments are always executed after the "normal" assignment and never trigger recursive actions.
onUpdate of Connections
Each connection definition (dockingpoint, dockingline, siblingpoint) may have their own onUpdate
. Those are executed after the onUpdate of the component and the calculation of the position but before any other script of the connection is evaluated (condition, assignments). This onUpdate
may write values to the connections-context which is then available in the other scripts on this connection. This is usefull when the connection may decide what data from the whole component to use within this context.
Silent Assignments
Normal "On Update"-Assignments lead to a disabling of the parameter which is set from the assignment. This is done because normally a User shouldnt be able to change a Parameter whose value will be override with the next refresh. In some case (e.g. if the change of the value triggers an update of the connected Component which leads to changes in the parameters so that the changed value stays the same after the next refresh) this automatic disabling should be silenced. In this case one can use assignmentsOnUpdateSilent. Those assignments are handled exactly like onUpdate Assignments, but without disabling the parameter. Silent assignments are always applied before the normal assignments (if both exist).
AssignmentScripts
For more complex solutions its possible to define assignmentScripts. Again seperated into onDock, onUnDock and onUpdate, those scripts are executed after the "normal" assignments are done. Within the assignmentScript one has access to the values of both sides of the connection (parent and child in docking, both siblings for siblingpoints). Those are accessilbe via context definition. F.e. the paramter "width" of the other side of the connection is accessible via "other.width" while "self.width" is the own parameter width. In parentDockings the "other." context is also accessible via "child.", in childDockings its "parent." and for Siblings its "sibling."
Dock Ranges
Dockranges provide the ability to create a range of dockPoints without specifing each of them individually. A range is defined by a startingPoint, the stepSize and the endPoint. The step might be one 3D step which is used as a direct increment until the endPoint is reached, or as stepX, stepY and stepZ which creates a raster of points. The condition and assignments are defined for the range, but executed for each generated point seperatly. Within those scripts you can access the position of the point and index within the range via "connection.position" and "connection.index".
AddOn Spots
For a visual hint to the user, its possible to define addOnSpots. An AddOnSpot is a position in the 3D space relative to the current Component where a Plus-Sign is shown. If the User clicks on the sign, the AddOn-View opens.
AddOnSpots have a position and a condition. The mask is defined for future use and has nothing to do with docking masks.
Packaging Size
This feature allows defining a package size for its component. This size will be the amount of all appearances of this component. Description by example:
The possible "packageSizes" are set to [5,3], this means for example if the component is docked 11 times the number of packages with size 5 will be 2 and the number of packages with size 3 will be 1. The number of components will always be first divided into the biggest possible package size and then the next smaller one and next smaller one until the smallest one is reached.
The parameter packaging adds also the size 1 to the "packageSize" if the condition of "someOtherParameter == 1" is true.
The parameter "articleNr" and "pricing" are containing the variable "packageSize". Therefore it is possible to get the current "packageSize".
Dimensioning
The configurator automatically shows the dimensions of the bounding box, or of the boxForMeasurement if defined. Additional dimensioning levels can be defined as objects in the dimensionings array. Every dimensioning has a type, from, to, level and visibility field:
type defines where this dimensioning applies (x, y or z)
from and to defines the begining and the end of the dimensioning
level is the layer of the dimensioning. 0 is the outermost layer
visible can be any condition defining if this dimensioning should be shown.
Plan interaction
In order for configurations to interact with objects in the plan such as walls, it must be possible to define the part of the geometries that can be influenced. This information must be taken into account when placing a configuration in a plan.