Roomle Script Built-in Functions
This is an overview of native RoomleScript functions provided by the core. These functions can be used directly and provide functionalities that are not achievable through standard scripting.
The functions are grouped by their availability in different script contexts. Some functions are available everywhere, some only in specific scripts like onUpdate, connection, collision condition or geometry.
General Functions
These functions are universally available and you can utilize them in any script context.
Math
These are mathematical functions.
asin
asin(
a: float
) : floatArcus sine (arcsine)
Parameters:
a: value between -1 and 1
Returns: arcsine of a in radians.
Usage:
v = 0.5;
angleRad = asin(v); /* returns 523598776 */
angle = (angleRad / M_PI) * 180; /* 30 */acos
acos(
a: float
) : floatArcus cosine (arccosine)
Parameters:
a: float value between -1 and 1
Returns: arccosine of a in radians.
Usage:
v = 0.5;
angleRad = acos(v); /* returns 1.04719755 */
angle = (angleRad / M_PI) * 180; /* 60 */atan
atan(
a: float
) : floatArcus tangent.
Parameters:
a: value between -1 and 1
Returns: arctangent of a in radians.
atan2
atan2(
y: float,
x: float
) : floatArcus tangent defined by ratio of opposite and adjacent side of the triangle.
Parameters:
y: length of opposite sidex: length of adjacent side
Returns: arctangent of the angle in radians.
ceil
ceil(
number: float,
digits: float
) : floatNearest higher value
Parameters:
number: the number to be ceileddigits: count of decimal digits
Returns: Nearest higher value rounded to given amount of decimal spaces.
Usage:
x = 123.4567;
ceil(x, 0); /* returns 124 */
ceil(x, 2); /* returns 123.46 */cos
cos(
valueRad: float
) : floatCosine
Parameters:
valueRad: value in radians
Returns: cosine value of a.
cosh
cosh(
valueRad: float
) : floatHyperbolic cosine
Parameters:
valueRad: value in radians
Returns: hyperbolic cosine value of a.
exp
exp(
x: float
) : floatExponential function
Parameters:
x: the exponent
Returns: Value of e powered to x
fabs
fabs(
x: float
) : floatAbsolute value
Parameters:
x: value
Returns: x if x is positive or -x if x is negative.
Usage:
fabs(5); /* returns 5 */
fabs(-5); /* returns 5 */floor
floor(
number: float,
digits: float
) : floatNearest lower value
Parameters:
number: the number to be flooreddigits: count of decimal digits
Returns: Nearest lower value rounded to given amount of decimal spaces.
Usage:
x = 123.4567;
floor(x, 0); /* returns 123 */
floor(x, 2); /* returns 123.45 */fmod
fmod(
dividend: float,
divisor: float
) : floatFloating point modulo
Parameters:
dividend: floatdivisor: float
Returns: Modulo as float.
⚠️ Warning: Works well only with integers that can be represented by single precision floating point numbers (32 bits, up to around 7 digits).
Usage:
fmod(13, 4); /* returns 1 */
fmod(12, 4); /* returns 0 */
fmod(123456789, 1234567); /* will not work well */log
log(
value: float
) : floatNatural logarithm
Parameters:
value
Returns: Logarithm of the value with base of e (~2.718)
Usage:
log(100); /* returns ~4.605 */
log(M_E); /* returns 1 */
log(1); /* returns 0 */
log(0); /* returns -inf */log10
log10(
value: float
) : floatCommon logarithm
Parameters:
value
Returns: Logarithm of the value with base of 10
Usage:
log10(100); /* returns 2 */
log10(M_E); /* returns ~0.434 */
log10(1); /* returns 0 */
log10(0); /* returns -inf */pow
pow(
value: float,
exponent: float
) : floatPower function
Parameters:
value: the value to compute powerexponent
Returns: value powered to exponent.
round
round(
number: float,
digits: float
) : floatNearest rounded value
Parameters:
number: the number to be roundeddigits: count of decimal digits
Returns: Nearest value rounded to given amount of decimal spaces.
Usage:
x = 1.234567;
round(x, 0); /* returns 1 */
round(x, 1); /* returns 1.2 */
round(x, 2); /* returns 1.23 */
round(x, 3); /* returns 1.235 */
round(x, 4); /* returns 1.2346 */sin
sin(
valueRad: float
) : floatSine
Parameters:
valueRad: value in radians
Returns: sie value of a.
sinh
sinh(
valueRad: float
) : floatHyperbolic sine
Parameters:
valueRad: value in radians
Returns: hyperbolic sine value of a.
sqrt
sqrt(
number: float
) : floatSquare root
Parameters:number: zero or positive number
Returns: Square root of the number or nan
Usage:
sqrt(2); /* returns M_SQRT2 or ~1.414 */tan
tan(
valueRad: float
) : floatTangent
Parameters:
valueRad: value in radians
Returns: tangent value of a.
tanh
tanh(
valueRad: float
) : floatHyperbolic tangent
Parameters:
valueRad: value in radians
Returns: hyperbolic tangent value of a.
Data Type Conversions
Functions to convert between data types.
float
float(
value: any
) : floatConvert to float
Parameters:
valuethe value to try to convert to float
Returns: If value starts with number, returns the first parsed number, otherwise 0.
Usage:
float('5'); /* returns 5.0 */
float('5 hello 3432'); /* returns 5.0 */
float('5.3'); /* returns 5.3 */
float('5,3'); /* returns 5.0 */
float(' 5'); /* returns 5.0 */
float('_5'); /* returns 0.0 */
float([5]); /* returns 0.0 */
float([1]); /* returns 0.0 */
float(Vector3f{5,5,5}) /* returns 0.0 */string
string(
input: any,
*decimalSpaces: Integer = 2
) : StringtoString function - converts value to string.
Parameters:
inputvalue to stringifydecimalSpacesif input is an Integer or float, defines the amount of decimal spaces of the number to show; default is 2note: not appliable to array, Vector2f, Vector3f, String
Returns: Value converted to string.
Usage:
string('some string') /* returns 'some string' */
string('some string', 4) /* returns 'some string' */
string(M_PI) /* returns '3.14' */
string(M_PI, 0) /* returns '3' */
string(M_PI, 2) /* returns '3.14' */
string(M_PI, 5) /* returns '3.14159' */
string([1, 2]) /* returns '[1.00,2.00]' */
string([1, 2], 0) /* returns '[1.00,2.00]' */
string(Vector2f{1, 2}) /* returns '{1.00,2.00}' */
string(Vector2f{1, 2}, 0) /* returns '{1.00,2.00}' */
string('1.00', 0) /* returns '1.00' */
string('1', 5) /* returns '1' */stringToArray
stringToArray(
stringifiedArray: string
) : [float]Parses a string to array.
Parameters:
stringifiedArray: stirng in a[number, number, ...]pattern
Returns: The parsed array or null if failed.
Usage:
arr = stringToArray('[1,2,3]');
x = get(arr, 0); /* returns 1 */stringToVector2f
stringToVector2f(
stringifiedVector: string
) : Vector2fParses a string as Vector2f.
Parameters:
stringifiedVector: String in aVector2f{number, number}or{number, number}pattern
Throws:
[1301]Error getting value
Returns: The parsed vector or null if failed.
Usage:
Vector parameter
{
"key": "size",
"type": "String",
"valueObjects": [
{
"value": "{100,200}",
"labels": {
"en": "10 x 20"
}
},
{
"value": "Vector3f{1000,200}",
"labels": {
"en": "100 x 20"
}
}
]
}_size = stringToVector2f(size);
AddCube(Vector3f{xFromVector(_size), yFromVector(_size), 500});stringToVector3f
stringToVector3f(
stringifiedVector: string
) : Vector3fParses a string as Vector3f.
Parameters:
stringifiedVector: String in aVector3f{number, number, number}or{number, number, number}pattern
Throws:
[1301]Error getting value
Returns: The parsed vector or null if failed.
Usage:
Vector parameter
{
"key": "size",
"type": "String",
"valueObjects": [
{
"value": "{100,200,300}",
"labels": {
"en": "10 x 20 x 30"
}
},
{
"value": "Vector3f{1000,200,300}",
"labels": {
"en": "100 x 20 x 30"
}
}
]
}_size = stringToVector3f(size);
AddCube(Vector3f{xFromVector(_size), yFromVector(_size), zFromVector(_size)});Array Operators
Functions that operate on arrays, like accessing and setting values, searching, inserting etc.
get
get(
array: [float],
index: Integer
) : floatReads an array element at a given index.
To write an array element, refer to set.
Parameters:
array: the array you want to accessindex: index of the element in the array, index of the first element is zero0⚠️ float indices will floor to the next lower integer
Returns: The number from the array at the given index or 0 if fails.
Throws:
[1404]Index out of bounds. Returns 0 in this case, execution continues
Usage:
arr = [10, 20, 30, 40];
get(arr, 2); /* returns 30 */
get(arr, 2.9); /* returns 20 */
get(arr, 2.999999); /* returns 20 */
get(
arr,
2.9999999
); /* returns 30 (floating point precision flips to index 3) */
get(arr, 5); /* returns 0, throws 1404 */
get(arr, -1); /* returns 0, throws 1404 */inArray
inArray(
valueToCheck: any,
value1: any,
value2: any,
...
) : booleanUseful for checking if a list of values contains a specific value.
Arguments
searchedValue: the value that is being searched for in the listarray: the array to check
Returns
trueif valueToCheck is equal to at least one of the other values, otherwisefalse
Usage:
inArray(1, [1, 2, 3, 1]); /* returns 1 */
inArray(10, [1, 2, 3, 1]); /* returns 0 */indexOf
indexOf(
searchedValue: float,
array: [float]
) : IntegerFind index of a value in an array.
Parameters:
searchedValue: the value that is being looked forarray: the array to search
Returns: Index of the first occurence of the value in the array or -1 if no occurence.
Usage:
indexOf(1, [1, 2, 3, 1]); /* returns 0 */
indexOf(10, [1, 2, 3, 1]); /* returns -1 */insert
insert(
array: [float],
index: Integer,
value: float | [float]
) : voidInsert into array in front of the element at given index
Parameters:
array: array into which the values are insertedindex: index of the element before which the values will insertvalue: value to be inserted, can be a number or an array of numbers
Throws:
[1404]index out of bounds
Usage:
arr = [10, 20];
insert(arr, 1, 15); /* arr is [10, 15, 20] */
insert(arr, 0, [0, 5]); /* arr is [0, 5, 10, 15, 20] */
insert(arr, 5, 25); /* arr stays [0, 5, 10, 15, 20], throws [1404] */
insert(arr, -1, 5); /* arr stays [0, 5, 10, 15, 20], throws [1404] */intersection
intersection(
a: [float],
b: [float]
) : [float]Intersection of arrays
Parameters:
a,b: two arrays of numbers
Returns: Array with elements that are present in both arrays.
Usage:
intersection([3, 2, 1], [2, 3, 4, 5]); /* returns [2, 3] */
intersection([3, 2, 1], [5, 4, 3, 2]); /* returns [3, 2] */
intersection([1, 2, 3], [4, 5, 6]); /* returns [] */
intersection([1], [1, 1, 1]); /* returns [1, 1, 1] */
intersection([1, 1, 1], [1]); /* returns [1, 1, 1] */length
length(
array: [float]
) : IntegerLength of array (for the length of a String, refer to size).
Parameters: * array: array of floats
Returns: count of the array elements.
Usage:
a = [];
b = [0, 1, 2];
c = [0];
length(a); /* returns 0 */
length(b); /* returns 3 */
length(c); /* returns 1 */popBack
popBack(
array: [float]
) : floatReturns and removes last number from array.
Parameters:
array
Returns: Last number of array, original array has this value removed or 0 if [1405] is thrown.
Throws:
[1405]: popBack empty array
Usage:
arr = [10, 20];
x1 = popBack(arr); /* returns 20, arr is [10] */
x2 = popBack(arr); /* returns 10, arr is [] */
x3 = popBack(arr); /* returns 0, arr is [], throws [1405] */pushBack
pushBack(
array: [float],
value: float
) : voidPushes a value at the end of an array.
Parameters:
array: the array to which to pushvalue: the value to push
Usage:
arr = [];
for (_.i = 0; _.i < 5; _.i = _.i + 1) {
pushBack(arr, 0);
}
/* arr is [0, 0, 0, 0, 0] */removeAt
removeAt(
array: [float],
index: Integer
) : floatRemove element at index from an array and return the next.
Parameters:
array: the array from which the element should be removedindex: index at which to remove the element, first index is 0
Returns: Next element after the one that has been removed or 0 if the element is the last one or if [1404] has been thrown.
Throws:
[1404]: Index out of bounds
Usage:
arr = [10, 20, 30, 40, 50];
x1 = removeAt(arr, 2); /* returns 40, arr is [10, 20, 40, 50] */
x2 = removeAt(arr, 3); /* returns 0, arr is [10, 20, 40] */
x3 = removeAt(arr, 3); /* returns 0 and throws 1404, arr stays as it is */
x3 = removeAt(arr, -1); /* returns 0 and throws 1404, arr stays as it is */set
set(
array: [float],
index: Integer,
value: float
) : voidSets value of an array element at a given index.
Parameters:
array: the array you want to setindex: index of the element in the array, index of the first element is zero0⚠️ float indices will floor to the next lower integer
value: the new value that will replace the old value
Throws:
[1404]Index out of bounds.
Usage:
arr = [1, 2, 3];
set(arr, 0, 5); /* [5, 2, 3] */
set(arr, 1, get(arr, 2)); /* [5, 3, 3] */
set(arr, 2, get(arr, 2) + 1); /* [5, 3, 4] */String Operators
Functions that operate on strings, like checking for patterns, getting length, splitting etc.
like
like(
input: String,
pattern: String
) : BooleanReturns true if input matches the pattern. The pattern is a String with placeholders for one any single character or any subString.
This is the OPTION_LIKE operator from the IDM 3.1 standard, which itself is designed to be similar on the SQL's LIKE operator.
Parameters:
input: the String to check against the patternpattern: a case sensitive String pattern, where_is a wildcard for any single character and%is a wildcard representing any subString at least 1 character longa_- length 2, starts withaa%- any String starting witha_a- length 2, ends witha%a- any String that ends with a%a%- any String that containsa
Returns: true if String matches to the pattern, otherwise false
Usage:
like('Hello beautiful world', 'Hello')
/* false; no wildcard, pattern means equls to 'Hello' */
like('Hello beautiful world', 'Hello%')
/* true; pattern means starts with 'Hello' */
like('Hello beautiful world', '%beatiful%')
/* true; pattern means contains 'beatiful' */
like('Hello beautiful world', '%Hello%')
/* false; pattern means contains 'Hello' which is preceded and followed by other characters */
like('Hello beautiful world', 'Hello%world')
/* true; pattern means starts with 'Hello' and ends with 'world' */
like('Hello beautiful world', 'h%';
/* false; pattern means starts with 'h' */size
size(
input: String
) : IntegerLength of String.
Parameters: * input: String
Returns: count of the String's characters.
Usage:
a = 'Hello';
b = '';
size(a); /* returns 5 */
size(b); /* returns 0 */stringPart
stringPart(
input: String,
delimiter: String,
index: Integer,
*fallback: String = ''
) : StringSplits a string with a delimiter and returns the part under the given index.
Parameters:
input: the string intended to be parseddelimiter: a string that will be used to separate the input stringindex: index of the part that willfallback: optional value to return if fails, empty string''by default
Returns: part of the string or a fallback value (defined or '') if fails.
Usage:
_.id = 'abcd:efgh';
_.catalogueId = stringPart(id, ':', 0); /* returns 'abcd' */
_.externalId = stringPart(id, ':', 1); /* returns 'efgh' */
_.empty = stringPart(id, ':', 2); /* returns '' */
_.fallback = stringPart(id, ':', 2, 'NULL'); /* returns 'NULL' */stringSplit
stringSplit(
input: String,
delimiter: String
) : [String]Splits a string with a delimiter and returns the parts as an array.
Parameters:
input: the string intended to be parseddelimiter: a string that will be used to separate the input string
Returns: Array of string parts or an empty array if input is an empty string.
Usage:
_.id = 'abcd:efgh';
_.idParts = stringSplit(id, ':'); /* returns ['abcd', 'ergh'] */
_.catalogueId = get(iidPartsd, 0); /* returns 'abcd' */
_.externalId = get(idParts, 1); /* returns 'efgh' */substring
substring(
input: String,
startIndex: Integer,
length: Integer
) : StringReturns part of string based on position and length.
Parameters:
input: the string from which the substring is to be extracedstartIndex: index where the substring starts, first index is 0length: length of the substring
Returns: Part of string starting at the given index of the given length. Empty string is returned for every character that is outside of the string, rather than throwing an exception.
Usage:
substring('my string', 3, 6); /* returns 'string' */
substring('my string', 3, 0); /* returns '' */
substring('my string', -3, 6); /* returns '' */
substring('my string', -3, 6); /* returns '' */
substring('my string', 0, 100); /* returns 'my string' */
substring('my string', 10, 100); /* returns '' */Component Data Functions
Component definitions can provide static non-changeable data in the JSON format. These functions allow to access and query this data and even evaluate them as expressions. There are several versions of these functions. Functions starting with get return the data as is, evaluate functions evaluate the data as RoomleScript expressions and find functions return arrays of data that match a certain criteria. In the basic form, these functions query the data of the current component definition. There are variants for accessing the data of a subComponent. If data is not found, there are variants of the functions that differ in the way they handle this case. Functions with OrNull suffix return null if data is not found, functions with WithDefault suffix return a default fallback value passed as an argument. Without any suffix, the functions return null and display an error message in the console.
These 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.
getData
getData(
...key : String | Integer
) : any | null Retrieves data from the data storage JSON object in the component.data.
⚠️ This does not handle non-existing path and scripter needs to ensure that the requested path exists.
Attributes:
key: path parts as String keys or Integer array indices; path segments are separate arguments, e.g.getData('a', 'b', 0, 'c')to accessdata.a.b[0].c
Returns: The retrieved data or null if data wasn't found, accompanied by an error message in the console.
Throws:
[1308]Data not found
Usage:
define the
datain the component definition
{
"id": "test:data",
"data": {
"size": 300,
"colors": [
"isdt:red",
"isdt:green"
],
"elementTypes": {
"smallbox": {
"label": "Small Box"
},
"bigsphere": {
"label": "Big Sphere"
}
}
}
}retrieve them using the
getDatafunction
/* returns 300 */
width = getData('size');
/* returns 'isdt:green' */
color = getData('colors', 1);
/* returns the 'Small Box' or 'Big Sphere' based on the current value of elementType variable */
label = getData('elementTypes', elementType, 'label');getDataOrNull
getDataOrNull(
...key : String | Integer
) : any | null Retrieves data from the data storage JSON object in the component.data or null if data wasn't found without emitting any error message.
Attributes:
key: path parts as String keys or Integer array indices; path segments are separate arguments, e.g.getData('a', 'b', 0, 'c')to accessdata.a.b[0].c
Returns: The retrieved data or null.
Usage:
define the
datain the component definition
{
"id": "test:data",
"data": {
"size": 300,
"colors": [
"isdt:red",
"isdt:green"
],
"elementTypes": {
"smallbox": {
"label": "Small Box",
"hasChildDock": true
},
"bigsphere": {
"label": "Big Sphere",
"hasParentDock": true
}
}
}
}retrieve them using the
getDataOrNullfunction in theconditionscript of aparentDocking
_.hasParentDock = getDataOrNull('elementTypes', elementType, 'hasParentDock');
if (isnull(_.hasParentDock) || _.hasParentDock == false) {
/* kill this docking if the element type has no docking possibility in the first step */
return false;
}
/* conitnue with the condition evaluation */getDataWithDefault
getDataWithDefault(
...key : String | Integer,
defaultValue: any
) : anyRetrieves data from the data storage JSON object in the component.data and returns a fallback value if entry hasn't been found.
Attributes:
key: path parts as String keys or Integer array indices; path segments are separate arguments, e.g.getData('a', 'b', 0, 'c')to accessdata.a.b[0].cdefaultValue: value to return if target path doesn't exist
Returns: The retrieved data or fallback.
Usage:
define the
datain the component definition
{
"id": "test:data",
"parameters": [
{
"key": "elementType",
"validValues": [
"armchair",
"inline"
]
}
],
"data": {
"translations": {
"armchair": {
"en": "Armchair",
"de": "Sessel",
"fr": "Fauteuil"
},
...
}
}
}retrieve them using the
getDataWithDefaultfunction in alabelscript:
return getDataWithDefault(
'translations',
elementType,
language,
getData('translations', elementType, 'en')
);Note: language hold the ISO code of the current language. It can be es for example, in which case the translation entry doesn't exist. Because elementType has a list of validValues, the developer can make sure that the getData will always return a value.
getSubComponentData
getSubComponentData(
subComponentInternalId : String
...key : String | Integer
) : any | nullRetrieves a component.data from another component, that is being linked as a subComponent of this component. Works exactly same as the getData counterpart, just in a different component.
Attributes:
subComponentInternalId: internalId of a subComponent definitionkey: path parts as String keys or Integer array indices; path segments are separate arguments, e.g.getData('a', 'b', 0, 'c')to accessdata.a.b[0].c
Returns: The retrieved data or null.
Throws:
[1308]Data not found
Usage:
Data subComponent:
{
"id": "mycatalog:component_with_data",
"data": {
"elementTypes": {
"chair": {
"articleCode": "MCH-75"
},
},
"materialArticleCodes": {
"fabric_pg1_red": "10.1-1001",
"fabric_pg1_blue": "10.1-1002",
"leather_pg6_palebrown": "20.6-1001"
}
}
}Main component:
"subComponents": [
{
"internalId": "DATACOMPONENT",
"componentId": "mycatalog:component_with_data",
"active": false,
"numberInPartList": 0
}
]Retrieve the data:
productCode = getSubComponentData(
'DATACOMPONENT', // internalId of the subComponent
'elementTypes',
'chair',
'articleCode'
);
materialCode = getSubComponentDataWithDefault(
'DATACOMPONENT',
'materialArticleCodes',
stringPart(material, ':', 1),
'UNDEFINED'
);
articleNr = productCode | ' ' | materialCode;getSubComponentDataOrNull
getSubComponentDataOrNull(
subComponentInternalId : String,
...key : String | Integer
) : any | nullOrNull counterpart of getSubComponentData. See getDataOrNull and getSubComponentData.
getSubComponentDataWithDefault
getSubComponentDataWithDefault(
subComponentInternalId : String,
...key : String | Integer
defaultValue: any
) : any | nullSame as getSubComponentDataWithDefault, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getSubComponentDataWithDefault.
evaluateData
evaluateData(
...key : String | Integer
) : any | nullSame as getData, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getData.
evaluateDataOrNull
evaluateDataOrNull(
...key : String | Integer
) : any | nullSame as getDataOrNull, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getDataOrNull.
evaluateDataWithDefault
evaluateDataWithDefault(
...key : String | Integer,
defaultValue: any
) : anySame as getDataWithDefault, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getDataWithDefault.
evaluateSubComponentData
evaluateSubComponentData(
subComponentInternalId : String,
...key : String | Integer
) : any | nullSame as getSubComponentData, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getSubComponentData.
evaluateSubComponentDataOrNull
evaluateSubComponentDataOrNull(
subComponentInternalId : String,
...key : String | Integer
) : any | nullSame as getSubComponentDataOrNull, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getSubComponentDataOrNull.
evaluateSubComponentDataWithDefault
evaluateSubComponentDataWithDefault(
subComponentInternalId : String,
...key : String | Integer,
defaultValue: any
) : anySame as getSubComponentDataWithDefault, but considers the value an expression and attempts to evaluate it. See evaluateData functions and getSubComponentDataWithDefault.
findData
findData(
...key : String | Integer,
filterFunction: string,
) : [{key: String | Integer, value: any}]Parameters:
key: path parts as String keys or Integer array indices; path segments are separate arguments, e.g.findData('a', 'b', 0, 'c', 'myFilterFunction')to accessdata.a.b[0].c; this is the path to an object or an array of objects, which will be filteredfilterFunction: name of the criteria function as a string; this function is called for each key-value pair in the target object or for each element in the target array
The filter function has following header filterFunction(key: String | Integer, value: any) : boolean and has to be available at the time of the findData call. The filterFunction is accessed by its name as a string argument. It can be either a local function or a component function.
The findData functions are useful for finding data based on a criteria function. The result of this function is an array of retrieved data objects that match the criteria. The criteria function is a function available in the same context where the findData function is called. It has two arguments (one for the key, the other for the value) and returns a boolean value indicating whether the key-value pair matches the criteria. This function is called by its name as a string argument. The Roomle Component Tool provides a code snippet to help you retrieve the data, giving you a template for the find function, criteria function, and the code comes nested in a wrapper function. See the example below for more details and good practice recommendations.
The findData function is somewhat similar to the filter function in JavaScript (returns an array of matching objects), but it is specifically designed to work with the Roomle Component Tool's data structure. To have an actual find counterpart, you can retrieve the first element of the array returned by findData and return it as a value, as in the following example.
The findData function returns an array of objects that meet the criteria function. If there is no match, the array is empty (length is 0). The return value of the function has the following structure:
[
{
key: String | Integer,
value: Object | String | Integer | Float | Boolean
},
...
]Example usage:
Let's say we have the following data and a length parameter, based on which we want to retrieve the data entry:
{
"data": {
"beamConstruction": [
{ "minLength": 0, "maxLength": 1000, "screwsCount": 2, "material": "isdt:red" },
{ "minLength": 1000, "maxLength": 1600, "screwsCount": 3, "material": "isdt:green" },
{ "minLength": 1600, "maxLength": 2000, "screwsCount": 4, "material": "isdt:blue" }
]
}
}It is recommended to encapsulate the findData call in a helper function in order to keep the code clean. Example for a recommended pattern for the findData function usage:
// Use a wrapper function to encapsulate the logic. Use a _ or __ prefix to avoid variable shadowing.
function find_beamConstruction(__length) {
// The criteria function, where the key is either the index of the data in the array or the key of the object in the data object.
function find_beamConstruction_filter(key, value) {
// in this example:
// key is 0, 1, 2
// value is the object at that index: {minLength, maxLength, screwsCount, material}
return __length > value.minLength && __length <= value.maxLength;
}
// Call the findData function, where we define the path of the data in the same way as in the getData function.
// The last argument is the stringified name of the criteria function.
_.beamConstruction_raw = findData('beamConstruction', 'find_beamConstruction_filter'); // returns an array of objects that match the criteria
/**
* _.beamConstruction_raw is:
* [
* {
* key: 0, 1 or 2,
* value: { "minLength": ..., "maxLength": ..., "screwsCount": ..., "material": ... }
* }
* ]
*/
if (length(_.beamConstruction_raw) > 0) { // if the search result is not empty, the length is greater than 0
_.beamConstruction_raw_0 = get(_.beamConstruction_raw, 0);
// Extract the first element of the array and return it.
_.found = _.beamConstruction_raw_0.value;
return _.found;
}
}
// either null or the first matching object
beamConstruction = find_beamConstruction(length);
// ---- use the found data ----
AddCube({self.length, 20, 50});
SetObjSurface(self.beamConstruction.material);Hint: You can use the
findDatacode snippet provided by the Roomle Component Tool. It generates a wrapper function, a criteria function, and thefindDatacall. You just need to fill in the criteria logic and the data path.
Filter the data at the path by a criteria function. This is a getData counterpart.
findAndEvaluateData
findAndEvaluateData(
...key : String | Integer,
filterFunction: string
) : [{key: String | Integer, value: any}]Filter the data at the path by a criteria function and evaluate them. Works like findData, but string scripts are considered to be script expressions and the result contains their resulting values. The difference is like between getData and evaluateData counterpart.
findSubComponentData
findSubComponentData(
subComponentInternalId : String,
...key : String | Integer,
filterFunction: string
) : [{key: String | Integer, value: any}]Filter the data at the path in a subComponent by a criteria function. See the findData and getSubComponentData counterpart.
findAndEvaluateSubComponentData
findAndEvaluateSubComponentData(
subComponentInternalId : String,
...key : String | Integer,
filterFunction: string
) : [{key: String | Integer, value: any}]Filter the data at the path in a subComponent by a criteria function and evaluate them. This is an findData and evaluateSubComponentData counterpart.
findDataKey
findDataKey(
...key : String | Integer,
filterFunction: string
) : [string]Returns: Array of keys of the data objects that match the criteria.
Similarly to the findData family of functions, which return the objects themselves, the findDataKey functions return an array of keys of the data objects that match the criteria. The keys are either numerical indices for the cases where an array is searched, or the keys of the object in the data object. This is useful in cases where the data contains a mix of data that you would retrieve with the getData, but also a few entries that you would like to evaluate, as in the following example:
{
"data": {
"beamConstruction": {
"short": {
"minLength": 0,
"maxLength": 1000,
"screws": 2,
"material": "isdt:red",
"articleNr": "'R' | string(beamLength, 0) | 'S2'"
},
"medium": {
"minLength": 1000,
"maxLength": 1600,
"screws": 3,
"material": "isdt:green",
"articleNr": "'G' | string(beamLength, 0) | 'S3'"
},
"long": {
"minLength": 1600,
"maxLength": 2000,
"screws": 4,
"material": "isdt:blue",
"articleNr": "'B' | string(beamLength, 0) | 'S4'"
}
}
}
}function getBeamConstructionIndex(__length) {
function find_beamConstruction_filter(key, value) {
return __length > value.minLength && __length <= value.maxLength;
}
_.beamConstructionIndices = findDataKey('beamConstruction', 'find_beamConstruction_filter'); // based on the criteria ['short' or 'medium' or 'long']
if (length(_.beamConstructionIndices) > 0) {
return get(_.beamConstructionIndices, 0);
}
}
beamConstructionIndex = getBeamConstructionIndex(length); // either 'short', 'medium' or 'long', or NULL_VALUE
articleNr = evaluateData('beamConstruction', beamConstructionIndex, 'articleNr' );findSubComponentDataKey
findDataKey(
subComponentInternalId : String,
...key : String | Integer,
filterFunction: string
) : [string]Counterpart of findDataKey for searching in subComponents.
Miscellaneous Functions
Functions that do not fit in the categories above.
activeGroupInView
activeGroupInView() : StringQueries the configurator UI to get the currently selected parameter group. This is useful for manipulating geometry based on what the user is configuring.
⚠️ Warning: This function can query the open group into a variable which can be used in the whole component. This is dangeours and can cause serious errors, because it is possible to change configuration based on the user interaction. The values retrieved by this function should only be used in the
geometryscript to change the view to hide walls, open doors etc. or to remove certain docking previews in theparentDockingconditionif used together with theconnection.isPreviewgetter. It is especially important to note, that this function IS NOT intended to project its value into the article number, label, pricing or docking points coordinates.
Returns: key property of the current parameter group
Usage:
geometry:
_.displayOpenDoor = activeGroupInView() === 'grpInternalEquipment';
AddCube(Vectorf3{doowWidth, doorThickness, doorHeight});
if (_.displayOpenDoor) {
/* rotate the door to visualize it is open */
RotateMatrixBy(Vector3f{0, 0, 1}, Vector3f{0, 0, 0}, 105);
}parent docking condition:
if (connection.isPreview) {
_.showPreviewOnOuterWall = activeGroupInView() !== 'grpInternalEquipment');
if (!_.showPreviewOnOuterWall) {
return false;
}
}getAbsolutePosition
getAbsolutePosition() : StringOnly in collisionCondition: (componentRuntimeId: int) : Vector3f
Returns the position of the current component in the coordinate system of the root component. This is the absolute position of the component withing the configuration, because the root component is always placed at the zero.
Inside of the collisionCondition script it is possible to optionally pass a componentId to the function to retrieve the absolute position of another component in the configuration.
⚠️ Warning: This function does not consider rotation of the docking points. It always returns the position of the component origin, regardless its rotation.
getComponentProperty
getComponentProperty(
key: 'runtimeId' | 'externalId' | 'catalogId',
*componentId: integer
) : integer | stringReturns the unique runtime id, or component Id of the current component. If this function is used in a collisionCondition script, such a property of another colliding component can be retrieved.
Note: parts of an ID are catalogId:externalId
Parameters:
keyeitherruntimeId,externalIdorcatalogIdstring valuescomponentIda runtime ID of a different component, only availabe in thecollisionCondition
Returns:
unique runtime ID as an integer
external or catalog ID as a string
Usage:
id = getComponentProperty('runtimeId'); // equivalent to getUniqueRuntimeId()
componentId =
getComponentProperty('catalogId') | ':' | getComponentProperty('externalId'); // get current component combinedId"collisionCondition": "
for (i = 0; i < length(collidingComponentIDs); i++) {
collidingComponentId = get(collidingComponentIDs, i);
// avoid collision with the catalog:shelf component
if (getComponentProperty('externalId', collidingComponentId) == 'shelf') {
return false;
}
}
return true;
"getDockPosition
getDockPosition() : Vector3fGet position of child docking point in the coordinate system of the parent.
Returns: Vector from parent origin to child docking point or zero Vector3f if component is the root component.
See getPosition for more details.
getDockPositionRelativeToParentDock
getDockPositionRelativeToParentDock() : Vector3fGet position of the child docking point in the coordinate system of the parent relative to the parent docking point.
Returns:
point - point: ideally zero Vector3f or the offset if configuration doesn't reload properly
range - point: ideally zero Vector3f or the offset if configuration doesn't reload properly
line - point: Vector from the beginning of the dockLine to the child docking point
root: zero Vector3f
getEnvironmentProperty
getEnvironmentProperty(
key: 'country' | 'currency' | 'language' | 'unit' | 'unitString' | 'level'
) : String | int | nullGets the environment property of the current configurator session. These properties can be set in the url arguments or behind the configuratorId in the Tenant Settings.
Returns:
country-> the ISO 3166-1 alpha-2 country code, e.g. 'us', 'de'currency-> the ISO 4217 currency code, e.g. 'USD', 'EUR'language-> the ISO 639-1 language code, e.g. 'en', 'de'unit->mm,cm,inch,inchfeetlevel-> the current value/parameterrestrictionLevel
getObjectProperty
getObjectProperty(
key: 'wallthickness' | 'configurationLoaded',
*defaultValue: boolean | int | float | string
) : boolean | int | float | stringReturns the value for the given property-key from the plan object.
wallthickness: Returns the thickness of the wall to which the plan object is attached if the object is used as a construction element. Otherwise, the default value or, if not present, 0 is returned.
configurationLoaded: Returns if the initial loading process of the configuration is completed.
getMaterialProperty
getMaterialProperty(
materialId: String,
propertyName: String,
fallback: String
) : StringRetrieves additional material data defined in material properties. See Using GetMaterialPropery Function for detailed description.
Parameters:
materialId: Id of the target materialpropertyName: name of the property on the given materialfallback: Value to return if material or property are missing
Returns: the value stored in the material property or fallback if no material is found or if the material doesn't have the property.
Usage:
exmaple material entry:
{
"externalIdentifier": "fabric_blue",
"id": "isdt:fabric_blue",
"properties": {
"pricegroup": "30"
},
...
}getMaterialProperty(
'isdt:fabric_blue',
'pricegroup',
'NULL'
); /* returns '30' */
getMaterialProperty('isdt:fabric_blue', 'type', 'NULL'); /* returns 'NULL' */
getMaterialProperty('doesnt:exist', 'something', 'NULL'); /* returns 'NULL' */getPosition
getPosition() : Vector3fOnly in collisionCondition: (componentRuntimeId: int) : Vector3f
Get position of the child component in the coordinate system of the parent.
Returns: Vector3f leading from parent component origin to child component origin or zero Vector if component is the root component.
Usage:
position = getPosition();
parentOrigin = Vector3f{
- xFromVector(position),
- yFromVector(position),
- zFromVector(position)
};
getListOfPolygonsFromSvg
getListOfPolygonsFromSvg(
svgData: String,
*curvePointDensity: (int >= 2) = 8
) : Array<Vector2f>An alternative way to get a list of 2D points from an SVG to getPointlistFromSvg is the getListOfPolygonsFromSvg function. This function returns a list of polygons, where each polygon is a list of points. The output of this function can be directly uesed with the AddPrism function to create a 3D geometry from an SVG input, including holes.
{
"id": "documentaiton:svg_prism_with_holes",
"geometry": "
_.svgData = '<svg width=\"600\" height=\"600\"><path d=\"M0 50 A50 50 0 0 0 50 0 H500 V600 H0 Z M200 200 A50 50 0 1 0 201 201 Z M400 400 A50 50 0 1 0 401 401 Z\" /></svg>';
_.polygons = getListOfPolygonsFromSvg(_.svgData);
AddPrism(100, _.polygons, bevelWidth = 0);
SetObjSurface('egger:h3332_st10');
RotateMatrixBy({1,0,0},{0,0,0},-90);
"
}
Example - Prism from SVG with holes
getPointlistFromSvg
getPointlistFromSvg(
svgData: String,
*index: int = 0,
*curvePointDensity: (int >= 2) = 8
) : Array<Vector2f>Converts SVG path data to a list of 2D points. This can be further used to pass to the AddPrism function to create an three dimensional object from an 2D SVG input.
This function supports all the basic functionality of SVGs but is limited to the geometrical shape related properties. It can create a pointlist (contour) from the SVG, but does not read any color values (color, gradient, etc.) or any advanced functiality (animations, etc.).
It is also possible to read multiple shapes defined in a single SVG file. It is necessary to pass the index of the desired shape. If not, the first shape is always returned by default.
It is also possible to define the pointlist resolution for curves, called "curve point density". If a shape consist of a straight line, only the start and end points get added to the list. If the shape is a curve it adds the amount of points defined by the value on that curve depending on the curve-point-density parameter, including the start and end points. Therefore, the minimum value is 2. If none is provided it defaults to 8, which was chosen to be a good value for use cases in RoomleScript.
The following table shows the outcomes when using different values for the curve point density parameter.




The provided SVG data has to be a string and can not be loaded directly from a file. It is necessary to paste the SVG file contents into a component definition, preferably into the data structure.
The function is memoized, so if you call it multiple times with the same SVG data and curve point density, the pointlist is only calculated once and cached for later calls. This makes it possible to call this function multiple times with different indices without a performance impact.
{
"id": "catalog:component",
"geometry": "
_.svgData = '<svg width=\"600\" height=\"600\">
<rect fill=\"#3dc1d3\" x=\"0\" y=\"0\" width=\"100\" height=\"100\"/>
<rect fill=\"#3dc1d3\" x=\"100\" y=\"100\" width=\"200\" height=\"200\"/>
<rect fill=\"#3dc1d3\" x=\"300\" y=\"300\" width=\"300\" height=\"300\"/>
</svg>';
AddPrism(100, getPointlistFromSvg(_.svgData, 0), bevelWidth = 0);
SetObjSurface('isdt:yellow');
AddPrism(100, getPointlistFromSvg(_.svgData, 1), bevelWidth = 0);
SetObjSurface('isdt:red');
AddPrism(100, getPointlistFromSvg(_.svgData, 2), bevelWidth = 0);
SetObjSurface('isdt:blue');
"
}The outcome of this example looks like this:

Notice how the offset definition in the SVG content also affects the position of the geometry in the 3D scene.
getUniqueRuntimeId
getUniqueRuntimeId() : IntegerReturns unique runtime ID that has been assigned to this component instance in the configurator. Every root component, child component and subComponent will have an unique number. This number is not reused after for example deleting components. It is not persistent between configuration instances. Can be used to determine the timing order in which the components have been added to the configuration.
It is useful as a decision factor between two components connected via sibling points in cases that no other way to choose one component from more.
This number is not persistent between configurator instances (i.e. after configuration reload or between undo/redo actions) and in most cases, storing it as a parameter makes no sense and can lead to errors.
Example: See the Quadpost Shelf System template
Returns: Integer representing the unique runtime ID of the component in the configuration.
Usage:
/* in onUpdate */
if (isnull(uid)) {
/* enter only in the first onUpdate call */
uid = getUniqueRuntimeId(); /* could be for example 7 */
}
/* in a siblingPoint.assignmentScripts.onUpdate script to determine owner of the shared wall */
// the higher one wins
if (self.height > other.height) {
self.hasSharedWall = true;
} else if (self.height < other.height) {
self.hasSharedWall = false;
// both are same height, let the older one win
} else {
self.hasSharedWall = self.uid > other.uid;
}ifnull
ifnull(
variable: any,
fallback: any
) : anyChecks if a variable is undefined or null and returns the variable or fallback. Useful for making sure a variable is defined.
Parameters:
variable: the variable to check for nullfallback: a value to return if varialbe is null or undefined
Returns:
either the
variableor thefallbackifvariableis null
Usage:
/* checks if variable 'initialized' is null and if yes, returns true in order to enter the block */
if (ifnull(initialized, true)) {
/* make sure to initialize in order to enter only once */
initialized = true;
}in
in(
valueToCheck: any,
value1: any, value2: any, ...
) : booleanUseful for checking if a list of values containes a specific value.
Parameters:
valueToCheck: the value that is being searched for in the listvalueN: any number of arguments that will form the list
Returns
trueif valueToCheck is equal to at least one of the other values, otherwisefalse
Usage:
fruit = 'banana';
isFruit = in(fruit, 'apple', 'banana', 'cherry'); /* true */
pearIsValid = in('pear', 'apple', 'banana', 'cherry'); /* false */Most used to compare a variable to a list of constants, however you can also check a constant to a list of variables.
/* check if at least one of variables is true */
isGroceryItem = in(true, isFruit, isVegetable, isDairy);
/* which is actually equivalent to */
isGroceryItem = (isFruit + isVegetable + isDairy) > 0;isEnabled
isEnabled(
parameterKey: String
) : BooleanReturns if a parameter is enabled.
Parameters:
parameterKey: key of the parameter
Returns: True if the parameter exists and its enabled flag is true, false otherwise.
Usage:
if (isVisible(depth)) {
actualDepth = depth;
} else {
/* do not take the depth parameter value but a fallback */
actualDepth = 700;
}isnull
isnull(
value: any
) : BooleanChecks for null values.
Parameters:
value: identifier to be checked
Returns: True if identifier is undeclared, null or after setnull call.
Usage:
initialize on component load, at the beginning of onUpdate
if (isnull(initialized)) {
initialized = true;
/* initialize values here */
}in a connection script of a docking range:
/* compute indeces of the docking point */
if (isnull(connection.i)) { connection.i = xFromVector(connection.position) / > offset; }
if (isnull(connection.j)) { connection.j = yFromVector(connection.position) / > offset; }isVisible
isVisible(
parameterKey: String
) : BooleanReturns if a parameter is visible.
Parameters:
parameterKey: the parameter key to get the visible flag value from
Returns: True if the parameter exists and its enabled flag is true, false otherwise.
Usage:
if (isVisible(depth)) {
actualDepth = depth;
} else {
/* do not take the depth parameter value but a fallback */
actualDepth = 700;
}setnull
setnull(
variable: any
) : voidUndeclares a variable of given name and sets it to null.
Usage:
setnull(x);
if (isnull(x)) { /* true */
...
}xFromVector
xFromVector(
v: Vector2f | Vector3f
) : floatGet X component of a Vector
Parameters:
vthe vector
Returns: x component of the Vector or 0 if fails
Usage:
v2 = Vector2f{10, 20};
v3 = Vector3f{100, 200, 300};
x2 = xFromVector(v2); /* returns 10 */
x3 = xFromVector(v3); /* returns 100 */yFromVector
yFromVector(
v: Vector2f | Vector3f
) : float(v : Vector2f | Vector3f) : float
Get Y component of a Vector
Parameters:
vthe vector
Returns: X component of the Vector or 0 if fails
Usage:
v2 = Vector2f{10, 20};
v3 = Vector3f{100, 200, 300};
x2 = yFromVector(v2); /* returns 20 */
x3 = yFromVector(v3); /* returns 200 */zFromVector
zFromVector(
v: Vector3f
) : floatGet Z component of a Vector
Parameters:
vthe vector
Returns: Z component of the Vector or 0 if fails
Usage:
v2 = Vector2f{10, 20};
v3 = Vector3f{100, 200, 300};
x2 = zFromVector(v2); /* returns 0 */
x3 = zFromVector(v3); /* returns 300 */onUpdate Script Functions
Functions available in the main onUpdate script of the component definition. Attempt to call these functions in other scripts will result in an error. Calls from an onUpdate type component function is possible.
AddAbsoluteDimensioning
AddAbsoluteDimensioning(
axis: string,
from: float,
to: float,
level: int,
*context: 'component' | 'object' | 'both' = 'component',
*label: string = ''
) : voidDynamic possibility to add a component dimensioning object from the onUpdate script. Values for the axis are x, y and z by default and you can add more axes using the AddAbsoluteDimensioningAxis. See Dimensioning for more detailed description.
AddAbsoluteDimensioningAxis
AddAbsoluteDimensioningAxis(
key: string,
origin: Vector3f,
direction: Vector3f,
labelDirection: Vector3f
) : voidDynamic possibility to add a component dimensioning object from the onUpdate script. See Dimensioning for more detailed description.
requestDockItem
requestDockItem(
item: string,
parentPosition: Vector3f,
*childPosition: Vector3f
) : voidSends a docking request to the configurator. After the current update call will have been finished, a docking of the defined configuration will happen. Connection and child component will be available in the next update call. Because the docking does not happen in the configurator kernel, compatible version of the SDK has to be used in custom integration for this function to be available. You need to define which docking points to use on both side by their positions.
This function is only valid in the main onUpdate script and must be inside an if-block.
Parameters:
itemEither an itemId or a stringified configuration JSON that should dock.parentPostionVector3f containing coordinates of a valid parent docking point on the parent side.childPostionOptional: Vector3f containing coordinates of a valid child docking point. If not provided, the first valid child docking point will be used.
Hint: To find out the correct arguments, you can do the docking manually and then check the configuration (which can be achieved by calling RoomleConfigurator.getCurrentConfiguration() or by using the interface buttons of the Rubens CLI). The parent docking point argument is the dockPosition of the child component, the child docking point is the dockChild value of the child component. Both these vectors are equal to the evaluated position values of the docking points.
Hint: It is better to not hardcode the catalogId of the current component, because the component could be published into a draft catalog. You can retrieve the catalogId by calling the getComponentProperty('catalogId') function, in which case the docked component will always be from the same catalog as the parent component.
Usage:
/*
Get the catalogId of the current component and create a childComponentId by appending ':itemId'.
It is better not to hardcode the catalogId, because the component could be published into a draft catalog.
*/
_.catalogId = getComponentProperty('catalogId');
_.childItemId = _.catalogId | ':' | 'itemId';
_.childComponentId = _.catalogId | ':' | 'componentId';
_.assignedWidth = 200;
requestDockItem('catalog:itemId', Vector3f{width / 2, 0, 0}, Vector3f{ 0, 0, 0 });
requestDockItem(
'{
\"componentId\": \"' | _.childComponentId | '\",
\"parameters\": {
\"width\": ' | _.assignedWidth | '
}
}
',
Vector3f{ width / 2, 0, 0 },
Vector3f{ - ' | _.assignedWidth | ' / 2, 0, 0 });setBoxForMeasurement
setBoxForMeasurement(
Box: Vector3f,
Offset: Vector3f
) : voidDefines the box to be used for calculating the measurements of this component. This overrides the bounding box of the geometry in order to change the measurements.
⚠️ This is only valid if called in onUpdate
Parameters:
Box: defines the size of the bounding boxOffset: position of the left rear bottom corner of the box
Hint: This behaves like a combination of AddPlainCube and MoveMatrixBy. Refer to the Dimensioning chapter for more information and examples.
Usage:
setBoxForMeasurement(Vector3f{1600, 800, 670}, Vector3f{-800, 0, 0});setEnabled
setEnabled(
parameterKey: String,
value: Boolean
) : voidSets and overrides the enabled flag of the parameter with the given key. This applies for the update loop in which this call is done.
Parameters:
parameterKey: key of the parametervalue: final status of theenabledflag
Usage:
"parameters": [
{
"key": "width",
"type": "Decimal",
"defaultValue": 100,
"unitType": "length",
"enabled": true,
"validValues": [100, 200, 300]
}
],
"onUpdate": "setEnabled('width', false) /* disables the width parameter */"setOrigin
setOrigin(
origin: Vector3f
) : voidFor computing the position in the Room Planner and the Rubens Configurator, the origin of a component is always the center of bounding box of the current geometry. This however can cause movement relative to the floor while changing dimensions or animating. This function allows to set a custom origin for the component, anchoring it to a specific point.
See Origin of Components for more details.
setVisible
setVisible(
parameterKey: String,
value: Boolean
) : voidSets and overrides the visible flag of the parameter with the given key. This applies for the update loop in which this call is done.
Parameters:
parameterKey: key of the parametervalue: final status of thevisibleflag
Usage:
{
"parameters": [
{
"key": "width",
"type": "Decimal",
"defaultValue": 100,
"unitType": "length",
"visible": true,
"validValues": [100, 200, 300]
}
],
"onUpdate": "setVisible('width', false) /* hides the width parameter */"
}Collision Condition Script Functions
Functions are only available in the collisionCondition script of a docking point, range or line. Attempt to call these functions in other scripts will result in an error. To learn more about collision detection and how it works in RoomleScript, see Collision detection of docked components.
Note: Inside the collisionCondition script, there are variants of the getAbsolutePosition, getPosition and getComponentProperty functions that allow to pass a component runtime ID to retrieve information about the other component in the collision.
collidingComponentIDs
collidingComponentIDs : [Integer]This is not a function, but a getter available in the collisionCondition script. It contains list of other components that collide by their bounding boxes or by their boundingGeometry. You can iterate over elements of this list and check other collision condition script functions to evaluate the collision condition value.
Example:
// iterate over the other colliding components
for (_.i = 0; _.i < length(collidingComponentIDs); _.i++) {
_.collidingComponentId = get(collidingComponentIDs, _.i); // unique runtime ID of the colliding componen
_.collidingComponentExternalId = getComponentProperty('externalId', _.collidingComponentId); // externalId part of the componentId
// avoid collision with shelf, hanger and drawer components of the mywardrobe configurator
if (in(_.collidingComponentExternalId, 'mywardrobe_shelf', 'mywardrobe_hanger', 'mywardrobe_drawer')) {
return false;
}
}
return true;getBoxForMeasurementOrigin
getBoxForMeasurementOrigin(
*runtimeId: int
) : Vector3fReturns the (local) origin position of the measurement box of this component relative to its own root (not global!). ONLY Inside of the collisionCondition script it is possible to optionally pass a componentId to the function to retrieve the data from the corresponding component.
getBoxForMeasurementSize
getBoxForMeasurementSize(
*runtimeId: int
) : Vector3fReturns the size of the measurement box of this component. ONLY Inside of the collisionCondition script it is possible to optionally pass a componentId to the function to retrieve the data from the corresponding component.
getBoxOrigin
getBoxOrigin(
*runtimeId: int
) : Vector3fReturns local origin position of the bounding box of the (other) component with the given runtimeId (or of this/self component if no runtimeId is given) relative to the root of this/self component.
getBoxSize
getBoxSize(
*runtimeId: int
) : Vector3fReturns size of the bounding box of the (other) component with the given runtimeId (or of this/self component if no runtimeId is given).
Geometry Functions
These functions are available in the geometry, boundingGeometry, previewGeometry and geometryHD scripts and in functions of type geometry.
Geometry functions are of two kinds: instantiation functions and modification functions. The modification functions always apply to the last call of the instantiation function of to the last group that was started with a BeginGroup() call and ended with an EndGroup() call. CSG operators apply to the last two instantiation function calls or groups and provide a new modification target.
There are certain enumerations that are used in some of the geometry functions argument. See:
Keyword Arguments of Geometry Functions
In order to be able to fulfill various requirements, like bevel styles and sizes or material mappings, there are many optional parameters for the geometry functions. To avoid confusion and to make the geometry functions easier to use and read, some geometry functions support these parameters to be passed as keyword arguments.
See the function signatures to see which parameters can are optional and can therefore be passed as keyword arguments. See their datatype to determine if a single value or an array of values can be passed.
If the parameter is an array, this array follows a specific index scheme to apply the values to the respective face of the geometry. The overview of the indices is shown in the respective function documentation below.
If these arrays are shorter than the number of faces, the first value at index 0 is applied to the rest of the faces.
Material Parameters
All basic geometry functions support passing a list (array) of material IDs directly in the constructor, either via array of strings or keyword arguments. If different materials get passed, the geometry gets created with the provided different materials. The order of the IDs inside the array is defined as mentioned above in the section Geometry faces indices.
If a material for a side gets provided via keyword arguments but no base material ("material") was given an error message will be logged and the base material gets set to the default value (empty string which results in plain white in the renderer). Some geometries, like prism or cylinder, have no left, right, front and back, but only a side/mantle that goes all around. In this case the material for the side has to be set via the 'materialFront' property or corresponding index in the array, all other provided side materials will be ignored.
If SetObjSurface(...) function gets called after component creation, all previously defined materials get overridden.
Example:
For the AddCube function, the materials parameter can be used as follows:
[
'isdt:black', // base - all faces
'isdt:white', // bevel - bevel is changed to white
'isdt:red' // top - top is changed to red
// the rest has isdt:black - the first value of the array
]which is equivalent to:
material = 'isdt:black',
materialBevel = 'isdt:white',
materialTop = 'isdt:red'
// the rest has isdt:black - the base material parametermaterials = ['isdt:red', 'isdt:green', 'isdt:blue', 'isdt:black', 'isdt:cyan', 'isdt:magenta', 'isdt:yellow', 'isdt:white'];
AddCube(Vector3f{1000, 1000, 1000}, Vector2f{1, 1}, 0, Vector2f{0, 0}, 50, materials);The result is a cube with a green bevel, a blue top, black bottom, cyan front, magenta back, yellow left side and white right side. The first member in the array is always the base material, so if not all sides are explicitly set to a material these sides get the base material assigned.
Edge Style and Width Parameters
See Edge Style for more details and examples.
UvTransform parameters
Similar to the multi-material arrays for geometry construtor functions it is possible to pass multiple different UV-transforms for all basic geometries. That means that all three different UV-transforms can be passed via a single value, to apply the same UV-transform to all faces, or as arrays of values, to apply different UV-transforms to different faces. So for example a uvScale can be passed as single value like Vector2f{2, 2} to apply a 2-times scaling to all faces of the geometry, or as multiple value array [{2, 2}, {3, 3}, {4, 4}] to apply different UV-scalings to different faces of the geometry. The order of the transforms inside the array is defined the same way as it is for the multi material arrays, see the individual function reference documentation for details.
If SetUvTransform(...) function gets called after component creation, the transform gets added to the existing one.
/*
If the wood texture has vertical grain orientation,
a shelf with correct UV mapping, long in the X direction
can be created like this:
*/
AddCube(
{800, 400, 19},
material = 'isdt:wood_oak',
uvRotation = 90
);
/*
If this shelf should be created with the long side in Y direction,
either use the first one and RotateMatrixBy afterwards, or keep the top and bottom
rotation at 0:
*/
AddCube(
{400, 800, 19},
material = 'isdt:wood_oak',
uvRotation = [90, 90, 0, 0],
edgeStyle = 'fillet',
bevelWidth = 5
);EdgeStyle Parameters
With the edgeStyle keyword argument it is possible to set the edge style of the geometry. The available values are edge, chamfer, fillet or defeult.
edge
Creates a sharp edge, no beveling.
chamfer
Creates a chamfered edge, where the edge gets cut off at an angle of 45°.
fillet
Creates a rounded edge, where the edge gets rounded with a radius of the bevel width.
default
Default edges for backward compatibility. Creates a chamfer edge with fillet normal vectors.

Cube
{
"id": "roomle_script_documentation:cube_edge_style",
"geometry": "
AddCube(
{1000, 1000, 1000},
bevelWidth = 250,
edgeStyle = 'fillet',
material = 'kronospan:k411_oe',
materialBevel = 'kronospan:k353_rt'
);
"
}
Example - cube with edge style
Prism
{
"id": "roomle_script_documentation:prism_edge_style",
"geometry": "
_.p = [{1000, 0}];
for (_.i = 1; _.i < 6; _.i++) {
_.a = 2 * M_PI * _.i / 6;
pushBack(_.p, {1000 * cos(_.a), 1000 * sin(_.a)});
}
AddPrism(
1000,
_.p,
bevelWidth = 300,
edgeStyle = 'chamfer',
material = 'egger:h1344_st32',
materialBevel = 'egger:f206_pm'
);
"
}
Example - cube with edge style
Cylinder
{
"id": "roomle_script_documentation:cylinder_edge_style",
"geometry": "
AddCylinder(
500,
500,
1000,
32,
bevelWidth = 250,
edgeStyle = 'fillet',
material = 'pfleiderer:r30023_vv',
materialBevel = 'pfleiderer:s63028_xmsm'
);
"
}
Example - cube with edge style
Cone, truncated Cone

{
"id": "catalog_id:component",
"geometry": "
AddCylinder(
600,
160,
1000,
32,
bevelWidth = 200,
edgeStyle = 'fillet',
material = 'egger:h3359_st32',
materialBevel = 'egger:f093_st7'
);
"
}
Example - cube with edge style
Individual edge Style and Width Paramameter
It is possible to define the edge style and width for each side of the geometry individually. This can be done with the keyword arguments edgeStyleTop, edgeStyleBottom, edgeStyleSide and edgeWidthTop, edgeWidthBottom, edgeWidthSide. The allowed values for the edge styles are the same as for the edgeStyle keyword argument, so edge, chamfer, fillet or default.
However, unlike with edgeStyle the value for edgeStyleTop, edgeStyleBottom, edgeStyleSide cannot only be a single value but also an array of values, where the index of the value inside the array defines the edge of the geometry it gets applied to. If the value is not an array but a single value, it applies to all edges in the area. In addtion a spcific edge cann be addressed by using the keywords edgeStyleTopyN, edgeStyleBottomN, edgeStyleSideN, edgeWidthTopN, edgeWidthBottomN, or edgeWidthSideN, wher N is the index of the edge.
This allows the edge style and width to be defined in a structured manner. For example, the general edge style and the general edge width can be defined with edgeStyle and bevelWidth and additionally a different style and/or width for the top can be defined with edgeStyleTop or edgeWidthTop and on top a specific edge can be defined with edgeStyleTop0, edgeStyleTop1, etc. or edgeWidthTop0, edgeWidthTop1, etc. This allows for a very flexible definition of the edge style and width for each side of the geometry.
Instantiation Functions
AddCube
(
Size:Vector3f{width,depth,height},
*uvScale: Vector2f | [Vector2f] = {1, 1},
*uvRotation: float | [float] = 0,
*uvOffset: Vector2f | [Vector2f] = {0, 0},
*bevelWidth: float = 2,
*edgeWidthTop, *edgeWidthBottom, *edgeWidthSide: float = null,
*edgeWidthTop0, *edgeWidthBottom0, *edgeWidthSide0, *edgeWidthTop1, *edgeWidthBottom1, *edgeWidthSide1, *edgeWidthTop2, *edgeWidthBottom2, *edgeWidthSide2, *edgeWidthTop3, *edgeWidthBottom3, *edgeWidthSide3 : float = null,
*material: String = '<empty material>',
*materials: Array<String> = [],
*materialBevel, *materialTop, *materialBottom*, *materialFront, *materialBack, *materialLeft, *materialRight*: String = null,
*edgeStyle: EdgeStyle = 'default',
*edgeStyleTop, *edgeStyleBottom, *edgeStyleSide: EdgeStyle = null,
*edgeStyleTop0, *edgeStyleBottom0, *edgeStyleSide0, *edgeStyleTop1, *edgeStyleBottom1, *edgeStyleSide1, *edgeStyleTop2, *edgeStyleBottom2, *edgeStyleSide2, *edgeStyleTop3, *edgeStyleBottom3, *edgeStyleSide3 : EdgeStyle = null
) : voidParameters:
Size: Vector3f defining the size of the cube in width (x), depth (y) and height (z) directionuvScale: Vector2f defining the scaling of the UV coordinates in U and V. The higher the value, the more often texture repeats (it appears smaller).uvRotation: float defining the rotation of the UV coordinates in degreesuvOffset: Vector2f defining the offset of the UV coordinates in U and V directionbevelWidth/edgeWidth*: float defining the width of the bevel on all edges of the cube. If set to 0, edges are sharp.material*: materialId of the material to be applied to the base or to the specific face of the cubematerials: array of materials applied to the faces of the cube:edgeStyle*: style of all edges of the cube. See EdgeStyle for possible values.
Adds a beveled or plain cube (depending on the argumnets) to the scene, placed by the left rear lower corner. Its origin is in the center of the cube and an internal transformation is applied to move the cube to instantiate at the mentioned corner. This makes it easier to position the cube in the scene, but has the side effect that animated rotation is applied around the center of the cube.
Array indices:
Parameters that have a possibility to pass an array will follow these indices to apply the values to the respective face of the cube. If the array has less than 8 entries, the first entry at index of 0 is applied to the rest of the faces.
BASE
0
material
BEVEL
1
materialBevel
TOP
2
materialTop
BOTTOM
3
materialBottom
FRONT
4
materialFront
BACK
5
materialBack
LEFT
6
materialLeft
RIGHT
7
materialRight
Example:
AddCube(
{800, 400, 19},
material = 'isdt:wood_oak',
uvRotation = 90
);
AddCube(
{1000, 500, 100},
material = 'demoCatalogId:grid', // all faces
materialBevel = 'isdt:yellow', // all bevels
edgeStyleTop = 'fillet', // all top edges rounded, but rear edge sharp
edgeStyleTop1 = 'edge',
edgeWidthTop = 10,
edgeStyleSide = 'edge', // default sharp edges at side
edgeStyleSide2 = 'fillet', // front left edge
edgeWidthSide2 = 10,
edgeStyleSide3 = 'fillet', // front right edge
edgeWidthSide3 = 10,
edgeWidthBottom = 0,
uvRotation = [0, 0, 90, 0, 45, 45, 45, 45], // top rotated in right angle, all sides 45 degrees
uvScale = [{1, 1}, {1, 1}, {10, 10}] // top scaled 10 times
);
AddCylinder
(
RadiusBottom: float,
RadiusTop: float,
Height: float,
CircleSegments: float,
*uvScale:Vector2f | [Vector2f] = {1, 1},
*uvRotation:float | [float] = 0,
*uvOffset:Vector2f | [Vector2f] = {0, 0},
*bevelWidth: float = 2,
*material: String = null,
*materials: [String] = null,
*edgeStyle: EdgeStyle = 'default',
*edgeWidthTop: EdgeStyle = null,
*edgeWidthBottom: EdgeStyle = null,
*edgeStyleTop: EdgeStyle = null,
*edgeStyleBottom: EdgeStyle =null,
) : voidAdds a cylinder or cone (based on if the two radii are same or different). Its origin is in the center of the bottom base.
Parameters:
radiusBottomradius of the bottom baseradiusTopradius of the topheightheight (distance of bottom and top)facesnumber of faces that form the prism approximating the cylinder (3 - triangular prism, 6 - hexagonal prism etc.)uvScalemultiply UV values of the vertices - the higher the value, the smaller the materialuvRotationrotate UV values of the vertices, in a left-hand directionuvOffsetincrease UV values of the vertices -> moves the material in a negative directionbevelWidthdefault 2, size of the cube's bevel (measured parallel to its walls)
Array indices:
BASE
0
material
BEVEL
1
materialBevel
TOP
2
materialTop
BOTTOM
3
materialBottom
SIDE
4
materialSide
SIDE #N
materialSide0, materialSide1, materialSide2, ...
Usage:
AddCylinder(1000, 300, 2000, 32, Vector2f{1, 1}, 0, Vector2f{0, 0}, 100);
SetObjSurface('isdt:white');
AddDimensioning
(
axis: String,
from: float,
to: float,
level: int,
*context: 'component' | 'object' | 'both' = 'component',
*label: String,
*parameterKey: String = null,
*parameterFunction: String = null
) : voidAdds a Geometry dimensioning object to the scene. See the chapter linked chapter to learn about the feature.
Parameters:
axis: Name of the dimensioning axis to use. Must be defined with theAddDimensioningAxisfunction prior to use.from: Start point of the dimensioning line along the axis in mm.to: End point of the dimensioning line along the axis in mm.level: Level of the dimensioning line in mm. Similar to dimensioning level.context: Context in which the dimensioning is applied. Possible values arecomponent(default) andscene.parameterKey: Optional parameter key to link the dimensioning to a parameter. If provided, the dimensioning will be interactive, providing an input field in the 3D scene.parameterFunction: Optional parameter function to link the dimensioning to a parameter function. If provided, the dimensioning will be interactive, providing an input field in the 3D scene, which takes the value of the interactive dimensoning and passes the returned value into the parameter function.
An existing axis name must be provided, which must be defined with the AddDimensioningAxis function first.
AddDimensioningAxis
(
key: string,
origin: Vector3f,
direction: Vector3f,
labelDirection: Vector3f
) : voidDefines a free dimensioning axis for the AddDimensioning function that can be used with a dimensioning object.
Parameters:
key: Unique key of the axis to be used in theAddDimensioningfunction.origin: Origin of the axis in local coordinates, serving as a 0 point for thefrom,tovalues of the dimensioning object.direction: Direction of the axis as a direction (possible unit) vector, serving also as the positive direction for thetovalue of the dimensioning object. Length of this vector does not matter.labelDirection: Direction into which the dimensioning line is drawn. Length of this vector does not matter.
AddExternalMesh
(
meshId: String,
Bounds: Vector3f,
*BoundsOffset: Vector3f,
*uvScale: Vector2f = {1, 1},
*uvRotation: float = 0,
*uvOffset: Vector2f = {0, 0}
) : voidInstantiate a mesh stored in RAPI (the Rubens Admin database). Has an overload for modifying UV settings.
Parameters:
meshIdthe ID of the mesh in acatalogueId:meshNamepatternBoundssize of the bounding box of the mesh useful for measurements, camera position and preview cubeBoundsOffsetposition of the bounding boxuvScalemultiply UV values of the vertices - the higher the value, the smaller the materialuvRotationrotate UV values of the vertices, in a left-hand directionuvOffsetincrease UV values of the vertices -> moves the material in a negative direction
When performing an export from Blender with the Roomle Blender Addon, you will get a txt file with AddExternalMesh functions accompanying the files you will be uploading to Rubens Admin. You can also get the function from the RuAd mesh entry page. Bounds and boundsOffset tells the configurator the size and position of the loading box until the mesh is loaded.
AddLightSource
AddLightSource(
type: 'spot' | 'point' | 'area',
position: Vector3f,
*direction: Vector3f,
*angle: number,
*color: string,
*intensity: number,
*distance: number,
*penumbra: number,
*decay: number,
*width: number,
*height: number
) : voidAdds a light to the scene. See Light sources for more information.
A light source is a target for modifier functions, like MoveMatrixBy and can be grouped.
Parameters:
type: type of the light source, possible values arespot,pointandareaposition: position of the light sourcedirection: direction of the light source, required forspotandarealightsangle: angle of the light cone forspotlights, in degreescolor: color of the light, as hex code, e.g.#fffffffor whiteintensity: intensity of the lightdistance: distance of the light, how far the light reaches forspotandpointlightspenumbra: softness of the edge of the light cone forspotlights, between 0 and 1decay: amount the light dims along the distance, forspotandpointlights, higher values mean nearer dimmingwidth: width of the light source forarealight sourceheight: height of the light source forarealight source
AddMesh
AddMesh(
Vertices: [Vector3f]
) : voidCreates a mesh from a list of vertices, calculating triangles, normals and UVs automatically.
AddMesh(
Vertices: [Vector3f],
Indices: [Integer],
uvCoordinates: [Vector2f],
normals: [Vector3f]
) : voidCreates a mesh from list of vertices, triangles, normals and UVs are defined manually.
Parameters:
verticeslist of the verticesindiceslist of indices of the vertices forming the triangles, following a left-hand thumb rule⚠️ length of the indices array must be divisible by 3
uvCoordinatesmultiply UV values of the vertices - the higher the value, the smaller the material⚠️ length of the array must be the same as the length of the
verticesarray
normalsrotate UV values of the vertices, in a left-hand direction⚠️ length of the array must be the same as the length of the
verticesarray
Usage:
n2 = 1 / sqrt(2);
n3 = 1 / sqrt(3);
AddMesh(
Vector3f[
/* 0 */{0, 0, 0},
/* 1 */{300, 0, 0},
/* 2 */{0, 300, 0},
/* 3 */{0, 0, 300}
],
[
0, 1, 2,
0, 3, 1,
0, 2, 3
],
Vector2f[
/* uv coordinate of vertex 0 */{0, 0},
/* uv coordinate of vertex 1 */{600, 0},
/* uv coordinate of vertex 2 */{600, -600},
/* uv coordinate of vertex 3 */{0, 600}
],
Vector3f[
/* normal of vertex 0 */{n3, n3, n3},
/* normal of vertex 1 */{0, n2, n2},
/* normal of vertex 2 */{n2, 0, n2},
/* normal of vertex 3 */{n2, n2, 0}
]
);
SetObjSurface('demoCatalogId:grid');
Creates a mesh from list of vertices, triangles, UV and normal coordinates.
(
vertices: [Vector3f],
indices: [Integer],
*uvScale: Vector2f,
*uvRotation: float,
*uvOffset: Vector2f
) : voidCreates a mesh from list of vertices and triangles. Overload for UV modifiers is available.
Parameters:
verticeslist of the verticesindiceslist of indices of the vertices forming the triangles, following a left-hand thumb rule⚠️ length of the indices array must be divisible by 3
uvScalemultiply UV values of the vertices - the higher the value, the smaller the materialuvRotationrotate UV values of the vertices, in a left-hand directionuvOffsetincrease UV values of the vertices -> moves the material in a negative direction
Usage:
AddMesh(
Vector3f[
{0, 0, 0}, /* index 0, origin */
{300, 0, 0}, /* index 1, right */
{0, 300, 0}, /* index 2, forward */
{0, 0, 300} /* index 3, top */
],
[
0, 1, 2, /* triangle in Z plane */
0, 3, 1, /* triangle in Y plane */
0, 2, 3 /* triangle in X plane */
]
);
SetObjSurface('demoCatalogId:grid');
Creates a mesh from list of vertices, triangles, UV and normal coordinates.
AddPlainCube
AddPlainCube(
Size: Vector3f,
*uvScale: Vector2f | [Vector2f] = {1, 1},
*uvRotation: float | [float] = 0,
*uvOffset: Vector2f | [Vector2f] = {0, 0},
*materials: [String]
) : voidA cube with sharp edges. A shortcut for an AddCube with bevel size of 0.
Usage:
AddPlainCube({1000, 1000, 1000});AddPrism
AddPrism(
Height: float,
Vertices: [Vector2f] | [[Vector2f]],
*uvScale: Vector2f | [Vector2f] = {1, 1},
*uvRotation: float | [float] = 0,
*uvOffset: Vector2f | [Vector2f] = {0, 0},
*bevelWidth: float = 2,
*material: String = '<empty material>',
*materials: [String],
*materialBevel: String,
*materialTop: String,
*materialBottom: String,
*materialSide: String,
*materialSide0: String,
*materialSideN: String,
*edgeStyle: EdgeStyle = 'default',
*edgeWidthTop: EdgeStyle,
*edgeWidthBottom: EdgeStyle,
*edgeStyleTop: EdgeStyle,
*edgeStyleBottom: EdgeStyle
) : voidExtrusion of a planar closed sketch in the Z direction. If the materials array is not used, the bevel is not an actual geometric bevel like in cases of other primitive shapes, but is faked by adjustments of normals (this ensures backward compatibility).
Parameters:
Heightlength of the extrusionVerticesif
[Vector2f]: list of vertices forming the sketchif
[[Vector2f]]: First[Vector2f]is the outer contour, the following[Vector2f]are holes in the shape
materials: An array with at least two materials triggers the new construction algorithm with real bevels. See description below.bevelWidth,edgeStyle,material, ... see Keyword Arguments of Geometry Functions for more details and AddCube for an example.
Creates an extruded object given the 2D Shape and the height where bevel width 0 creates sharp prism. You can optionally pass an array with material IDs, see Material parameter. The values for uvScale, uvRotation and uvOffset can also be passed via array to apply different transforms to each geometry face, see section UvTransform parameters. Bevels where not working correctly for prisms so there is a new implementation in place. To use the new construction algorithm you need to pass more then one material or uvTransform to the construction function. This can be the same material or uvTransform twice but it is needed to trigger the new algorithm. This extra step is needed to ensure backwards compatibility.
Array indices:
BASE
0
material
BEVEL
1
materialBevel
TOP
2
materialTop
BOTTOM
3
materialBottom
SIDE
4
materialSide
SIDE #N
N
materialSide0, materialSide1, materialSide2, ...
Usage: Example of a 90 degrees slice of a cirle.
/* sine values for angles */
s0 = 0;
s15 = 0.2588190451;
s30 = 0.5;
s45 = 0.7071067812;
s60 = 0.8660254038;
s75 = 0.9659258263;
s90 = 1;
radius = 100;
AddPrism(
100,
Vector2f[
{0, 0},
{radius * s90, radius * s0},
{radius * s75, radius * s15},
{radius * s60, radius * s30},
{radius * s45, radius * s45},
{radius * s30, radius * s60},
{radius * s15, radius * s75},
{radius * s0, radius * s90}
]
);
SetObjSurface('demoCatalogId:grid');
Prisim with individual materials for each side:
{
"id": "roomle_script_documentation:prism_side_face_material",
"geometry": "
AddPrism(
500,
[{0, 500}, {476, 155}, {294, -405}, {-294, -405}, {-476, 155}],
bevelWidth = 20,
material = 'roomle_script_documentation:black',
materialBevel = 'roomle_script_documentation:white',
materialSide0 = 'roomle_script_documentation:red',
materialSide1 = 'roomle_script_documentation:green',
materialSide2 = 'roomle_script_documentation:blue',
materialSide3 = 'roomle_script_documentation:yellow',
materialSide4 = 'roomle_script_documentation:magenta'
);
"
}Example - prism with individual material on either side

Example - prism with individual uv transformation on either side

Prism with cut-outs
It is possible to create a prism with cut-outs (holes) in the geometry. To do this, an array of polygons is passed to the AddPrism function. Polygons are defined as arrays of points, where each point is a Vector2f. The polygon defines the outline and the holes of the prism. The function AddPrism creates a prism with the specified outline and holes, subtracting the holes from the prism geometry. Unlike the CSG MINUS operator, the cut-outs are not created by a 3D operation, but by defining the holes in the outline of the prism.
Examples:
{
"id": "roomle_script_documentation:prism-with-hole",
"geometry": "
_.outline = [{-300, -600}, {300, -600}];
_.n = 64;
for (_.i = 0; _.i < _.n / 2; _.i++) {
_.a = M_PI * _.i / (_.n / 2);
pushBack(_.outline, {300 * cos(_.a), 300 * sin(_.a)});
}
_.hole = [{180, 0}];
for (_.i = 1; _.i < _.n; _.i++) {
_.a = 2 * M_PI * _.i / _.n;
pushBack(_.hole, {180 * cos(_.a), 180 * sin(_.a)});
}
AddPrism(
100,
[_.outline, _.hole],
bevelWidth = 50,
edgeStyle = 'chamfer'
);
SetObjSurface('pfleiderer:f76001_sd');
RotateMatrixBy({1,0,0},{0,0,0},90);
"
}
{
"id": "catalog_id:component",
"geometry": "
_.outline = [{0, 0}, {0, 800}, {1150, 800}, {1200, 850}, {1200, 1150}, {1250, 1200}, {2000, 1200}, {2000, 0}];
_.hole1 = [{200, 200}, {200, 600}, {600, 600}, {600, 200}];
_.hole2 = [{700, 200}, {700, 600}, {1100, 600}, {1100, 200}];
_.polygons = [_.outline, _.hole1, _.hole2];
AddPrism(
120,
_.polygons,
edgeWidthTop = 50,
edgeStyle = 'edge',
edgeStyleTop = ['edge', 'chamfer', 'chamfer', 'chamfer', 'chamfer', 'chamfer', 'edge', 'edge'],
edgeWidthBottom = 0,
edgeStyleBottom = 'edge',
material = 'egger:u311_st9',
materialTop = 'egger:f030_st75',
materialBevel = 'egger:h3408_st38',
materialSide1 = 'egger:h3408_st38',
materialSide2 = 'egger:h3408_st38',
materialSide3 = 'egger:h3408_st38',
materialSide4 = 'egger:h3408_st38',
materialSide5 = 'egger:h3408_st38'
);
"
}
Example - Worktop with cutouts
AddRectangle
AddRectangle(
Size: Vector2f,
*uvScale: Vector2f | [Vector2f] = {1, 1},
*uvRotation: float | [float] = 0,
*uvOffset: Vector2f | [Vector2f] = {0, 0},
*materials: [String]
) : voidAdds an up facing flat quad in the ground plane with origin in its center. Passing multiple materials or uvTransforms via array is possible but has no effect because Rectangle has only one face. Only the first value will be taken.
Parameters:
Sizesize of the quaduvScalemultiply UV values of the vertices - the higher the value, the smaller the materialuvRotationrotate UV values of the vertices, in a left-hand directionuvOffsetincrease UV values of the vertices -> moves the material in a negative directionmaterialsmaterial or array of materials to be applied to the quad
Copy
Copy() : voidCreates a copy of the last instantiated object and switches the target of all modifiers to the newly created copy instantiated object.
Hint: This function has no parameters and any parameter is ignored. You can use a string argument as a comment, e.g. Copy('left side');
Usage:
screws = 3;
width = 400;
spacing = width / (screws + 1);
offset = spacing / 2;
AddCube(Vector3f{400, 40, 10});
SetObjSurface('isdt:gray');
BeginObjGroup('CREW + NUT + SHIM');
/* shim */
AddCylinder(14, 14, 1, 32, Vector2f{1, 1}, 0, Vector2f{0, 0}, 0);
MoveMatrixBy(Vector3f{0, 0, -1});
Copy();
MoveMatrixBy(Vector3f{0, 0, 11});
/* nut */
AddCylinder(10, 10, 7, 6, Vector2f{1, 1}, 0, Vector2f{0, 0}, 0);
MoveMatrixBy(Vector3f{0, 0, -8});
Copy();
MoveMatrixBy(Vector3f{0, 0, 19});
/* screw */
AddCylinder(3, 3, 14, 32);
MoveMatrixBy(Vector3f{0, 0, -2});
EndObjGroup('SCREW + NUT + SHIM');
SetObjSurface('demoCatalogId:chrome');
MoveMatrixBy(Vector3f{spacing, 20, 0});
/* start with one, we already have the first screw */
for (i = 1; i < screws; i = i + 1) {
Copy();
MoveMatrixBy(Vector3f{spacing, 0, 0});
}
SubComponent
SubComponent(
subComponentInternalId: String
) : voidInstantiates a geometry of the subComponent of a given internalId with its current assigned values. The subComponent must have its active flag set to true. Any modifiers will apply to the whole subComponent geometry as if it was in a group.
For detailed explanation, refer to the SubComponents chapter.
Usage:
"subComponents": [
{
"internalId": "SOFA",
"active": "elementType == 'sofa'",
"numberInPartList": 1,
"assignments": {
"material": "material_primary"
}
}
]if (elementType == 'SOFA') {
SubComponent('SOFA');
}Grouping Functions
Most modifier functions target the last object (some CSG operators target the last two objects). To apply properties to multiple objects at once, you can group them and treat them further as one object. Grouping is done with BeginObjGroup(); and EndObjGroup(); functions. SubComponent instance also behaves like a group. If a custom component geometry function instantiates some geometry, it is not treated as a group and wrapping the contents of the function with BeginObjGroup(); and EndObjGroup(); is recommended in the function body.
BeginObjGroup
BeginObjGroup() : voidStarts an object group. All further geometry objects until the EndObjGroup(); call will be in the same group and will be affected by all other modifiers at once.
BeginObjGroup(); will indent furher code by 4 spaces in the Roomle Component Tool VS Code extension. Every BeginObjGroup(); should match to an EndObjGroup();. Can be nested in any way and combined with SubComponent or CSG operator calls.
Parameters:
there are no arguments, but it is a common to pass a String argument defining the name of the group, however this serves more like as a comment and is ignored by the core.
Usage:
BeginObjGroup();
AddCube(Vector3f{1000, 1000, 1000});
SetObjSurface('isdt:blue');
MoveMatrixBy(Vector3f{ -1000, 0, 0});
AddSphere(Vector3f{1000, 1000, 1000});
MoveMatrixBy(Vector3f{0, 0, 500});
SetObjSurface('isdt:green');
EndObjGroup();
SetObjSurface('isdt:red'); /* overrides colour of the objects in the group, all will be red */
MoveMatrixBy(Vector3f{0, 500, 0});
/*
adds to the position of the objects in the group:
* cube is at {-1000, 500, 0}
* sphere is at {0, 500, 500}
*/EndObjGroup
EndObjGroup() : voidCloses the group started by BeginObjGroup. Removes 4 spaces from indentation.
Modifier Functions
Modifiers are functions called after an object or object group. There are transformations (position, rotation and scale of the object), UV transformations (modify texture mapping) and set material functions in RoomleScript. These functions are indented by one extra space in the Roomle Component Tool VS Code extension to add legibility.
Recommended order of transformations (which is also the most intuitive):
Scale
Rotate
Move
IntersectWithWalls
IntersectWithWalls() : voidIndicates that the previously constructed geometry must be intersected with walls. Intersection with walls cannot be applied prior to 3D Boolean operations. Therefore, using a geometry that needs to be intersected by walls in a Boolean operation will result in an error. This should be used together with component.planInteraction.intersectWithWalls set to true.
MoveMatrixBy
MoveMatrixBy(
translation: Vector3f
) : voidApplies translation transformation to the last object or group. The position will be added (not overriden) to all previous transformations.
Parameters:
move: addition to the position vector of the last object or group
Usage:
AddCube(Vector3f{1000, 1000, 1000});
MoveMatrixBy(Vector3f{0, 0, 1000}); /* moves 1000 mm up*/MoveUvMatrixBy
MoveUvMatrixBy(
uvOffset: Vector2f
) : voidAddition to the mesh's UV coordinates. Positive values bring the texture to the left and to down on a cube.
Parameters:
uvOffsetthe amount to move
Usage:
AddCube(Vector3f{1000, 1000, 1000});
SetObjSurface('demoCatalogId:grid');
MoveUvMatrixBy(Vector2f{500, 100});ReverseFaces
ReverseFaces() : voidReverses the faces of the last drawn object or group. This can fix issues when a mesh is drawn inside out, e.g. after a negative scale operation (mirroring). The winding order of the triangles is reversed.
RotateMatrixBy
RotateMatrixBy(
axis: Vector3f,
pivot: Vector3f,
angle: float
) : voidParameters:
axis: a direction vector of the axis around which you rotatepivot: a point definiing the position of the axis (together withaxisdefines the line)angle: amount of rotation in degrees
Applies the rotation transformation to the last object or group around a defined axis by an amount of degrees of angle in a clockwise direction.

The object is always rotated around the origin of the world (0, 0, 0). That means if the centre of the mesh is not (0, 0, 0) or the object is moved prior to rotation, the origin of the world is the pivot point of the rotation.

To get better control over the rotation, the pivot point can be specified explicitly.

Hint: This is a left hand rule. If you place your left hand thumb in the direction of the axis, fingers will show the positive direction of the rotation. To understand
Usage:
AddCube(Vector3f{1000, 1000, 1000});
/* lifts the cube by its left side by 5 degrees */
/* axis goes forward through the lower right side edge */
RotateMatrixBy(Vector3f{0, 1, 0}, Vector3f{1000, 0, 0}, 5);RotateUvMatrixBy
RotateUvMatrixBy(
uvRotation: float
) : voidRotation of the mesh's UV coordinates. Positive values rotatet the texture clockwise.
Parameters:
uvRotationthe amount to rotate
Usage:
AddCube(Vector3f{1000, 1000, 1000});
SetObjSurface('demoCatalogId:grid');
RotateUvMatrixBy(45);ScaleMatrixBy
ScaleMatrixBy(
scaling: Vector3f,
*pivot: Vector3f = {0, 0, 0}
) : voidApplies a scale transform to the last object or group. Neutral value is 1.
Parameters:
scaling: amount of scale to apply (multiply to previous, not override)origin: pivot point of the scaling operation

The object is always scaled relative the origin of the world (0, 0, 0). This means that if the centre of the mesh is not (0, 0, 0) or the object is moved prior to scaling, the origin of the world is the pivot point for scaling.

To get better control over the scaling, the pivot point can be specified explicitly.

Usage:
AddCube(Vector3f{1000, 1000, 1000});
ScaleMatrixBy(Vector3f{1, 1, 0.001}, Vector3f{0, 0, 1000}); /* scales the cube to 1 mm thickness, top surface of the cube stays in place */SetObjSurface
SetObjSurface(
MaterialId: String
) : voidApplies a material from RAPI to all meshes and faces of the last object or group.
Parameters:
MaterialId: in formatcatalogue:externalIdleading to an existing material entry in RAPI
Usage:
AddCube(Vector3f{1000, 1000, 1000});
SetObjSurface('isdt:black_transparent'); /* applies transparent black material to the cube */SetObjSurfaceAttribute
SetObjSurfaceAttribute(
attributeName: string
) : voidModifies the last object's material shader values. This is especially useful if you intend to have one normal map material which you can afterwards colourize in multiple possible colours. See Material Attributes for more details.
Parameters:
attributeName: either of the material definition, like'color','alpha','roughness','metallic'string valuesattributeValue:0.0fto1.0fifattributeNameisalpha,rougnessormetallicif attributeName is color, then a JavaScript compatible color definition, such as:
#ffffffrgb(255, 0, 128)rgb(50%, 0%, 100%)
Usage:
AddSphere(Vector3f{1000, 1000, 1000});
SetObjSurface('isdt:red');
SetObjSurfaceAttribute('alpha', 0.5); // 50% transparency
SetObjSurfaceAttribute('color', '#00ff00'); // greenSetUvTransform
SetUvTransform(
uvScale: Vector2f,
uvRotation: float,
uvOffset: Vector2f
) : voidSets the UV trasnforms to a given values. This overrides any previous modifiers.
Parameters:
uvScalemultiply UV values of the vertices, neutral value is 1uvRotationrotate UV values of the vertices, in a left-hand directionuvOffsetincrease UV values of the vertices
ScaleUvMatrixBy
ScaleUvMatrixBy(
uvScale: Vector2f
) : voidMultiplication of mesh's UV coordinates. Higher values make the texture smaller. Neutral value is 1.
Parameters:
uvScalethe amount to scale; neutral value is 1; the higher the number, the more often the texture is repeated
Usage:
AddCube(Vector3f{1000, 1000, 1000});
SetObjSurface('demoCatalogId:grid');
ScaleUvMatrixBy(Vector2f{2, 1});CSG Operators
CSG operators are modifiers to the meshes, which split or combine them. Some of them target the last two objects, some only the last one. CSG operators, especially the And, Or and Minus, are expensive operations and should be used sparingly and only with as simple geometries as possible. for example, if you want to cut a round hole into a cube, the maximum feasible performant option is 3 MinusOperator calls with a cylinder, creating a very complex mesh already. Standard mesh creation workflow is should be the first choice. Options are external meshes, AddPrism which can create geometry with holes or defining where the cuts into the geometry are and replace the partion of the mesh with a simple, preferably primitive geometry without bevels.

AndOperator
AndOperator() : voidInterserction of the last two objects or meshes.
Usage:
AddSphere(Vector3f{500, 500, 500});
AddCube(Vector3f{400, 400, 400}, Vector2f{5, 5}, 0, Vector2f{0, 0}, 0);
MoveMatrixBy(Vector3f{ -400 / 2, -400 / 2, -400 / 2});
AndOperator();
ClipOperator
ClipOperator(
position: Vector3f,
direction: Vector3f,
*material: String,
*uvScale: Vector2f,
*uvRotation: float,
*uvOffset: Vector2f
) : voidClips the previously constructed geometry with a plane and optionally creates a cap. The cap geometry is only generated if a material is specified. The resulting geometry object is the original part and the eventual cap together (modifiers target them whole).
Parameters:
position: a point on the clipping planedirection: the normal vector of the clipping plane, the partion of the mesh in the direction of this vector will be keptmaterial: if specified, the cap (filler) will be created with this material; otherwise the mesh will be cut openuvScale: multiply UV values of the cap's verticesuvRotation: rotate UV values of the cap's vertices, in a left-hand directionuvOffset: increase UV values of the cap's vertices
Example: see ClipOperator for more details.
MinusOperator
MinusOperator() : voidSubtracts the geometry of the last object from the penultimate object. Intersection plane will have imprinted the last object's UV map values.
This operator is very expensive and should be used sparingly. It should be tried out and checked for performance on the target meshes before production use.
Usage:
AddSphere(Vector3f{500, 500, 500});
AddCube(Vector3f{400, 400, 400}, Vector2f{5, 5}, 0, Vector2f{0, 0}, 0);
MoveMatrixBy(Vector3f{ -400 / 2, -400 / 2, -400 / 2});
MinusOperator();
OrOperator
OrOperator() : voidUnion of two last geometry objects. Works similarily to an object group, but bakes the meshes in one, removing vertices inside the internal volume.
Usage:
AddSphere(Vector3f{500, 500, 500});
AddCube(Vector3f{400, 400, 400}, Vector2f{5, 5}, 0, Vector2f{0, 0}, 0);
MoveMatrixBy(Vector3f{ -400 / 2, -400 / 2, -400 / 2});
MinusOperator();
StretchOperator
StretchOperator(
position: Vector3f,
direction: Vector3f,
distance: float,
*material: String,
*uvScale: Vector2f,
*uvRotation: float,
*uvOffset: Vector2f
) : voidStretches the previously constructed geometry with at a plane. The object is divided into 2 parts in the plane and an the contour of the cut is extruded and inserted between the two parts. The part in the direction of the normal vector is moved, the other part stays in place. The resulting geometry object is the original parts and the extruded part together (modifiers target them whole).
Parameters:
position: a point on the cutting planedirection: the normal vector of the cutting planedistance: the amount of extrusion in the direction of the normal vectormaterial: material of the inserted extrusion; if not specified, the material of the target object is useduvScale: multiply UV values of the extrusion's verticesuvRotation: rotate UV values of the extrusion's vertices, in a left-hand directionuvOffset: increase UV values of the extrusion's vertices
Animations
For the animations topic, see the Animations Matrix chapter.
There are two versions of the animation functions:
AnimatedMoveBy,AnimatedRotateBy,AnimatedScaleBythat are recommended for preferred use and work in the same manner as the standard transformation functions, are applied to the object or object groups in the same way.AnimationMatrixMoveBy,AnimationMatrixRotateBy,AnimationMatrixScaleBythat apply the animation transformations to the local origins of the individual meshes. This is not as intuitive to use, but could be useful in some special cases. Note: cube from the AddCube function has its local origin at the center, not at its insertion point in the left-rear-bottom corner.
Animation functions have a key parameter, which is the ${animation.key}:${actionKey}. E.g.:
"animations": [
{
"key": "doors",
"actions": [
{
"key": "close"
},
{
"key": "open"
}
]
}
],The keys are doors:close and doors:open.
AnimatedMoveBy
AnimatedMoveBy(
key: String,
translation: Vector3f
) : voidCreates a translation animation for the last object or group.
AnimatedRotateBy
AnimatedRotateBy(
key: String,
axis: Vector3f,
pivot: Vector3f,
angle: float
) : voidCreates a rotation animation for the last object or group.
AnimatedScaleBy
AnimatedScaleBy(
key: String,
scaling: Vector3f,
*pivot: Vector3f
) : voidCreates a scale animation for the last object or group.
AnimationMatrixMoveBy
AnimationMatrixMoveBy(
key: String,
translation: Vector3f
) : voidCreates a translation animation for the local origin of the individual meshes of the last object or group.
AnimationMatrixRotateBy
AnimationMatrixRotateBy(
key: String,
axis: Vector3f,
pivot: Vector3f,
angle: float
) : voidCreates a rotation animation for the local origin of the individual meshes of the last object or group.
AnimationMatrixScaleBy
AnimationMatrixScaleBy(
key: String,
scaling: Vector3f,
*pivot: Vector3f
) : voidCreates a scale animation for the local origin of the individual meshes of the last object or group.
Last updated