SmartShape QL Language Reference
The goal of the SmartShape Query Language (aka "SmartShapeQL") is to perform computations on large tree-like data sets, such as the scene tree of the 3D scene. As such, it aims at efficiency and seeks performance through massive lock-free parallelisation. This is why SmartShapeQL is a (pure) functional programing language.
- there are no variables, only immutable constants
- there are no
whileloops, only iterators
You can read more on functional programing on Wikipedia.
SmartShapeQL evaluation is used to implement many features of the SmartShape platform. In many place, the API will accept and store SmartShapeQL programs instead of values in order to implement business logic in key areas of the platforms.
SmartshapeQL (Smartshape Query Language) is used throughout Smartshape and covers: - Nodes search - Annotations search - Behaviors - Layers - Rendering styles - Search forms - Attribute metadata - Attribute transformation
SmartshapeQL queries: - Can only access data the current user is allowed to access to. - Are case-insensitive.
Similarities and differences with other languages¶
Functions are called like in most programming languages, by writing their name followed by their parameters in parentheses. Functions can return only one value.
Variables are more similar to macros in other languages. They are defined only once by the runtime and the query cannot declare nor modify any variable.
A SmartShapeQL query is composed of only one expression, so complex behavior is achieved by composing function calls.
Notion of context¶
Depending on the API the query is called in, it may behave differently.
The query is applied to each node of the scene and is casted to a boolean value to know whether the node is kept in the search results or not. By default, when no operator nor qualifier is used, the query matches the node name.
$smartshape: See the reference on the
Executes a subquery on the direct children of the current node and returns every child that matches the subquery.
Note: This operator won’t match the currently evaluated node if used in conjunction with “parent”.
Executes a subquery on the parents of the current node and returns every parent that matches the subquery.
Executes a subquery on all the ancestors of the current node and returns every ancestor that matches the subquery.
. operator references the current element that the query is being evaluated on. Useful for calling functions on it.
|Axis Operator||Axis Operator Shorthand|
Node qualifiers allow to access some properties of the currently evaluated node.
All qualifiers have a long notation.
For some qualifiers, a short notation is available.
All operators can be combined with an implicit “and”. For instance, you could find all the walls with a wood material with a query like:
Matches a node with a given name.
Matches a node which contains a given attribute. This operator returns the value of the matched attribute, so it can be used to also match the value of the attribute.
Matches a node belonging to a given layer.
Please note that this operator accepts only layer IDs.
Matches a node that has an ancestor (or itself) belonging to a given layer. Please note that this operator accepts only layer IDs.
Matches a node that has a given modifier applied to it.
Accepted modifier types:
Matches a node that has a given modifier applied to itself or its ancestors. See “modifier” for the list of accepted modifier types.
Matches a node with a specific id.
Matches a node with a specific uuid.
Because SmartShapeQL was originally just a fancy list of operators for SmartShape's scene search engine, some legacy behaviors still apply.
Node name matching¶
String literals are evaluated as the regular expression match against the name of the
Node if any, or
For example, the program
"groundfloor" will actually be evaluated to:
trueif the current context
Nodehas its name set to "groundfloor";
In certain cases, it is also possible to omit the quotes. For example
groundfloor is evaluated to
true if and only if the name of the current
Node contains "groundfloor". It is equivalent to
"*groundfloor*" (see text matching).
Unless explicitly specified otherwise, literal values are casted to
Boolean and combined with the
For example, the
"*42" @status=controlled program is strictly equivalent to
"*42" and @status=controlled.
As such, it will return:
trueif the current context
Nodename ends with "42" and has a
statusattribute set to "controlled";
Boolean literal values are
SmartShapeQL supports implicit coercion of other types to "truthy" and "falsy" boolean values:
- an empty
Stringis evaluated as
- the 0
Numberis evaluated as
false, every other
Numberis evaluated as
String literal values are made of any string of characters that do not match any reserved keyword. Ambiguity can be resolved by using quotes:
falseis not a
Stringliteral (it's a
42is not a
Stringliteral (it's a
- String functions
Number values are 64bit floating precision numerical values.
Integers are also represented using the
SmartShapeQL support compound arrays: each
Array can store values of mixed types.
Array values have no literal notation. Instead,
Array values are created using the
not operators are available and work as expected.
<= operators are available and work as expected.
Note that there are no arithmetic operators.
This query is not valid
Math operators are not available. Use math functions instead.
Works down the array and matches the first element found with a given text.
Works down the array backwards and matches the first element found with a given text.
Matches any element of an array with a given text.
Simple text search¶
The simplest form of a search query is a node name. Entering any text will match the nodes that have this character sequence in their name.
Find nodes whose name contain "groundfloor_entrance":
The characters authorized for simple text search are:
* Alphanumeric characters and letters with accents.
If you need to search nodes by name with other characters, you can use quoting.
Globbing and quoting¶
You can use globbing (
*) and quoting (
" ") to fine-tune your query.
* characters match any character sequence:
" " characters match exactly the character sequence:
add(a: Number, b: Number) : Number¶
Returns a + b.
all(values: Array) : Boolean¶
Returns true if all elements of
values are truthy, false otherwise.
apply(element: Any, query: Query) : Any¶
element. Returns the return value of
array(value1: Any, value2: Any, …) : Array¶
Creates an array containing each value passed in argument in the same order they are passed in.
concat(leftString: String, rightString: String) : String¶
Concatenates two strings together.
Concatenate the “Status” attribute of the node with another String
count(values: Array) : Number¶
Counts the number of elements of an array.
Counts the number of children of the current node
divide(dividend: Number, divisor: Number) : Number¶
Returns dividend / divisor.
dot(vec1: Array, vec2: Array) : Number¶
Returns the dot product between
vec2 must be arrays of numbers of length 3.
flatten(values: Array) : Array¶
values a single level deep.
indexOf(values: Array, value: Any) : Number¶
Returns the index at which the first occurrence of
value is stored in the
fill(values: Array, item: Any, count: Number) : Array¶
Add the value
item to the
filter(values: Array, query: Query) : Array¶
Creates a new array with all elements that pass the test implemented by the query.
floor(num: Number) : Number¶
number rounded down to 0.
get(object: Object, field: String) : Any¶
Returns the field
field of the object
getRangeIndex(value: Number, min: Number, max: Number, numRanges: Number) : Number¶
Returns the index of the range in which
value is found.
map(values: Array, query: Query) : Array¶
Creates an array of values by running
query over each element of
values and returns the resulting array.
max(values: Array) : Number¶
Returns the maximum value of an array.
min(values: Array) : Number¶
Returns the minimum value of an array.
multiply(a: Number, b: Number) : Number¶
Returns a * b.
nth(values: Array, index: Number) : Any¶
Returns the element of
values at index
range(min: Number, max: Number, step: Number) : Array¶
Returns the range [min, max]. If only one argument is given this method will assume it is for the range max.
replace(string: String, pattern: String, replacement: String) : String¶
Replaces matches for
round(num: Number, precision: Number) : Number¶
num rounded to
select(query: Query): Array<Node>¶
Executes a query on every node of the scene. Returns the nodes matched by the query.
Returns every node of the scene
sort(values: Array) : Array¶
values array sorted in ascending order. This method performs a stable sort, that is, it preserves the original sort order of equal elements.
string(value: Any) : String¶
value to a String.
timestampToIsoDate(timestamp: Number, offset: Number) : String¶
Converts a UNIX timestamp (in milliseconds, like the dates stored in annotations) to an ISO 8601 date. The timezone can be chosen with the
offset parameter which corresponds to the offset from UTC.
converts a timestamp to Eastern Standard Time
unique(values: Array) : Array¶
Returns a duplicate-free version of the
values array. Only the first occurrence of each element is kept. The order of result values is determined by the order they occur in the array.
zip(leftArray: Array, rightArray: Array) : Array¶
Creates an array of grouped elements, the first of which contains the first elements of the given arrays, the second of which contains the second elements of the given arrays, and so on.