» webapi documentation » Creating Parametric Designs » Using JavaScript for scripting designs

Prev: Using XML to describe designs Next: OpenSCAD support

Using JavaScript for scripting designs

Our JavaScript API provides a simple yet powerful programmatic way for customizing 3D models. Through various objects and functions, it allows generating and manipulating solids, performing operations on them and modifying their materials. When used as a design modifier, the input of the script is the current 3D model of the design. The output of the script is always a 3D model. Additional global variables may also be defined externally through the use of design parameters, specified for example via a companion XML design description file (see Using XML to describe designs), or via the Web interface.

Types and classes

All JavaScript native types are supported: Number, String, Object, Function, etc.. The native Array, Math and Date classes are also available. In order to manipulate 3D solids the Mesh class is defined. The global object is of Mesh class and describes the 3D model being modified by the script. This class is described in more details in the next section. Additional primitive classes are derived from the Mesh class and are described next. Finally, a ‘print’ function is defined for ease of debugging, which prints its message argument in a black fading box at the time of script execution in the customization page. Uncaught errors are reported in the same manner.

1. Mesh

The Mesh class represents a 3D mesh made of vertices and faces. It is only possible to create and handle meshes representing 3D solids (so they must be closed, non self-intersecting and correcly oriented). Faces of the mesh may be selected to modify it locally, and all faces of the global mesh are initially selected. A Mesh object also contains materials, which may be referenced independently for each face of the mesh, and enables assigning them a color. Textures are not supported yet as of this version of the API. Faces may also belong to named grouped allowing to select easily parts of the mesh.

1.1 Properties

The following properties are defined on the Mesh class:

vn

Number of vertices

fn

Number of faces

minx

Minimal x coordinate of the axis-aligned bounding box

miny

Minimal y coordinate of the axis-aligned bounding box

minz

Minimal z coordinate of the axis-aligned bounding box

maxx

Maximal x coordinate of the axis-aligned bounding box

maxy

Maximal y coordinate of the axis-aligned bounding box

maxz

Maximal z coordinate of the axis-aligned bounding box

dimx

Dimension along the x-axis of the axis-aligned bounding box (=maxx-minx)

dimy

Dimension along the y-axis of the axis-aligned bounding box (=maxy-miny)

dimz

Dimension along the z-axis of the axis-aligned bounding box (=maxz-minz)

centerx

x coordinate of the center of the axis-aligned bounding box (=(maxx+minx)/2)

centery

y coordinate of the center of the axis-aligned bounding box (=(maxy+miny)/2)

centerz

z coordinate of the center of the axis-aligned bounding box (=(maxz+minz)/2)

Note that the vertices coordinates and the face indices are not accessible directly as of this version of the API.

1.2 Boolean operations

All these methods take a second Mesh as argument and perform a boolean operation between the current mesh and the argument. The operation is performed globally, independently of the selected faces.

append(other)

Joins the two meshes.

union(other)

Computes the boolean union of both meshes.

intersection(other)

Computes the boolean intersection of both meshes.

difference(other)

Computes the boolean difference of both meshes.

1.3 Selection

These methods allow modifying face selection.

select_all()

Selects all the faces of the mesh.

select_none()

Unselects all the faces of the mesh

select_inv()

Inverts current selection.

select_more()

Adds all faces adjacent to selected faces to the current selection.

select_less()

Removes all faces adjacent to unselected faces from the current selection.

select_face(face):

Adds the face of index ‘face’ to the current selection.

select_part(part):

Adds the part (connected component/shell) of index ‘part’ to the current selection.

select_group(group):

Adds the group of index ‘group’ to the current selection.

select_material(mat):

Adds the faces using material of index ‘mat’ to the current selection.

1.4 Transforms

These methods move, rotate and scale the selected part of the model. All vertices used by at least one selected face are concerned by the transform.

translate(x,y,z)

Translates the model by vector <x,y,z>.

scale(x,y,z)

Scales the model in each dimension.

scale(x)

Equivalent to scale(x,x,x).

rotate(angle,x,y,z)

Rotates the object along axis <x,y,z> with ‘angle’ degrees.

rotate(x,y,z)

Rotates the object along axis <x,y,z> with norm(<x,y,z>) degrees.

rotate(m00, m01, m02, m10, m11, m12, m20, m21, m22)

Transforms the object using the 3x3 matrix [[m00 m01 m02] [m10 m11 m12] [m20 m21 m22]].

1.5 Materials

color(r,g,b)

Applies color <r,g,b> to the selection. The values r,g,b are Numbers between 0 and 1 representing the color in RGB space.

texture(texture, id = mesh.mn)

Adds or replace a texture of the model. If the optional ‘id’ argument is set to an index less than the number of materials in the model, this material is replaced with the texture, otherwise a new texture material is added and apply to all faces with an uv-mapping.

bump(texture, depth=0.1)

Performs bumpmapping with the given texture by displacing each uv-mapped vertex of the model with the corresponding texture intensity at the vertex location. The ‘depth’ parameter controls the amount of displacement along the vertex normal.

1.6 Faces

ray_intersect(ox,oy,oz,dx,dy,dz)

Returns the index of the first face intersected by a ray of origin <ox,oy,oz> and direction <dx,dy,dz>, or -1 if no face is intersected.

face_part(face)

Returns the index of the part this face belongs to.

face_group(face)

Returns the index of the group this face belongs to.

face_material(face)

Returns the index of the material this face belongs to.

1.7 Miscellaneous

curve(Array)

Defines a new curve from the points in the Array. The array must contains Number elements and its size must be a multiple of three. These values represent the coordinates of the points defining the curve. This function returns the index of the newly created curve.

simplify_distance(distance)

Simplifies the geometry of the solid, with bounded deformation as indicated via the ‘distance’ argument.

2. Primitives

Theses classes extend the Mesh class and are used to create new geometry when instanciated. Note that they must be combined with the global Mesh via Boolean Operations to produce some output. For example, the following script will produce a cube:

append(new Cube());
Tetrahedron()

Creates a new regular tetrahedron inscribed in the unit sphere.

Cube(scale=1.0)

Creates a new cube of unit side, optionally scaled by the ‘scale’ argument.

Sphere(radius=1.0,resolution=100)

Creates a new polygonal approximation of a sphere of radius equal to ‘radius’ and with ‘resolution’*’resolution’ vertices.

Cylinder(radius=1.0,height=1.0,resolution=100)

Creates a new polygonal approximation of a cylinder of radius equal to ‘radius’, height equal to ‘height’ and 2*’resolution’ vertices.

Cone(radius1=1.0, radius2=1.0, height=1.0, resolution=100)

Creates a new polygonal approximation of a cone of lower radius equal to ‘radius1’, upper radius equal to ‘radius2’, height equal to ‘height’ and 2*resolution vertices.

CurveRevolution(curve_index, resolution=100)

Creates a new revolution shape from the given curve.

Text(font, text, height, depth, invcradius)

Creates a new 3D text from the glyphs of ‘font’ and the ‘text’ string. The only available for as of this version of the API is the global variable ‘default_font’. Height and Depth are in model unit, invcradius is the inverse of curved radius.

Heightfield(img, h_support=1.0, h_map=1.0)

Creates a new 3D model using grid rising. ‘img’ is an image of Texture type, representing the heightmap, in grayscale (the whiter the point, the higher it is). ‘h_support’ is the height of the rectangular support generated below, ‘h_map’ is the maximum height of the relief. Generated mesh has the size of the original image. ‘img’ can be input into your script using a texture parameter, see XML Parameters.

Waffle(width=1.0, height=1.0, depth=1.0, resolution_x=100, resolution_y=100)

Creates a new ‘waffle’, a box with the top face segmented into a square grid of ‘resolution_x’ * ‘resolution_y’ resolution. The top face is uv-mapped in the [0,1]^2 interval. Useful for building heightmaps of fixed resolution.

ParametricSurface(resolution_u, resolution_v, Function(u,v) -> [x,y,z])

Creates a close parametric surface. The borders u=0 and u=1 are closed independently while the borders v=0 and v=1 are stitched together. The function argument is executed for each of the resolution_u*resolution_v points of the (u,v) parameter space, numbered from 0 to resolution_u-1 and 0 to resolution_v-1. It must return an Array triplet of Numbers representing the coordinates of the surface point for the input u and v parameter values.

ImplicitSurface(domain, step, value, Function(u,v) -> scalar value, orientation = 1)

Creates a close implicit surface. The domain defines a bounding box where the implicit surface is evaluated. The step defines the distance between the evaluation of two consecutive points where the function will be evaluated. The value is the scalar used to define the border of the surface. The function is used to define the scalar field in the domain. The orientation identifies the interior of the closed implicit surface. When orientation is set to 1, the values lesser than value will define the interior of the surface. If orientation is set to 2, the values greater than the value will define the interior of the surface.

TextOnMesh(mesh, font, text, text_height=0.1, text_size=0.5, tolerance=0.5, rox=0.0, roy=-1.0, roz=0.0, rdx=0.0, rdy=1.0, rdz=0.0, dx=1.0, dy=0.0, dz=0.0)

Creates a text, with glyphs transformed to follow local mesh surface curvature. The ‘mesh’ argument must be a Mesh object on which to fit the text. The ‘font’ argument must be a File object indicating which font to use for text writing. The ‘text’ argument is a String representing the text to write. The text center is determined by tracing a ray from (rox,roy,roz) in the (rdx,rdy,rdz) direction. The (dx,dy,dz) vector is used to determine the direction of text writing. The ‘tolerance’ value is used to determine the text writing region, by grouping mesh faces around the ray hit location so that the cosine of the angle between each face normal and the mean normal of the region do not differ by more than ‘tolerance’. The ‘text_size’ parameter is used to scale the text in the plane. The ‘text_height’ value determines the height of the glyphs.

3. Texture

This class is used to represent bitmap images and textures. It interacts with the Mesh class or its subclasses via texturing, bumpmapping, or heightfield construction.

3.1 Properties

The following properties are defined on the Texture class:

width

Number of pixels in the horizontal dimension.

height

Number of pixels in the vertical dimension.

3.2 Constructor

A single constructor is defined for Texture objects. Direct use of the constructor is rarely needed, instead textures should be imported via design parameters, see XML Parameters.

Texture(width, height)

Creates a new texture of ‘width’x’height’ pixels. The pixels are initially clear, with a (0,0,0,0) value for the (red,green,blue,alpha) components.

3.3 Methods

The following methods are defined on the Texture objects:

get_pixel(x, y)

Returns the pixel at location (x, y), as an Array of four Numbers represention the red, green, blue and alpha components of the pixel. The Number components are in the range [0,255], with 0 representing no intensity and 255 representing full intensity.

set_pixel(x, y, r, g, b, a)

Sets the value of the pixel at location (x, y). The ‘r’, ‘g’ , ‘b’, ‘a’ arguments are used to specify the red, green, blue and alpha components of the pixel respectively.

flip_x()

Flips the texture in the horizontal direction.

flip_y()

Flips the texture in the vertical direction.

invert()

Replaces each (r,g,b,a) pixel with (255-r, 255-g, 255-b)

discard_alpha()

Replaces each (r,g,b,a) pixel with (r,g,b,255)

convert_to_greyscale()

Turns the texture into a greyscale texture by replacing each (r,g,b,a) pixel with (l,l,l,a) where l is equal to 0.3 * r + 0.59 * g + 0.11 * b

histogram_equalization()

Equalizes the texture histogram.

blur()

Blurs the image by averaging pixels in a 3x3 window.

sobel()

Applies Sobel edge detection to the texture

bilinear_resize(width, height)

Resizes the texture to ‘width’ * ‘height’ pixels, by performing bilinear interpolation.

4. File

This class is used to represent files. It is currently used only for font files and interacts with the Mesh class or its subclasses via text writing. It has no constructor, properties or methods, it’s only purpose being to represent files in a safe manner.

5. Audio

This class is used to audio data. It has no direct interaction with other classes. It’s purpose is to hold and access audio data to build designs made from sounds.

5.1 Properties

The following properties are defined on the Audio class:

length

Number of samples in the audio record.

rate

Sampling rate of the record.

channels

Number of audio channels in the record (1 for mono, 2 for stereo).

5.2 Constructor

A single constructor is defined for Audio objects. Direct use of the constructor is rarely needed, instead audio records should be imported via design parameters, see XML Parameters.

Audio(length, channels, rate)

Creates a new audio record of ‘length’ samples, ‘rate’ sampling rate and ‘channels’ number of channels. The samples are initialy set to zero, representing silence.

5.3 Methods

The following methods are defined on the Audio objects:

spectrum(start, length)

Performs spectral analysis of the audio signal, starting at ‘start’ over ‘length’ samples, which must be a power of two. Returns the result of a real-valued FFT over the selected samples, as an Array of Numbers of ‘length’ size, containing the values of the FFT in the [Re(0), Re(1),…, Re(length/2), Im(length/2-1),…, Im(1)] format

Examples

A simple script creating a cube:
append(new Cube());
Coloring the cube with a random color:
var r, g, b, cube;
cube = new Cube();
r = Math.random();
g = Math.random();
b = Math.random();
cube.color(r, g, b)
append(cube);
Drilling a red hole in the cube:
append(new Cube().color(Math.random(),Math.random(),Math.random()));
difference(new Cylinder(0.25, 2).color(1,0,0))
A funny sphere through the use of a parametric surface:
var M_PI = 3.1415926525;
function psphere(u, v)
{
    var fu = 2 * M_PI * u / 100;
    var fv = M_PI * v / 100;

    var fx = Math.cos (fu) * Math.sin (fv) *(0.9+ Math.random() * 0.1);
    var fy = Math.sin (fu) * Math.sin (fv);
    var fz = Math.cos(fv);
    return [ fx, fy, fz ];
}

append(new ParametricSurface(100, 100, psphere));
A Christmas decoration example

Download

Netoile = 6;
Nboule = 3;

function crochet(X) {
  X.union(new Sphere(5).translate(0, 0, 50));
  X.difference(new Cylinder(2, 10).rotate(90, 0, 0).translate(0, 0, 50));
  return X;
}

function branche() {
  var c;

  c = new Cylinder(1, 50);
  c.append(new Cylinder(1, 20, 10).rotate(30, 0, 0).translate(0, -5, 15));
  c.append(new Cylinder(1, 20, 10).rotate(-30, 0, 0).translate(0, 5, 15));

  return c.translate(0, 0, 25);
}

function etoile(n) {
  var e = branche();
  for (var i = 1; i < n; i++) {
    e.append(branche().rotate((360.0 * i) / n, 0, 0));
  }
  return e;
}

function boule(n, m) {
  var b = etoile(n);
  for (var i = 1; i < m; i++) {
    b.append(etoile(n).rotate(0, (360.0 * i) / m, 0));
  }
  return b;
}

append(crochet(boule(Netoile, Nboule)));
Same example inlined in XML to be uploaded directly as a customizable design

Download

<?xml version="1.0" encoding="UTF-8"?>
<sculpteo>

    <design configurable="1">
        <name>Floboule</name>
        <description>Un mélange entre le flocon et la boule de Noël.</description>

        <operation type="script">
            <script type='text/javascript' locked="1">
                /* <![CDATA[ */
                function crochet(X)
                {
                    X.union(new Sphere(5).translate(0,0,50));
                    X.difference(new Cylinder(2,10).rotate(90,0,0).translate(0,0,50));
                    return X;
                }

                function branche()
                {
                    var c;

                    c = new Cylinder(1, 50);
                    c.append((new Cylinder(1,20, 10)).rotate(30,0,0).translate(0,-5,15));
                    c.append((new Cylinder(1,20, 10)).rotate(-30,0,0).translate(0,5,15));

                    return c.translate(0,0,25);
                }

                function etoile(n)
                {
                    var e = branche();
                    for (var i = 1; i < n; i++) {
                        e.append(branche().rotate(360.0 * i / n, 0, 0));
                    }
                    return e;
                }

                function boule(n, m)
                {
                    var b = etoile(n);
                    for (var i = 1; i < m; i++) {
                        b.append(etoile(n).rotate(0, 360.0 * i / m, 0));
                    }
                    return b;
                }

                append(crochet(boule(Netoile, Nboule)));

                /* ]]> */
            </script>

            <parameter type="select" value="6">
                <description>Nombre de branches</description>
                <bind value="Netoile"/>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
                <option value="10">10</option>
            </parameter>

            <parameter type="select" value="3">
                <description>Nombre d'étoiles</description>
                <bind value="Nboule"/>
                <option value="3">3</option>
                <option value="4">4</option>
                <option value="5">5</option>
                <option value="6">6</option>
                <option value="7">7</option>
                <option value="8">8</option>
                <option value="9">9</option>
                <option value="10">10</option>
            </parameter>

        </operation>
    </design>

</sculpteo>
Prev: Using XML to describe designs Next: OpenSCAD support

» webapi documentation » Creating Parametric Designs » Using JavaScript for scripting designs

Last update: 1970-01-01 01:00 (CET)