Posts Tagged ‘Mesh’

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):

Grid Generation panel

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
         ]);
}

Grid mapped to a unit-disk

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)

QuadTree splits performed on some faces of the grid

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

A couple of barycentric splits performed on the grid

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

Progressive splits on a torus (3x3 to 96x96).

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 picking of a torus

# 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)

Drawing of the selected faces

Similarly with some edges:

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

Drawing of some 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)

Elephant mesh rendered with an emerald material

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):

Different shaders applied on the elephant (Toon, Brick, Bumpy, Normals as RGB color)

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”):

Two Dirac impulses on a quads grid

Impulses on the refined grid


Distorted Grid (in according to the impulses impact)

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)]);
}

The sinusoidal surface obtained by the script listed above


Meshcripter (fancy portmanteau between the words Mesh and Scripter – Mesh Scripter) is an OpenGL and Qt tool for mesh management and real-time interaction, written in C++. It is equipped with a text console through which one performs almost all mesh operations, rendering customizations, and functions definition.

The powerful Qt-Script module provides a Javascript-like language, endowed with several objects that allow a console-based interplay. These objects (called scripters) set up a separate level of indirection (namely, a new layer), particularly convenient for modifiability and expandability issues. New scripters are simple to add and old scripters are change-prone.

The first release of Meshcripter was called Homology Tools because it was designed to grasp some of Homology and Algebraic Topology concepts, such as chain, incidence matrix, and boundary operator. Specifically, it was written to employ the Metrized Chains Method in a real context. The main idea is to embed all the properties (geometry, topology and physics – talking about simulations) of a complex (namely, a Cell Complex) in a single mathematical framework, making possible simultaneous changing of these properties (e.g. a mesh refinement influences automatically the physics of the scene). Homology Tools made use of this method to compute physics impact on the mesh (e.g. solution of a field problem) and to visualize it, by a color map (e.g. a heat field on a doughnut). One was able to import and export all the structures (e.g. matrices and vectors) used by this method, refine and manipulate the mesh, just explore the mesh or render few parts of it, etc.

These ideas have not entirely disappeared in Meshcripter. Some of the Metrized Chains Method routines and a few other things were removed. The new goal of Meshcripter is to focus on mesh interaction, manipulation and visualization. Anyhow, one can manually define functions for Metrized Chains Methods behavior, because the rendering mode by color maps is left enabled!

Hence, Meshcripter provides several topological and mathematical features. Users are able to explore the mesh and perform operations on it, supported by a solid rendering and a powerful language. Persistence is supported by CGAL.

This new adventure begins in Jan 2011. I’ve just created a new branch of hTools, now it is Meshcripter. The first step is “cleaning” unwanted features (they are very few), then I’ll need to improve the base code (a sort of refactoring). Next, I hope I’ll be ready for new operations implementation.

I’m going to employ this category to report interesting things, showing videos when it is possible. Stay tuned!