Signing Processing applets
Robustness of geometric algorithms is a prime concern in my hemesh library. It is surprising how fast the intricacies of floating-point calculations crop up and render your code fickle and buggy. It’s easy to forget that computer math is not the same as regular math. Rather, it is a discrete limited-domain simulation of real mathematics.
I’m currently adding some new plumbing to hemesh using an arbitrary precision library, Apfloat. because it’s a lot slower it is only called when necessary. Including it had an unexpected side-effect. Apfloat requires information about your system when it’s running in a browser. It needs your machine’s inherent precision.
However, accessing your computer is a big no-no for my code. So unless the applets are signed, they won’t run because of security restrictions. In itself, this is not really a problem, we can still share code and show each other images. But I’d rather keep sharing applets, these always include the correct libraries and often rely on unreleased alpha-level modifications of my library.
I can’t claim a proper understanding of Java security issues and all details about signing. But I’ve been looking around and gathered masses of raw data, info-ore. I’ve smelted it down to an ingot of usefulness. In short, this is how you sign a Processing applet without knowing what you’re doing. On a Windows machine… (don’t be too disappointed, the essentials are the same on hipster machines.)
Preparations
1) First locate your Java Development Kit (JDK) distribution. If you’re using Eclipse, or program in JAVA, you probably have one around somewhere. If not, Processing has it included in its \java subdirectory. Check out the contents of the \bin folder. See all those executables, we’ll be using a few of those. Let’s say you traced your JDK to c:\processing\java. So anywhere the text mentions c:\processing\java\bin substitute this with your own location.
2) Include the \bin subdirectory in your system’s PATH. Check this if you aren’t sure how, of course use c:\processing\java\bin instead of the Matlab example. This’ll save you a lot of typing. The executables in the bin folder can now be called from any directory.
3) Create a folder to store your keystore, the repository for your certificates. I’ll be using c:\keystore.
Creating your certificate
4) Open up a command prompt (press windows+r, type cmd). If you set up the PATH properly, you can access the commands we’ll be using anywhere. Otherwise you’ll have to call them with their full path… We’ll create a keystore and a first certificate mykey now. Since our keys will be self-certified only (i.e. no certifying agency will vouch for your good intentions), we’ll give them a validity of 100 years. That should be enough…
keytool -genkey -keystore c:\keystore\mykeystore.jks -alias mykey -validity 36500
Since this is the first time the keystore is accessed, you’ll need to input some important info. Just choose a decent keystore password (let’s say passw0rd ;) ) and fill in the rest. After filling in your data, keytool will ask for the key password. You can keep this the same as the keystore password, just enter and finish. You now have a keystore with a single certificate mykey in it.
5) Now we’ll make the certificate self-certified. It’s up to the end-user whether or not he’ll trust your applet.
keytool -selfcert -keystore c:\keystore\mykeystore.jks -alias mykey
Signing your applet
6) I now have an applet I want to share and that requires signing:c:\sketchbook\condel. First export the applet. The /applet subdirectory now contains all Java archives (JAR) associated with your sketch. We’ll need to sign all of them, even if only one requires authentication.
7) Re-open the command window if necessary and navigate to c:\sketchbook\condel\applet. For every JAR run this:
jarsigner -keystore c:\keystore\mykeystore.jks -storepass passw0rd -keypass passw0rd core.jar mykey
In my case, I have core.jar, hemesh.jar, apfloat.jar and several others I’ll need to sign.
8) Done! You can upload the applet. If somebody accesses the page she will be given the choice of trusting the applet. If yes, then the applet will run. If no, then it won’t.… I’ve created condel this way.
Snippets VII: 2D boolean
Another demo of the wblut.geom and wblut.geom2d packages included with hemesh. Meshes are generated by the intersection of two stars.
Hemesh : a 3D mesh library for Processing
UPDATE : He_Mesh has grown enough to give it its own site: http://hemesh.wblut.com/. In time, the new site will contain tutorials and in-depth explanations.
Coded, recoded, lost, recoded and recoded … hemesh, 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 at least it holds potential for growth.
What is hemesh?
hemesh 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 hemesh do?
The library is currently focused on the stuff I coded it for: 3D voronoi and random plane divisions. So with hemesh we can create 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 hemesh 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 hemesh 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…
Getting hemesh
The library is maintained at code.google.com. hemesh is currently at beta version 1.1.01.3.0 Download and extract the archive inside the Processing ‘libraries’ folder. The ‘hemesh’ subfolder contains several examples. A Processing version supporting JAVA 1.5 syntax is recommended, Rev 180 or higher. In the coming days, I’ll post some tutorials and spielerei to illustrate further use.
Future
At this time, the library reflects my current interests. If you want it to do something else, have a suggestion or hemesh goes haywire on you, let me know! One major addition is already planned: boolean mesh operations. This is a small step away from completion.
import processing.opengl.*;
import wblut.hemesh.*;
import wblut.geom.*;
HE_Mesh box;
void setup(){
size(600,600,OPENGL);
hint(ENABLE_OPENGL_4X_SMOOTH);
HEC_Box boxCreator=new HEC_Box(this)
.setWidth(400).setWidthSegments(10)
.setHeight(200).setHeightSegments(4)
.setDepth(200).setDepthSegments(4);
boxCreator.setCenter(100,100,0).setAxis(1,1,1);
box=new HE_Mesh(boxCreator);
HEM_Lattice lattice=new HEM_Lattice().setDepth(10)
.setWidth(10).setFuse(true).setThresholdAngle(HALF_PI);
box.modify(lattice)
}
void draw(){
background(120);
lights();
translate(300,300,0);
rotateY(mouseX*1.0f/width*TWO_PI);
rotateX(mouseY*1.0f/height*TWO_PI);
noStroke();
box.drawFaces();
stroke(0);
box.drawEdges();
}











