de.jreality.geometry
Class ThickenedSurfaceFactory

java.lang.Object
  extended by de.jreality.geometry.ThickenedSurfaceFactory

public class ThickenedSurfaceFactory
extends Object

This factory class allows you to create a thickened surface from a given surface (given as an instance of IndexedFaceSet. The result is a closed surface with a well-defined interior and exterior.

The first step is that a copy of the surface is created by moving the original vertices along the vertex normal direction until they are a distance thickness from the original vertices. For convenience, call the origina surface the bottom surface and this new surface the top surface.

The second step is to find all edges which only appear once in the combinatorics of the indexed face set. These edges are assumed to be boundary edges; to each such edge a new quadrilateral is created which joins the edge to its translated image under step one. If face colors are provided for the original surface, then the face color of these new boundary faces is inherited from the unique face to which the boundary edge belongs.

The third step is to (optionally) generate holes in the thickened surface, one for each face of the original surface. To be exact, a hole are introduced into each face of the bottom surface and its corresponding face in the top surface. A tube is then constructed joining the two holes together. The tube is constructed as a product surface. Currently, any cross section of the tube parallel to the two faces is a scaled version of a special curve inscribed in this face; to be exact, it is a quadric curve tangent to the midpoints of the faces of the face. And the cross section of the tube by a plane passing through the center of the hole and perpendicular to the original face is determined by the profile curve parameter.

A typical invocation of an instance of this class looks like:

                surface = SphereUtility.tessellatedIcosahedronSphere(1); 
                tsf = new ThickenedSurfaceFactory(surface);             // constructor requires a surface
                tsf.setThickness(.1);                           // distance between top and bottom
                tsf.setMakeHoles(true);                         // boolean
                tsf.setHoleFactor(.5);                          // values smaller than one make the holes bigger
                tsf.setStepsPerEdge(6);                         // each original edge is replaced by 6 segments
                // profile curve describes the cross-section of the hole
                tsf.setProfileCurve(new double[][]{{0,0}, {.333,.5},{.666, .5},{1,0}});
                tsf.update();
                IndexedFaceSet thickSurface = tsf.getThickenedSurface();

 

Note: if the original surface is non-orientable surface, then the thickened version probably won't be closed (the "top" surface will be on both sides of the "bottom" surface). The factory doesn't attempt to check this.

Author:
Charles Gunn

Constructor Summary
ThickenedSurfaceFactory(IndexedFaceSet ifs)
           
 
Method Summary
static List<de.jreality.geometry.ThickenedSurfaceFactory.Pair> boundaryEdgesFromFaces(IntArrayArray faces)
           
 double getHoleFactor()
           
 double[][] getProfileCurve()
           
 double getShiftAlongNormal()
           
 int getSignature()
           
 int getStepsPerEdge()
           
 IndexedFaceSet getSurface()
           
 IndexedFaceSet getThickenedSurface()
          This returns the thickened surface.
 double getThickness()
           
 boolean isCurvedEdges()
           
 boolean isKeepFaceColors()
           
 boolean isLinearHole()
           
 boolean isMakeHoles()
           
 boolean isThickenAlongFaceNormals()
           
 void setCurvedEdges(boolean curvedEdges)
           
 void setHoleFactor(double holeFactor)
          This parameter is an additional parameter conrolling the size of the hole.
 void setKeepFaceColors(boolean keepFaceColors)
          Set this to true to retain the original face colors of the input surface in the thickened surface.
 void setLinearHole(boolean linearHole)
           
 void setMakeHoles(boolean makeHoles)
          Determines whether holes are generated in the thickened surface or not.
 void setProfileCurve(double[][] profileCurve)
          This set of number pairs controls the cross-section of the hole when I cut it with a plane passing through the center of the hole parallel to the normal direction of the original surface.
 void setShiftAlongNormal(double shiftAlongNormal)
           
 void setSignature(int signature)
          For working in non-euclidean geometries, set this.
 void setStepsPerEdge(int stepsPerEdge)
          The refinement of the geometry created to represent a hole is controlled by this parameter.
 void setThickenAlongFaceNormals(boolean thickedAlongFaceNormals)
           
 void setThickness(double thickness)
          This parameter controls how far apart the top and bottom surfaces are.
 void update()
          This has to be called after each set of edits to the state of the factory, in order to update the result.
 
Methods inherited from class java.lang.Object
equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Constructor Detail

ThickenedSurfaceFactory

public ThickenedSurfaceFactory(IndexedFaceSet ifs)
Method Detail

getSurface

public IndexedFaceSet getSurface()

isMakeHoles

public boolean isMakeHoles()

setMakeHoles

public void setMakeHoles(boolean makeHoles)
Determines whether holes are generated in the thickened surface or not. Default: false;

Parameters:
makeHoles -

getProfileCurve

public double[][] getProfileCurve()

setProfileCurve

public void setProfileCurve(double[][] profileCurve)
This set of number pairs controls the cross-section of the hole when I cut it with a plane passing through the center of the hole parallel to the normal direction of the original surface. to be precise, they are weights used with a bilinear interpolation scheme.

The first coordinate of each pair controls the mixture of the top and bottom surfaces and the second coordinate controls the mixture of the center point and the peripheral point (point on the original edge).

For example, the triple {{0,0},{.5,1},{1,0}} results in a profile curve that begins on the bottom surface (x = 0) at the original edge (y=0), moves to the middle between top and bottom (x = .5) at the center of the hole (y=1), and ends at the top surface (x = 0) at the original edge there (y = 0). examples.put("borromean ring",surface);

Parameters:
profileCurve -

getStepsPerEdge

public int getStepsPerEdge()

setStepsPerEdge

public void setStepsPerEdge(int stepsPerEdge)
The refinement of the geometry created to represent a hole is controlled by this parameter. Default: 3

Parameters:
stepsPerEdge -

getThickness

public double getThickness()

setThickness

public void setThickness(double thickness)
This parameter controls how far apart the top and bottom surfaces are.

Parameters:
thickness -

getHoleFactor

public double getHoleFactor()

setHoleFactor

public void setHoleFactor(double holeFactor)
This parameter is an additional parameter conrolling the size of the hole. It basically is used as a scale factor on the y-coordinate of the profile curve; larger values make the hole smaller, while smaller ones make the whole bigger. Negative values are discouraged. Default: 1.0

Parameters:
holeFactor -

isKeepFaceColors

public boolean isKeepFaceColors()

getSignature

public int getSignature()

setSignature

public void setSignature(int signature)
For working in non-euclidean geometries, set this. Default: Pn.EUCLIDEAN. Warning: currently ignored.

Parameters:
signature -

setKeepFaceColors

public void setKeepFaceColors(boolean keepFaceColors)
Set this to true to retain the original face colors of the input surface in the thickened surface.

Parameters:
keepFaceColors -

isCurvedEdges

public boolean isCurvedEdges()

setCurvedEdges

public void setCurvedEdges(boolean curvedEdges)

isLinearHole

public boolean isLinearHole()

setLinearHole

public void setLinearHole(boolean linearHole)

getShiftAlongNormal

public double getShiftAlongNormal()

setShiftAlongNormal

public void setShiftAlongNormal(double shiftAlongNormal)

isThickenAlongFaceNormals

public boolean isThickenAlongFaceNormals()

setThickenAlongFaceNormals

public void setThickenAlongFaceNormals(boolean thickedAlongFaceNormals)

getThickenedSurface

public IndexedFaceSet getThickenedSurface()
This returns the thickened surface. This remains the same for the life of the factory.

Returns:

update

public void update()
This has to be called after each set of edits to the state of the factory, in order to update the result.


boundaryEdgesFromFaces

public static List<de.jreality.geometry.ThickenedSurfaceFactory.Pair> boundaryEdgesFromFaces(IntArrayArray faces)