In this post, I’m going to show you some examples of Meshcripter using.

If you’re trembling, watch this (I suggest you to watch it on Youtube for a better quality):

Meshcripter provides a handful of global objects that manage the interaction with the main components (the mesh, the renderer, the console, and a special algebraic object). These are specialized as soon as the user needs finer grain objects (e.g. a face). We have four global objects:

**mesh** manages mesh interaction/access;

**viewer** allows customizations of the renderer;

**algebra** endows the console with vector and matrices;

**console** provides access to the console itself;

## Mesh Access

Mesh access operations are, for example, mesh traversal and interaction (performed through **mesh **global object). These operations allow us to obtain references to finer grain scripters:

# vertex = mesh.vertex(0) vertex [0] (0.00,0.00,0.00) # vertex.coords() 0.00,0.00,0.00

**vertex **is a “console-reference” to vertex 0 (each element has a unique integer index – like in Topology). Suppose we want to change the coordinates of vertex:

# vertex.changeCoords([0.1,0.1,0.1])

This function modifies the coordinates of the caller vertex, receiving an array as a parameter. Now, we generate a 20×20 quads grid and we map it to a disk (circle):

Remember the parametric form of the circle:

x = radius u cos(v) y = radius u sin(v) z = 0 u ∈ [0,1] v ∈ [0,2π] radius is a real number

We use it to map the grid to a disk:

for(i=0; i<mesh.verts_num(); i++) { x = mesh.vertex(i).coords()[0]; y = mesh.vertex(i).coords()[1]; mesh.vertex(i).changeCoords([ y*Math.cos(x*Math.PI*2), y*Math.sin(x*Math.PI*2), 0 ]); }

One can perform as many mappings as one wants to, knowing the function to use. The result can be exported in a new mesh.

Now, we obtain a reference to the face 0 and we show some basic information about that:

# face = mesh.face(0) face [0] {vertices->(0, 11, 12, 1) edges->(3, 0, 1, 2)}

It means the face 0 is bounded by vertices 0, 11, 12, 1 and by edges 3, 0, 1, 2. Obviously, it is possible to grasp a reference to one of these:

# vertex_of_face = face.vertex(0) vertex [0] (0.00,0.00,0.00)

These initial functions suffice to deal with several issues (e.g. Topology, Geometry).

## Mesh Refinement

# mesh.split_face(54) # mesh.split_face(53) # mesh.split_face(44) # mesh.split_face(43)

The effect of some quadtree splits is shown above. Below, barycentric splits are figured:

Observe a progressive split on a torus (the doughnut), starting from a 3×3 quads grid:

The latter rendering is performed by a couple of shaders, implementing the Phong lighting model.

## Renderer Customization

The object **viewer** provides several functions able to customize the renderer. For example, materials/lights setting, shaders, faces/edges selection/highlighting, mesh subsets rendering.

We select some faces through the picking function and return them stopping it:

# faces=viewer.stopPicking() 7,17,27,37,47,57,67,77,87,97

faces is an array containing the indices of the selected faces . Let’s draw only these:

# viewer.faces(faces)

Similarly with some edges:

# edges = [3,6,9,12,15,18,21,24,27,30] # viewer.edges(edges)

**viewer** allows us to employ custom materials. Let’s create an emerald (searching the Web for the values) and use it together with a Blinn-Phong light per-pixel shader:

# emerald = viewer.newMaterial() # emerald.setAmbient([0.0215, 0.1745, 0.0215, 1]) # emerald.setDiffuse([0.07568, 0.61424, 0.07568, 1]) # emerald.setSpecular([0.633, 0.727811, 0.633, 1]) # emerald.setShininess(0.6*128) # viewer.setMaterial(emerald)

We can manage lights properties (a single source, for now):

# viewer.lightPos([1,1,1,0]) # viewer.lightAmb([1,0,0,0])

These commands, for example, sets the position and the ambient component of the light.

Some built-in shaders are shown above (the user can also write his own shaders):

## Computational Functionalities

Meshcripter provides both sparse matrices and vectors (supplied by **boost** library). The reason arises from its original purpose: supporting the Metrized Chains Method (plm.dia.uniroma3.it/milicchio/2009/10/discrete-physics-using-metrized-chains). Specifically, one can associate a value for each vertices (faces) and color the mesh according to these values (using a color map – e.g. a heat field). These data could be imported or computed by Meshcripter, thanks to its “algebraic support”. For example, we can render two Dirac impulses on a toroidal grid (opposite bounded vertices and edges are “topologically equivalent”):

It’s not important how to obtain those values, but the support to matrices calculation is significant:

# matrix = algebra.getMatrix(1,1) matrix { _->0} # matrix_2 = algebra.newMatrix([[1,1],[2,2]]) matrix {(0,0)->1, (0,1)->1, (1,0)->2, (1,1)->2} # vector = algebra.newVector([1,2,3,4]) vector {0->1, 1->2, 2->3, 3->4}

Mehscripter supplies all the functions for accessing/setting values on matrices and vectors, in addition to sum, inversion, product, transposition, SOE solving, etc.

It’s interesting to observe the full integration with Javascript arrays (in both “directions”):

# vector = algebra.getVector(16) vector { _->0} # vector.set(0,10) # vector.set(10,-1.05) # vector {0->10, 10->-1.05, _->0} # js_array = vector.toArray() 10,0,0,0,0,0,0,0,0,0,-1.05,0,0,0,0,0 # js_array[0] 10 # js_array[1] 0 # js_array[3]=4 4 # js_array 10,0,0,4,0,0,0,0,0,0,-1.05,0,0,0,0,0 # vector.replace(js_array) # vector {0->10, 3->4, 10->-1.05, _->0}

## Scripts loaded from a file

Sometimes writing programs by hand is inconvenient, it could be better to load them from a file, also for reusing purposes. For example, suppose you know a lot of materials and you want to store their values in a file, thus you’ll be able to employ them when you need to. Then you can just write a simple txt file (or any format you like) and load it when you want to, invoking the load function (or using the console menu):

# load("materials.txt")

Through the scripts, writing own functions is as easy as loading them. This capability makes the tool highly customizable. As a final example, we write a script to map a grid to a sinusoidal surface:

for(i=0;i<mesh.verts_num();i++) { x = mesh.vertex(i).coords()[0]; y = mesh.vertex(i).coords()[1]; mesh.vertex(i).changeCoords([ x, y, 0.3*Math.sin(x*2*Math.PI)*Math.sin(y*2*Math.PI)]); }