OpenSCAD User Manual/Objects
part of the section on Values, Data Types, and Constants
Creating Objects
Built-In Object Creators
- textmetrics()
- function to extract size and formatting info from a text string.
- fontmetrics()
- function to extract information from a font.
- data=import()
- function to import data from a JSON file.
Object() Function
[Note: Requires version Dev Snapshot 2025.07.11 or later]
Note: Objects are currently experimental and so must be enabled in menu item Edit > Preferences > Features Tab > checkbox
A call to the object() function returns an object containing the member definitions in the order they are given as arguments to the function call.
Member Names
Member names are strings and are not limited by the rules for variable names.
unicode_name="invalid\u00A3object,name";
namevar = "goodname";
xxx= object( [
["bad name", 12],
[unicode_name,"anything"],
[goodname,5],
["this\nthat", "value" ]
]
);
which echo shows as:
{ bad name = 12; invalid£object,name = "anything"; goodname = "5"; this
that = "value"; }
Note the Unicode character "£" and the newline between "this" and "that".
Members can be accessed for use in expressions in two ways, as will be seen later in this page. Member names that follow the Variable Name rules may use Dot Notation in an expression:
sphere( r=xxx.goodname);
in the same way as the first three elements of a vector may be access by vec.x, vec.y, and vec.z.
All member names may use the square brackets and string syntax for accessing object members:
sphere( r=xxx["bad name"]);
which in this case is a constant string, "bad name", with a space character in it, so a member reference in dot notation, as xxx.bad name, will emit a warning.
The string between square brackets may be a constant, a variable with a string value, or a string resulting from an expressions evaluation.
Name=Value Members
The simplest member definition is a <name>=<value> assignment, where name is a valid variable name and <value> is an expression result.
Example
Fred = object( name="Fred", spouse="Wilma", friends=["Barney"] );
// ECHO: Fred = { name = "Fred"; spouse = "Wilma"; friend = ["Barney"]; }
When <value> is calculated by an expression that results in undef the member is still added:
Barney = object( name="Barney", spouse=Betty );
// ECHO: Barney = { name = "Barney"; spouse = undef; }
Vector of Members
Members may also be created using a vector of [name,value] vector elements
my_object = object( [ ["<name>",<value>], ["<name>",<value>] ] );
Where the <name> is any expression resulting in a string, and the value is any expression result.
Using the vector argument form of member definition it is possible to edit an object's members.
A name only element like, [["name"]], will remove the named member from the object.
It is not an error to attempt removing a member that does not exist in the object.
Assigning undef is allowed, as seen above, but that does not remove the member.
Example of Removal
We define a person:
Fred = object( name="Fred", spouse="Wilma", friends=["Barney"] );
and then another one:
Wilma= object( name="Wilma", spouse=Fred, friends=["Betty"] );
but for Wilma the object Fred has been assigned as the spouse. Now that the Wilma object is defined a copy of Fred could be made using the Wilma object as spouse. First we copy the members of Fred to newFred, remove the spouse member, and then define a new spouse using the object Wilma:
newFred = object( Fred, [["spouse"]], spouse=Wilma );
echo( newFred );
//ECHO: { name = "Fred"; friends = ["barney"]; spouse={ name="Wilma"; ... }}
The spouse member is gone.
Removing a member that does not exist in the object is not an error:
newFred = object( Fred, [["child"]] );
newFred is an exact copy of Fred as there was no "child" member to remove.
Copying an Object
An existing object may be given as an argument to an object():
o1 = object( one=1 ); // make an object o2 = object( o1 ); // make a copy
Additional members may be added to the copy, and removals done, as in the previous section.
Lets assume that Fred and Wilma objects are already defined.
Wilma with a member spouse=Fred and having removed spouse from Fred we want to add the Wilma object as spouse:
newFred = object( Fred, spouse=Wilma );
and now:
newFred = {
name = "Fred";
spouse = {
name = "Wilma"; // object as spouse
spouse = {
name = "Fred"; // the Fred Object is Wilma's spouse
spouse = "wilma"; // placeholder value
friends = ["barney"]; // Fred's friend
};
friends = ["Betty"]; // Wilma's friend
};
friends = ["barney"]; // newFred's friend
}
Now we can chain member references ject in an object:
echo( WHsp = Wilma.spouse.spouse, "\n" ); // "wilma" from original Fred
Note: The Wilma.spouse is the original Fred and newFred has the Wilma object as spouse
The argument list of object() may combine any of the member definition forms allowing us to combine operations.
The spouse member could be removed and replaced in one call:
newFred = object( Fred, [["spouse"]], spouse=Wilma ); echo( newFred =newFred, "\n");
gives
newFred = {
name = "Fred";
friends = ["barney"];
spouse = { name = "Wilma"; spouse = undef; friends = ["Betty"]; };
},
Showing the spouse member is now the Wilma object and is the last member in the object.
Note: The order of the members is updated by the removal a member and by the addition of a new one
Object Combinations Accumulate
Giving an object as an argument copies its members to the new object. Giving additional objects as arguments will add its members to the new object, overriding any members of the first object that have the same name.
The language rule about assigning a new value to an existing variable applies to object creation. The rule is that assignment to a previously defined name sets the new value at the location of the first definition meaning that the new value is used everywhere in the script. The arguments to object() are effectively a sequence of assignments creating named objects and so any of the member definition forms that use existing member names will override previous values, and when listed ( by echo() ) will show the last set value in the position of the first definition.
When we add two objects to create xxx:
Fred = object( name="Fred", spouse="wilma", friends=["Barney"] );
echo(Fred =Fred, "\n");
// define Wilma using the Fred object as spouse
Wilma = object( name="Wilma", spouse=Fred, friends=["Betty"] );
echo( Wilma=Wilma, "\n");
xxx=object(Fred,Wilma);
The combined object, xxx, will be a copy of Wilma:
Fred = { name = "Fred"; spouse = "wilma"; friends = ["Barney"]; }
Wilma = { name = "Wilma";
spouse = { name = "Fred"; spouse = "wilma"; friends = ["Barney"]; };
friends = ["Betty"];
}
ECHO: { name = "Wilma";
spouse = { name = "Fred"; spouse = "wilma"; friends = ["Barney"]; };
friends = ["Betty"];
}
When the object being combined have members that are not in the others they are added to the combination in the order of the list:
Fred = object( name="Fred", spouse="wilma", children=["Pebbles"] );
Wilma = object( name="Wilma", spouse=Fred, pets=["Dino"] );
xxx=object(Fred,Wilma);
echo(xxx);
The combined result, xxx, is thus:
{ name = "Wilma";
spouse = { name = "Fred"; spouse = "wilma"; children = ["Pebbles"]; };
children = ["Pebbles"];
pets = ["Dino"];
}
Members name and spouse from Wilma have overridden those of Fred, and the children and pets vectors are added in the order of Fred and Wilma in the argument list.
To illustrate this further we combine the original Fred and Wilma, then remove the spouse member:
xxx = object( Fred, Wilma, <nowiki>[["spouse"]]</nowiki> );
// xxx= { name = "Wilma"; friend = ["Betty"]; }
Explanation:
- Fred object is added to xxx
- members of the Wilma object override the values of Fred's members
- removing the
spousemember affects the copy of Wilma - xxx is a copy of Wilma, with no spouse
If an assignment or object later in the argument list overrides something before it it may look like members are out of order. If we prefer to have Fred.spouse be the Wilma object we might try:
// set spouse to a placeholder value
Fred = object( name="Fred", spouse="wilma", friends=["barney"] );
// create a Wilma object
Wilma = object( name="Wilma", spouse=Fred, friends=["Betty"] );
// this will NOT give Fred2 the Wilma object as spouse
Fred2 = object( spouse=Wilma, Fred );
// ECHO: { spouse = "wilma"; name = "Fred"; friends = ["barney"]; }
To explain:
- The new object,
Fred2, is given theWilmaobject as its first member,spouse - the
Fredobject is added so its members are applied:Fred.spouse("wilma") overrides Fred2.spouse in the position of the first definition in Fred2- Fred.name and Fred.friends are added to Fred2 as second and third members
The result shown by echo() by the rule of "new value defined as if at original definition" is correct.
Functions as Members
fx = function(x)x+2;
xxx=object( this="that",that=12, func=function(x)x+2);
echo(xxx, xxx.func(8) );
// ECHO: { this = "that"; that = 12; func = function(x) (x + 2); }, 10
Object Data Type
[Note: Requires version Development snapshot]
An "object" is a collection of names and associated values. In other languages this data structure might be called an object (JavaScript), a dictionary (Python), or an associative array (some UNIX shells, awk),
Retrieving Member Values
The name of a member may be used in this dot notation:
n = obj.name;
Using the vector index form, but with a string required in place of an integer, we can achieve the same result:
n=obj["name"];
Members with valid identifier names can be accessed using either syntax. Names for members that do not meet the Named Object rules must be given as strings using this format.
Iterating over object members
The for statement is extended to loop through the keys of an object in the order the object members were defined in:
for( key = object ) <statement object[key]>
The loop counter key in this case, is the member's name as a string.
Inside the loop the array index form, ["key"], must be used to refer to members, with the advantage that even keys with non-compliant names will be correctly processed.
So:
oo = object( [["a!",1],["b@",2],["c#",3],["d$",4],["e%",5],["f^",6] ] ); keys = [for( io = oo ) io]; // ["a!", "b@", "c#", "d$", "e%", "f^"]
To be able to process all of the object's values we must use the text names:
doubles = object( [ for( io = oo ) [ io, oo[io] * 2 ] ] ); echo(doubles); // [2, 4, 6, 8, 10, 12]
Object Comparisons
The equality operators work with objects:
my_object = object( name=12 );
your_object = object( my_object ); // make a copy
echo( my_object == your_object); // true
echo( my_object != your_object); // false
an_object = object( name="this", other=12 );
na_object = object( other=12, name="this" );
echo( an_object == na_object); // false
echo( an_object != na_object); // true
But not the relational ones:
xx_object = object( name="this", other=12 );
yy_object = object( name="this", other=13 );
echo( xx_object < yy_object ); // WARNING: operation undefined (object < object)
echo( xx_object >= yy_object ); // WARNING: operation undefined (object >= object)
is_object() Function
returns true when its argument is an object and false otherwise.
has_key() Function
There is a new function has_key( <object>,<name> ) that returns true if the object contains the named key.