jogamp.graph.curve.tess.CDTriangulator2D Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jogl-all Show documentation
Show all versions of jogl-all Show documentation
Java™ Binding for the OpenGL® API
/**
* Copyright 2010 JogAmp Community. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY JogAmp Community ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JogAmp Community OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of JogAmp Community.
*/
package jogamp.graph.curve.tess;
import java.util.ArrayList;
import com.jogamp.graph.curve.tess.Triangulator;
import com.jogamp.graph.geom.Outline;
import com.jogamp.graph.geom.Triangle;
import com.jogamp.graph.geom.Vertex;
import com.jogamp.opengl.math.VectorUtil;
import jogamp.opengl.Debug;
/** Constrained Delaunay Triangulation
* implementation of a list of Outlines that define a set of
* Closed Regions with optional n holes.
*
*/
public class CDTriangulator2D implements Triangulator{
protected static final boolean DEBUG = Debug.debug("Triangulation");
private float sharpness = 0.5f;
private ArrayList loops;
private ArrayList vertices;
private ArrayList triangles;
private int maxTriID = 0;
/** Constructor for a new Delaunay triangulator
*/
public CDTriangulator2D() {
reset();
}
/** Reset the triangulation to initial state
* Clearing cached data
*/
public void reset() {
maxTriID = 0;
vertices = new ArrayList();
triangles = new ArrayList(3);
loops = new ArrayList();
}
public void addCurve(Outline polyline) {
Loop loop = null;
if(!loops.isEmpty()) {
loop = getContainerLoop(polyline);
}
if(loop == null) {
GraphOutline outline = new GraphOutline(polyline);
GraphOutline innerPoly = extractBoundaryTriangles(outline, false);
vertices.addAll(polyline.getVertices());
loop = new Loop(innerPoly, VectorUtil.Winding.CCW);
loops.add(loop);
} else {
GraphOutline outline = new GraphOutline(polyline);
GraphOutline innerPoly = extractBoundaryTriangles(outline, true);
vertices.addAll(innerPoly.getVertices());
loop.addConstraintCurve(innerPoly);
}
}
public ArrayList generate() {
for(int i=0;i size){
tri = loop.cut(false);
}
else{
tri = loop.cut(true);
}
numTries++;
if(tri != null) {
numTries = 0;
size--;
tri.setId(maxTriID++);
triangles.add(tri);
if(DEBUG){
System.err.println(tri);
}
}
if(numTries > size*2){
if(DEBUG){
System.err.println("Triangulation not complete!");
}
break;
}
}
Triangle tri = loop.cut(true);
if(tri != null)
triangles.add(tri);
}
return triangles;
}
private GraphOutline extractBoundaryTriangles(GraphOutline outline, boolean hole) {
GraphOutline innerOutline = new GraphOutline();
ArrayList outVertices = outline.getGraphPoint();
int size = outVertices.size();
for(int i=0; i < size; i++) {
GraphVertex currentVertex = outVertices.get(i);
GraphVertex gv0 = outVertices.get((i+size-1)%size);
GraphVertex gv2 = outVertices.get((i+1)%size);
GraphVertex gv1 = currentVertex;
if(!currentVertex.getPoint().isOnCurve()) {
Vertex v0 = gv0.getPoint().clone();
Vertex v2 = gv2.getPoint().clone();
Vertex v1 = gv1.getPoint().clone();
gv0.setBoundaryContained(true);
gv1.setBoundaryContained(true);
gv2.setBoundaryContained(true);
final Triangle t;
final boolean holeLike;
if(VectorUtil.ccw(v0,v1,v2)) {
holeLike = false;
t = new Triangle(v0, v1, v2);
} else {
holeLike = true;
t = new Triangle(v2, v1, v0);
}
t.setId(maxTriID++);
triangles.add(t);
if(DEBUG){
System.err.println(t);
}
if( hole || holeLike ) {
v0.setTexCoord(0, -0.1f);
v2.setTexCoord(1, -0.1f);
v1.setTexCoord(0.5f, -1*sharpness -0.1f);
innerOutline.addVertex(currentVertex);
} else {
v0.setTexCoord(0, 0.1f);
v2.setTexCoord(1, 0.1f);
v1.setTexCoord(0.5f, sharpness+0.1f);
}
}
else {
if(!gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve()){
currentVertex.setBoundaryContained(true);
}
innerOutline.addVertex(currentVertex);
}
}
return innerOutline;
}
private Loop getContainerLoop(Outline polyline) {
ArrayList vertices = polyline.getVertices();
for(int i=0; i < loops.size(); i++) {
Loop loop = loops.get(i);
boolean inside = false;
for(int j=0; j < vertices.size(); j++) {
Vertex v = vertices.get(j);
inside |= loop.checkInside(v);
}
if(inside) {
return loop;
}
}
return null;
}
}