Minor bug-fixes and some Processing 2.0 issues. Remove the current library before reinstalling.
W:Blut HE_Mesh
A Processing library for mesh creation and manipulation
HE_Mesh 1.8
A few fixes, long overdue. Those of you who contacted me personally are probably already using this one but I’ve neglected the rest of you.
To use, remove the old HE_Mesh library and replace it with this one.Remove all hemesh.* imports from your code and do a fresh import.
Cheers!
A promise … soon
Always:
import wblut.math.*;
import wblut.processing.*;
import wblut.core.*;
import wblut.hemesh.*;
import wblut.geom.*;
HE_Mesh: a 3D library for Processing
Download the latest version here.
Coded, recoded, lost, recoded and recoded … HE_Mesh, the half-edge mesh library for Processing has slowly accreted to a state that warrants a release. A release in more than one way. In retrospect, the current functionality looks depressingly small, especially compared to the hundreds of hours that already went into coding it. But like a broke home-owner with a basement and a half-finished first floor, I comfort myself with the thought that it holds potential for growth.
At least, that’s what I wrote more than a year ago. Some of the basement turned out mouldy, the first floor is somewhat basic but liveable. The second floor is taking shape and the garden is filled with a variety of half-finished sheds… No doubt about it, I’m a belgian.
What is HE_Mesh?
HE_Mesh is an implementation of a half-edge datastructure for manipulating 3D meshes in Processing. Basically it’s a toolset to extend my Processing sandbox to a proper playground.
Generating and displaying a mesh requires nothing more than a list of vertices and a list of faces connecting them. This hardly requires a special dataset. However, manipulating a mesh in any but a trivial way requires a lot of connectivity information: neighboring vertices, neighboring faces, shared edges,… Keeping track of this in a simple facelist type structure is difficult. Hence the need for a datastructure that incorporates connectivity information in an efficient way: the half-edge mesh.
What can HE_Mesh do?
The library is currently focused on the stuff I coded it for: generative/degenerative geometry. So with HE_Mesh we can create and manipulate 3D meshes. Several primitives are built-in, but any kind of 2-manifold mesh can be turned into a half-edge mesh from its vertices and facelist. The weight of the implementation lies in closed meshes but open surfaces are handled as well.
Creating meshes is cool (for a given amount of cool) but destroying them is cooler. Several modifiers are provided, either as part of the basic mesh functionality or as separate modifier classes. Subdividors are a special class of modifier oriented towards subdivisions. (The names might not be original but I guess it’s easier to remember than quaghot and umpsink.)
What HE_Mesh can’t do…
The half-edge datastructure has a few limitations in itself. In practice, each edge in a mesh can be shared by at most two faces. The implementation is strongly face-based, isolated vertices and edges are not supported and will lead to ouchie.
The initial intent of HE_Mesh was to build a system to prototype geometric play. So large-scale systems were never a goal. Several implemented algorithms are O(n²) and use a lot of storage. Connaiseurs and lectors in computational geometry are advised to avoid perusing the code, bleeding eyes often offend. On the positive side, there’s room for improvement…
HE_Mesh doesn’t turn Processing into RhinoJava or 3D Studio Processing. It does not provide a GUI to manipulate meshes on-screen. Neither was it conceived as a modelling library. Still, HE_Mesh provides the elements needed to build such an application if needed.
Getting HE_Mesh
The library is maintained at code.google.com. HE_Mesh is currently at beta version 1.5.0. Download and extract the archive inside the Processing ‘libraries’ folder. The ‘reference’ and ‘tutorial’ subfolders contain several examples.
Future
At this time, the library reflects my current interests. If you want it to do something else, have a suggestion or HE_Mesh goes haywire on you, let me know!
import wblut.hemesh.modifiers.*;
import wblut.core.processing.*;
import wblut.hemesh.creators.*;
import wblut.hemesh.core.*;
HE_Mesh mesh;
WB_Render render;
void setup() {
size(800, 800, P3D);
createMesh();
HEM_SphereInversion modifier=new HEM_SphereInversion();
modifier.setRadius(200);
modifier.setCenter(50, 0, 0);
modifier.setCutoff(1000);
modifier.setLinear(false);
mesh.modify(modifier);
render=new WB_Render(this);
}
void draw() {
background(120);
directionalLight(255, 255, 255, 1, 1, -1);
directionalLight(127, 127, 127, -1, -1, 1);
translate(400, 400, 0);
rotateY(mouseX*1.0f/width*TWO_PI);
rotateX(mouseY*1.0f/height*TWO_PI);
fill(255);
noStroke();
render.drawFaces(mesh);
stroke(0);
render.drawEdges(mesh);
}
void createMesh() {
HEC_Cube creator=new HEC_Cube(300, 1,1, 1);
mesh=new HE_Mesh(creator);
mesh.modify(new HEM_Extrude().setDistance(300));
mesh=new HE_Mesh(new HEC_FromFrame().setFrame(mesh).setMaximumStrutLength(20));
}
Did you code all of HE_Mesh?
Sometimes you get wrapped up in writing a piece of code, getting it to work your only purpose. Inevitably you turn to existing code, ripping and tearing through it to get at its beating heart.
With the internet providing access to such an amount of information, it can be easy to forget where a particular solution came from. On the other hand, including complete generic libraries to benefit from a few classes in specific instances would quickly bloat any project. I tried to compile a list of code that was ravaged for the good of HE_Mesh:
- Javolution is included in the HE_Mesh distribution. This high-performance library offers fast, reliable alternatives for many of JAVA’s basic classes. Without FastTable and FastMap, HE_Mesh would be a lot slower.
- libssrckdtree-j Generic k-d tree Java library: only a barebone skeleton remains of this truly generic k-d tree implementation, wblut.tree.WB_KDTree and wblut.tree.WB_KDNeighbor. It provides lightning-fast closest-point calculation and degenerate-vertex checking. Although k-d tree algorithms are well-described, implementing a fast one yourself is a less than trivial task.
- Sean Luke’s fast Mersenne Twister random number generator is my preferred RNG throughout hemesh. For (my) convenience it is exposed through wblut.math.WB_MTRandom, WB_RandomDisc and WB_RandomSphere.
- Marius Watz’ unlekkerLib provided the foundation for the wblut.hemesh.HE_Mesh.saveToSTL function.
- The Fortune’s sweep algorithm for 2D Voronoi is often discussed but rarely implemented. wblut.geom.WB_Voronoi2D is a bare-bones adaptation of Zhenyu Pan’s JAVA transcription of Shane O’Sullivan’s C implementation
- John Lloyd’s QuickHull3D package makes a reappearance as a convex hull generator for the wblut.hemesh.modifiers.HEM_Wireframe joints.
Not only code is scavenged without mercy, a whole range of reference material on algorithms is scoured:
- The über-reference Paul Bourke. Invaluable for many geometric algorithms, especially in HEC_IsoSurface.
- Christer Ericson’s Real-time Collision Detection for many of the geometric datastructures and intersection algorithms in wblut.geom.
- Code provided by Jon Squire served as the starting point for the basic platonic solid creators in wblut.hemesh.
- Scloopy‘s reference to a paper by Mandal and Esan proved just the thing I needed for wblut.hemesh.modifiers.HEM_Wireframe.
- A thousand page tome has added its burden to my desk: Geometric Tools for Computer Graphics by Philip Schneider and David Eberly. Its contents are increasingly implemented in HE_Mesh’s geometric backbone. If HE_Mesh turns out to be stable, this book deserves the praise. If not, it’s me that messed up somewhere…
- David Marec was so gracious to provide me with meticulously compiled vertex and connectitivity data for a whole host of polyhedra. Not only was the data flawless, it was also almost directly usable. A rare fortune indeed.
While HE_Mesh grows into different areas, these lists will undoubtedly expand. I just hope the need for proper bookkeeping won’t spoil the fun of coding…