Search code examples
opengljava-3dlightingnormals

Java3d - Bad Normals using GeometryInfo


I'm working with Java3d under eclipse Indigo in windows. After finally modifying the StlLoader example and ObjLoad classes to get my STL files to load up, I get a result that looks like the below (I think from other questions these are definitely bad vector normals). Does anybody know why I might be having this problem? I am using SolidWorks to save the STL as an ASCII file and using a modification of the code for loading STL files given on java3d.org. Although I have only changed some appearance properties and fixed broken imports etc. I have confirmed that the facet normals put into "normList" below definitely match those from the file.

Example of Result:

enter image description here

Snippet of StlFile.java from http://www.java3d.org :

private SceneBase makeScene()
{
// Create Scene to pass back
SceneBase scene = new SceneBase();
BranchGroup group = new BranchGroup();
scene.setSceneGroup(group);

// Store the scene info on a GeometryInfo
GeometryInfo gi = new GeometryInfo(GeometryInfo.TRIANGLE_STRIP_ARRAY);

// Convert ArrayLists to arrays: only needed if file was not binary
if(this.Ascii)
{
  coordArray = objectToPoint3Array(coordList);
  normArray = objectToVectorArray(normList);
}

gi.setCoordinates(coordArray);
gi.setNormals(normArray);
gi.setStripCounts(stripCounts);

// Setting the Material Appearance
Appearance app = new Appearance();

// Coloring Attributes
ColoringAttributes catt = new ColoringAttributes();
catt.setShadeModel( ColoringAttributes.NICEST );
app.setColoringAttributes(catt);

Material mat = new Material(new Color3f(0.6f, 0.6f, 0.6f),      // ambient
                            new Color3f(0, 0, 0),               // emissive
                            new Color3f(0.6f, 0.6f, 0.6f),      // diffuse
                            new Color3f(0.6f, 0.6f, 0.6f),      // specular
                            10);                                // shininess
app.setMaterial(mat);

// Put geometry into Shape3d
Shape3D shape = new Shape3D(gi.getGeometryArray(), app);

group.addChild(shape);
scene.addNamedObject(objectName, shape);

return scene;
} // end of makeScene

Solution

  • If some areas on the surface are really black (0x000000), I would guess some of the normals are actually pointing inwards the model rather than to the outside.

    You may check if vertices v1,v2,v3 for all the triangles are defined in right-hand order (just test if det(v1,v2,v3) > 0 ) and reorder points accordingly. Alternatively, detect the "opposite" normals and multiply them by -1