ShapeScript files can get quite large for complicated scenes, and you may find that there are common shapes that you wish to across multiple ShapeScript files. The import command can help with both of these problems:
import "MyShape.shape"
Here we’ve used import to load an external ShapeScript file and evaluate it inside the calling script. Any symbols that are defined in the imported file will become available inside the scope in which it is loaded, and any geometry created by the imported file will be displayed.
You can import the same file several times in the same script, and import statements can appear inside loops, if statements or blocks. If you don’t want the geometry inside an imported file to be displayed immediately, you can place the import inside a define statement:
define ball {
import "Ball.shape"
}
In this way, the loaded shape is bound to a symbol of your choice, and can be used a later point in the script. This approach also prevents any symbols defined in the imported script from leaking outside into the calling script’s global scope.
Note: As with textures, the first time you try to import a file you may see an access permission warning.
Imported ShapeScript files can define script options, which can be overridden by adding a block to the import command:
import "Wheel.shape" {
radius 2
color #333333
}
The statements inside the import block are option overrides for the imported script. They are evaluated in the importing script’s scope, then passed into the imported file. The imported file’s own option declarations still provide the default values and determine the expected types.
For example, if Wheel.shape contains:
option radius 1
option color #000000
cylinder {
size radius radius 0.25
color color
}
Then the following script imports the wheel twice with different option values:
import "Wheel.shape" {
radius 1
color #222222
}
import "Wheel.shape" {
radius 2
color #ff0000
}
If an import block supplies an option that the imported file has not declared, ShapeScript will report an error.
The import command is not limited to loading .shape files, it can also load 3D models in a variety of standard formats:
| Extension | File Type |
|---|---|
| abc | Alembic |
| csg | OpenSCAD Constructive Solid Geometry |
| dae | COLLADA Digital Asset Exchange |
| obj | Wavefront Object |
| off | Object File Format |
| ply | Polygon File Format |
| scn / scnz | SceneKit Scene |
| stl / stla | Stereolithography |
| svg | Scalable Vector Graphics |
| usd / usdz | Universal Scene Description |
Imported models can be used just like imported script files. Importing a model inserts it directly into your scene:
import "Rocket.obj"
Paths beginning with ~/ are resolved relative to your home directory:
import "~/Desktop/Rocket.obj"
Or you can define a symbol for the model, to be used later:
define rocket import "Rocket.obj"
Depending on the format, imported models may include their own materials. Uncolored / untextured models can be styled in the normal way by using material commands:
define rocket {
texture "Rocket.png"
import "Rocket.obj"
}
Append #name to a ShapeScript or model filename to import just the geometry with that name:
import "Assembly.shape#wheel"
import "Assembly.obj#wheel"
In ShapeScript files, fragments select geometry named with the name property, rather than script variables. The complete script is evaluated, including its imports and options, before selection. Only the selected geometry is added to the calling scene, and the imported script’s symbols remain local to that import.
Model fragments select named objects or groups. OBJ object and group names are preserved. Other model formats depend on the names provided by their importer. Formats that don’t support named geometry, such as STL, cannot provide a matching fragment.
The selected geometry retains its descendants, materials and position in the original scene. Ancestor transforms are applied without including the ancestor groups. Referencing an unknown or ambiguous/duplicate name produces an error. Names containing spaces or special characters can be percent-encoded, for example #front%20wheel.
ShapeScript can import CSG files exported from OpenSCAD:
import "Part.csg"
ShapeScript does not evaluate .scad source programs, so renaming a .scad file to .csg will not work in most cases. ShapeScript’s import options apply only to .shape files.
The importer supports a range of OpenSCAD’s 2D and 3D geometry, including primitives, boolean operations, transforms, extrusions, colors, and text. Imported 2D profiles can be used with ShapeScript’s own extrusion commands:
extrude import "Profile.csg"
Not all features of the CSG format are currently supported. Unsupported operations or options produce warnings. ShapeScript may approximate or skip geometry, ignore an argument, or use child shapes without applying the unsupported operation, so the resulting model may differ from the OpenSCAD original. Unknown or misspelled functions or malformed CSG syntax produce errors rather than warnings.
Note: ShapeScript can also open CSG files directly in the viewer, or via the command-line tool. See Getting Started for how to open a CSG document.
SVG files can be imported as a path or group of paths, using element IDs as geometry names. Both open and closed paths are supported. Add a fragment ID to the filename to load just a specific element or group, including its ancestor transforms:
import "Drawing.svg"
fill import "Drawing.svg#outline"
extrude import "Drawing.svg#part"
The importer supports paths, rectangles, circles, ellipses, polygons, polylines, lines, transforms and local <use> references. Document dimensions and viewBox determine the scale, with physical units converted to millimeters and the SVG Y axis flipped to point upwards. Imports retain their document positions after coordinate conversion, including when selecting individual elements or groups. Separately imported fragments therefore remain aligned with each other. Selecting a fragment ID that does not exist produces an error. SVG colors and other visual styling are not imported; use ShapeScript materials to style the paths.
When an SVG is imported from a CSG file, closed shapes are filled and open paths are converted to closed outlines using their stroke width, caps and joins. Overlapping shapes are combined. CSG imports support id, layer, center, dpi and tessellation options, and retain document coordinates unless center=true.
Text, embedded images, external references, clipping and masks are not supported and produce warnings. Convert text to paths in an SVG editor before importing it.
In addition to scripts and 3D models, plain text files can be imported as a string value.
define text import "Text.txt"
Imported strings can then be displayed directly, or further processed using ShapeScript’s string functions:
for line in text.lines {
print (trim line)
}
ShapeScript also supports importing JSON files as structured data:
define data import "Data.json"
ShapeScript converts JSON arrays to tuples, and JSON objects to objects. If the object uses the same member names as ShapeScript’s block syntax, it can be directly used to create meshes, polygons, points, materials, colors, vectors, and other structured values.
For example, the following JSON file describes a triangular mesh:
{
"name": "triangle",
"polygons": [
{
"points": [
{ "position": [0, 0], "color": [1, 0, 0] },
{ "position": [1, 0], "color": [0, 1, 0] },
{ "position": [0, 1], "color": [0, 0, 1] }
]
}
]
}
If this file is named Triangle.json, it can be imported and displayed like this:
define triangle import "Triangle.json"
mesh triangle
The top-level JSON object can be interpreted as a mesh because it matches the mesh object structure. Mesh objects support name, polygons, and material members. Polygon objects support points and material. Point objects support position, x, y, z, color, and isCurved. Materials use the same member names as material block syntax, such as color, opacity, roughness, metallicity and glow.
Note: ShapeScript currently only supports txt or json file extensions for data files. To import structured text in other formats you will need to change the file extension.
You can also import texture and font files. When you import a texture or font, the import expression returns a value that you can store, pass around, or reuse later:
define woodTexture import "Wood.png"
define uiFont import "UI.ttf"
texture woodTexture
font uiFont
This is different from passing a filename directly to the texture or font commands. Using a file path with those commands both loads the file and immediately applies it to the current scope. Importing the file gives you a value without changing the current texture or font, which is useful when you want to store it in a symbol for later reuse.
It can sometimes be useful to generate the name of an imported file dynamically. For example if you have multiple numbered files to import, you might want to generate the names programatically.
You can do this using the text interpolation feature. The following code, for example, will load the files “Shape1.shape”, “Shape2.shape”… up to “Shape10.shape”:
for n in 1 to 10 {
import "Shape" n ".shape"
}