diff options
author | Sven Gothel <[email protected]> | 2014-03-22 06:23:50 +0100 |
---|---|---|
committer | Sven Gothel <[email protected]> | 2014-03-22 06:23:50 +0100 |
commit | b4817d053d7af20dae33774e430bf79a3d3c6fcd (patch) | |
tree | 1e7cd3d713e3c1f8442f00be8d161a63de34f601 /src/jogl/classes/jogamp/graph/curve/tess | |
parent | 523d1dae2431fdd56d39d3ea06220cfed412a0b5 (diff) |
Bug 801: Revise Graph VBAA (Add border dropping MSAA; Test diff. AA modes incl. FXAA2) ; Test exp. LineAA ; Misc Changes
- Revise VBAA
- Add border to FBO dropping MSAA
- This automatically gives AA for edges on FBO boundary
- Correcting ceil-diff, use object-diff instead of win-diff (diff := ceil(a)-a, w/ float a)
- Reorg shader - using includes to test diff. AA modes:
- [poles, wholeedge] * [equalweight, propweight]
- fxaa2
- Exp. LineAA (disabled)
- Test ROESSLER-2012-OGLES for detected rectangles only
- Test boundary line detection
See screenshots: <http://jogamp.org/files/screenshots/graphui/20140322/>
Diffstat (limited to 'src/jogl/classes/jogamp/graph/curve/tess')
4 files changed, 412 insertions, 45 deletions
diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java index 35263407d..ad01c24fa 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2D.java @@ -39,14 +39,18 @@ import com.jogamp.opengl.math.VectorUtil; import jogamp.opengl.Debug; -/** Constrained Delaunay Triangulation +/** + * 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"); + protected static final boolean DEBUG = Debug.debug("graph.curve.Triangulation"); + + private static final boolean TEST_LINE_AA = Debug.debug("graph.curve.triangulation.LINE_AA"); + private static final boolean TEST_MARK_LINE = Debug.debug("graph.curve.triangulation.MARK_AA"); + private static final boolean TEST_ENABLED = TEST_LINE_AA || TEST_MARK_LINE; private final ArrayList<Loop> loops = new ArrayList<Loop>(); @@ -89,7 +93,8 @@ public class CDTriangulator2D implements Triangulator { @Override public final void generate(List<Triangle> sink) { - for(int i=0;i<loops.size();i++) { + final int loopsSize = loops.size(); + for(int i=0;i<loopsSize;i++) { final Loop loop = loops.get(i); int numTries = 0; int size = loop.computeLoopSize(); @@ -109,12 +114,12 @@ public class CDTriangulator2D implements Triangulator { tri.setId(maxTriID++); sink.add(tri); if(DEBUG){ - System.err.println(tri); + System.err.println("CDTri.gen["+i+"].0: "+tri); } } if(numTries > size*2){ if(DEBUG){ - System.err.println("Triangulation not complete!"); + System.err.println("CDTri.gen["+i+"].X: Triangulation not complete!"); } break; } @@ -122,6 +127,26 @@ public class CDTriangulator2D implements Triangulator { final Triangle tri = loop.cut(true); if(tri != null) { sink.add(tri); + if(DEBUG){ + System.err.println("CDTri.gen["+i+"].1: "+tri); + } + } + } + if( TEST_ENABLED ) { + final float[] tempV2 = new float[2]; + final CDTriangulator2DExpAddOn addOn = new CDTriangulator2DExpAddOn(); + final int sinkSize = sink.size(); + if( TEST_MARK_LINE ) { + for(int i=0; i<sinkSize; i++) { + final Triangle t0 = sink.get(i); + addOn.markLineInTriangle(t0, tempV2); + } + } else if ( TEST_LINE_AA ){ + for(int i=0; i<sinkSize-1; i+=2) { + final Triangle t0 = sink.get(i); + final Triangle t1 = sink.get(i+1); + /* final float[] rect = */ addOn.processLineAA(i, t0, t1, tempV2); + } } } } @@ -131,15 +156,15 @@ public class CDTriangulator2D implements Triangulator { final ArrayList<GraphVertex> outVertices = outline.getGraphPoint(); final int size = outVertices.size(); for(int i=0; i < size; i++) { - final GraphVertex currentVertex = outVertices.get(i); - final GraphVertex gv0 = outVertices.get((i+size-1)%size); - final GraphVertex gv2 = outVertices.get((i+1)%size); - final GraphVertex gv1 = currentVertex; + final GraphVertex gv1 = outVertices.get(i); // currentVertex + final GraphVertex gv0 = outVertices.get((i+size-1)%size); // -1 + final GraphVertex gv2 = outVertices.get((i+1)%size); // +1 - if( !currentVertex.getPoint().isOnCurve() ) { + if( !gv1.getPoint().isOnCurve() ) { final Vertex v0 = gv0.getPoint().clone(); final Vertex v2 = gv2.getPoint().clone(); final Vertex v1 = gv1.getPoint().clone(); + final boolean[] boundaryVertices = { true, true, true }; gv0.setBoundaryContained(true); gv1.setBoundaryContained(true); @@ -149,10 +174,10 @@ public class CDTriangulator2D implements Triangulator { final boolean holeLike; if(VectorUtil.ccw(v0,v1,v2)) { holeLike = false; - t = new Triangle(v0, v1, v2); + t = new Triangle(v0, v1, v2, boundaryVertices); } else { holeLike = true; - t = new Triangle(v2, v1, v0); + t = new Triangle(v2, v1, v0, boundaryVertices); } t.setId(maxTriID++); sink.add(t); @@ -160,20 +185,26 @@ public class CDTriangulator2D implements Triangulator { 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); + v0.setTexCoord(0.0f, -0.1f, 0f); + v2.setTexCoord(1.0f, -0.1f, 0f); + v1.setTexCoord(0.5f, -sharpness-0.1f, 0f); + innerOutline.addVertex(gv1); } else { - v0.setTexCoord(0, 0.1f); - v2.setTexCoord(1, 0.1f); - v1.setTexCoord(0.5f, sharpness+0.1f); + v0.setTexCoord(0.0f, 0.1f, 0f); + v2.setTexCoord(1.0f, 0.1f, 0f); + v1.setTexCoord(0.5f, sharpness+0.1f, 0f); + } + if(DEBUG) { + System.err.println("CDTri.ebt["+i+"].0: hole "+(hole || holeLike)+" "+gv1+", "+t); } } else { if( !gv2.getPoint().isOnCurve() || !gv0.getPoint().isOnCurve() ) { - currentVertex.setBoundaryContained(true); + gv1.setBoundaryContained(true); + } + innerOutline.addVertex(gv1); + if(DEBUG) { + System.err.println("CDTri.ebt["+i+"].1: "+gv1); } - innerOutline.addVertex(currentVertex); } } return innerOutline; diff --git a/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2DExpAddOn.java b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2DExpAddOn.java new file mode 100644 index 000000000..2ada436f8 --- /dev/null +++ b/src/jogl/classes/jogamp/graph/curve/tess/CDTriangulator2DExpAddOn.java @@ -0,0 +1,340 @@ +/** + * Copyright 2014 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 com.jogamp.graph.geom.Triangle; +import com.jogamp.graph.geom.Vertex; +import com.jogamp.opengl.math.FloatUtil; +import com.jogamp.opengl.math.VectorUtil; + +/** + * Experimental Add-On .. + * + * Disabled by default + */ +public class CDTriangulator2DExpAddOn { + + private final float[] tempV3a = new float[3]; + private final float[] tempV3b = new float[3]; + + protected final void markLineInTriangle(final Triangle tri1, final float[] tempV2) { + if( !tri1.isOnCurve() || !tri1.isLine() ) { + return; + } + + final boolean[] boundVs = tri1.getVerticesBoundary(); + final Vertex[] triVs = tri1.getVertices(); + final Vertex v0 = triVs[0]; + final Vertex v1 = triVs[1]; + final Vertex v2 = triVs[2]; + + int lineSegCount = 0; + final boolean v0IsLS, v1IsLS, v2IsLS; + if( v0.isOnCurve() && VectorUtil.isVec2Zero(v0.getTexCoord(), 0) && !boundVs[0] ) { + v0IsLS = true; + lineSegCount++; + } else { + v0IsLS = false; + } + if( v1.isOnCurve() && VectorUtil.isVec2Zero(v1.getTexCoord(), 0) && !boundVs[1] ) { + v1IsLS = true; + lineSegCount++; + } else { + v1IsLS = false; + } + if( v2.isOnCurve() && VectorUtil.isVec2Zero(v2.getTexCoord(), 0) && !boundVs[2] ) { + v2IsLS = true; + lineSegCount++; + } else { + v2IsLS = false; + } + if( 2 > lineSegCount ) { + return; + } else { + if(CDTriangulator2D.DEBUG) { + System.err.println("CDTri.markLine.1: "+tri1); + System.err.println("CDTri.markLine.1: count "+lineSegCount+", v0IsLS "+v0IsLS+", v1IsLS "+v1IsLS+", v2IsLS "+v2IsLS); + } + final float texZTag = 2f; + if( true ) { + if( v0IsLS ) { + v0.setTexCoord(0f, 0f, texZTag); + } + if( v1IsLS ) { + v1.setTexCoord(0f, 0f, texZTag); + } + if( v2IsLS ) { + v2.setTexCoord(0f, 0f, texZTag); + } + } else { + if( v0IsLS ) { + final Vertex v = v0.clone(); + v.setTexCoord(0f, 0f, texZTag); + triVs[0] = v; + } + if( v1IsLS ) { + final Vertex v = v1.clone(); + v.setTexCoord(0f, 0f, texZTag); + triVs[1] = v; + } + if( v2IsLS ) { + final Vertex v = v2.clone(); + v.setTexCoord(0f, 0f, texZTag); + triVs[2] = v; + } + } + if ( false ) { + final Vertex vL1, vL2, vL3, vO; + if( 3 == lineSegCount ) { + vL1 = v0; vL2=v1; vL3=v2; vO=null; + } else if( v0IsLS && v1IsLS ) { + vL1 = v0; vL2=v1; vL3=null; vO=v2; + } else if( v0IsLS && v2IsLS ) { + vL1 = v0; vL2=v2; vL3=null; vO=v1; + } else if( v1IsLS && v2IsLS ) { + vL1 = v1; vL2=v2; vL3=null; vO=v0; + } else { + return; // unreachable + } + if( null != vL1 ) { + vL1.setTexCoord(texZTag, 0f, 0f); + } + if( null != vL2 ) { + vL2.setTexCoord(texZTag, 0f, 0f); + } + if( null != vL3 ) { + vL3.setTexCoord(texZTag, 0f, 0f); + } + } + } + } + + /** + * If this and the other triangle compose a rectangle return the + * given <code>tempV2</code> array w/ shortest side first. + * Otherwise return null; + * <p> + * Experimental CODE, enabled only if {@link #TEST_LINE_AA} is set .. WIP + * </p> + * <p> + One test uses method: ROESSLER-2012-OGLES <http://www.cg.tuwien.ac.at/research/publications/2012/ROESSLER-2012-OGLES/> + * </p> + * <p> + * However, we would need to tesselate all lines appropriately, + * i.e. create 2 triangles sharing the middle actual line using thickness+radius. + * + * This test simply used our default font w/ a line thickness of 2 pixels, + * which produced mentioned rectangles. + * This is of course not the case for arbitrary Outline shapes. + * </p> + * @param tri2 + * @param checkThisOnCurve + * @param tempV2 temp float[2] storage + */ + protected final float[] processLineAA(final int i, final Triangle tri1, final Triangle tri2, final float[] tempV2) { + if(CDTriangulator2D.DEBUG){ + System.err.println("CDTri.genP2["+i+"].1: ? t1 "+tri1); + System.err.println("CDTri.genP2["+i+"].1: ? t2 "+tri2); + } + final float[] rect = processLineAAImpl(tri1, tri2, tempV2); + if(CDTriangulator2D.DEBUG){ + if( null != rect ) { + System.err.println("CDTri.genP2["+i+"].1: RECT ["+rect[0]+", "+rect[1]+"]"); + System.err.println("CDTri.genP2["+i+"].1: RECT t1 "+tri1); + System.err.println("CDTri.genP2["+i+"].1: RECT t2 "+tri2); + } else { + System.err.println("CDTri.genP2["+i+"].1: RECT NOPE, t1 "+tri1); + System.err.println("CDTri.genP2["+i+"].1: RECT NOPE, t2 "+tri2); + } + } + return rect; + } + private final float[] processLineAAImpl(final Triangle tri1, final Triangle tri2, final float[] tempV2) { + if( !tri1.isOnCurve() || !tri2.isOnCurve() || !tri1.isLine() || !tri2.isLine() ) { + return null; + } + final float[] rect; + int eqCount = 0; + final int[] commonIdxA = { -1, -1 }; + final int[] commonIdxB = { -1, -1 }; + final Vertex[] verts1 = tri1.getVertices(); + final Vertex[] verts2 = tri2.getVertices(); + float[] coord = verts1[0].getCoord(); + if( VectorUtil.isVec3Equal(coord, 0, verts2[0].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 0; + commonIdxB[eqCount] = 0; + eqCount++; + } else if( VectorUtil.isVec3Equal(coord, 0, verts2[1].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 0; + commonIdxB[eqCount] = 1; + eqCount++; + } else if( VectorUtil.isVec3Equal(coord, 0, verts2[2].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 0; + commonIdxB[eqCount] = 2; + eqCount++; + } + coord = verts1[1].getCoord(); + if( VectorUtil.isVec3Equal(coord, 0, verts2[0].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 1; + commonIdxB[eqCount] = 0; + eqCount++; + } else if( VectorUtil.isVec3Equal(coord, 0, verts2[1].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 1; + commonIdxB[eqCount] = 1; + eqCount++; + } else if( VectorUtil.isVec3Equal(coord, 0, verts2[2].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 1; + commonIdxB[eqCount] = 2; + eqCount++; + } + final int otherIdxA; + if( 2 == eqCount ) { + otherIdxA = 3 - ( commonIdxA[0] + commonIdxA[1] ); + } else { + coord = verts1[2].getCoord(); + if( VectorUtil.isVec3Equal(coord, 0, verts2[0].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 2; + commonIdxB[eqCount] = 0; + eqCount++; + } else if( VectorUtil.isVec3Equal(coord, 0, verts2[1].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 2; + commonIdxB[eqCount] = 1; + eqCount++; + } else if( VectorUtil.isVec3Equal(coord, 0, verts2[2].getCoord(), 0, FloatUtil.EPSILON) ) { + commonIdxA[eqCount] = 2; + commonIdxB[eqCount] = 2; + eqCount++; + } + if( 2 == eqCount ) { + otherIdxA = 3 - ( commonIdxA[0] + commonIdxA[1] ); + } else { + otherIdxA = -1; + } + } + if( 0 <= otherIdxA && commonIdxB[0] != commonIdxB[1] ) { + final int otherIdxB = 3 - ( commonIdxB[0] + commonIdxB[1] ); + // Reference must be equal, i.e. sharing the actual same vertices! + if( verts1[commonIdxA[0]] != verts2[commonIdxB[0]] || verts1[commonIdxA[1]] != verts2[commonIdxB[1]] ) { + throw new InternalError("XXX: diff shared verts"); // FIXME remove when clear + } + final Vertex vC0A, vC1A, vOA, vOB; + if( false ) { + // Fetch only! + vC0A = verts1[commonIdxA[0]]; + vC1A = verts1[commonIdxA[1]]; + vOA = verts1[otherIdxA]; + vOB = verts2[otherIdxB]; + } else { + // Fetch and clone, write-back to triangles + vC0A = verts1[commonIdxA[0]].clone(); + verts1[commonIdxA[0]] = vC0A; + verts2[commonIdxB[0]] = vC0A; + vC1A = verts1[commonIdxA[1]].clone(); + verts1[commonIdxA[1]] = vC1A; + verts2[commonIdxB[1]] = vC1A; + vOA = verts1[otherIdxA].clone(); + verts1[otherIdxA] = vOA; + vOB = verts2[otherIdxB].clone(); + verts2[otherIdxB] = vOB; + } + + final float texZTag = 2f; + final float[] vOACoords = vOA.getCoord(); + final float dOC0A = VectorUtil.vec3Distance(vOACoords, vC0A.getCoord()); + final float dOC1A = VectorUtil.vec3Distance(vOACoords, vC1A.getCoord()); + if( false ) { + final float[] vec3Z = { 0f, 0f, -1f }; + final float[] vecLongSide, vecLineHeight; + if( dOC0A < dOC1A ) { + tempV2[0] = dOC0A; // line width + tempV2[1] = dOC1A; // long side + vecLongSide = VectorUtil.normalizeVec3( VectorUtil.subVec2(tempV3a, vOACoords, vC1A.getCoord()) ); // normal long side vector + vecLineHeight = VectorUtil.crossVec3(tempV3b, vec3Z, tempV3a); // the line-height vector (normal) + vOA.setTexCoord(-1f, -1f, texZTag); + vC1A.setTexCoord(1f, -1f, texZTag); + vOB.setTexCoord(0f, 1f, texZTag); + vC0A.setTexCoord(0f, 1f, texZTag); + } else { + tempV2[0] = dOC1A; // line width + tempV2[1] = dOC0A; // long side + vecLongSide = VectorUtil.normalizeVec3( VectorUtil.subVec2(tempV3a, vOACoords, vC0A.getCoord()) ); // normal long side vector + vecLineHeight = VectorUtil.crossVec3(tempV3b, vec3Z, tempV3a); // the line-height vector (normal) + } + if(CDTriangulator2D.DEBUG){ + System.err.println("RECT.0 : long-side-vec "+vecLongSide[0]+", "+vecLongSide[1]+", "+vecLongSide[2]); + System.err.println("RECT.0 : line-height-vec "+vecLineHeight[0]+", "+vecLineHeight[1]+", "+vecLineHeight[2]); + } + + } else { + /** + * Using method: ROESSLER-2012-OGLES <http://www.cg.tuwien.ac.at/research/publications/2012/ROESSLER-2012-OGLES/> + * + * Arbitrary but consistently pick left/right and set texCoords, FIXME: validate + * + * Testing w/ fixed line-width 1, and radius 1/3. + */ + final float lineWidth; + final Vertex vL1, vL2, vR1, vR2; + if( dOC0A < dOC1A ) { + lineWidth = dOC0A; // line width + tempV2[0] = dOC0A; // line width + tempV2[1] = dOC1A; // long side + // Left: vOA, vC1A + // Right: vOB, vC0A + vL1 = vOA; vL2 = vC1A; + vR1 = vOB; vR2 = vC0A; + } else { + lineWidth = dOC1A; // line width + tempV2[0] = dOC1A; // line width + tempV2[1] = dOC0A; // long side + // Left: vOB, vC1A + // Right: vOA, vC0A + vL1 = vOB; vL2 = vC1A; + vR1 = vOA; vR2 = vC0A; + } + final float r = lineWidth/3f; + final float wa = lineWidth + r; + final float waHalf = wa / 2f; + vL1.setTexCoord(lineWidth, waHalf, texZTag); + vL2.setTexCoord(lineWidth, waHalf, texZTag); + vR1.setTexCoord(lineWidth, -waHalf, texZTag); + vR2.setTexCoord(lineWidth, -waHalf, texZTag); + if(CDTriangulator2D.DEBUG){ + System.err.println("RECT.0 : lineWidth: "+lineWidth+", dim "+dOC0A+" x "+dOC1A+", radius "+r); + System.err.println("RECT Left.0: "+vL1+", "+vL2); + System.err.println("RECT Right.0: "+vR1+", "+vR2); + } + } + rect = tempV2; + } else { + rect = null; + } + return rect; + } +} diff --git a/src/jogl/classes/jogamp/graph/curve/tess/GraphVertex.java b/src/jogl/classes/jogamp/graph/curve/tess/GraphVertex.java index 1ef1d8c7f..89ad3edf1 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/GraphVertex.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/GraphVertex.java @@ -120,4 +120,8 @@ public class GraphVertex { public void setBoundaryContained(boolean boundaryContained) { this.boundaryContained = boundaryContained; } + + public String toString() { + return "GraphVertex[contained "+boundaryContained+", "+point+"]"; + } } diff --git a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java index f96726e5b..f91c2e77f 100644 --- a/src/jogl/classes/jogamp/graph/curve/tess/Loop.java +++ b/src/jogl/classes/jogamp/graph/curve/tess/Loop.java @@ -49,25 +49,23 @@ public class Loop { return root; } - public Triangle cut(boolean delaunay){ + public Triangle cut(final boolean delaunay){ if(isSimplex()){ - Triangle t = new Triangle(root.getGraphPoint().getPoint(), root.getNext().getGraphPoint().getPoint(), - root.getNext().getNext().getGraphPoint().getPoint()); - t.setVerticesBoundary(checkVerticesBoundary(root)); - return t; + return new Triangle(root.getGraphPoint().getPoint(), root.getNext().getGraphPoint().getPoint(), + root.getNext().getNext().getGraphPoint().getPoint(), checkVerticesBoundary(root)); } - HEdge prev = root.getPrev(); - HEdge next1 = root.getNext(); + final HEdge prev = root.getPrev(); + final HEdge next1 = root.getNext(); - HEdge next2 = findClosestValidNeighbor(next1.getNext(), delaunay); + final HEdge next2 = findClosestValidNeighbor(next1.getNext(), delaunay); if(next2 == null){ root = root.getNext(); return null; } - GraphVertex v1 = root.getGraphPoint(); - GraphVertex v2 = next1.getGraphPoint(); - GraphVertex v3 = next2.getGraphPoint(); + final GraphVertex v1 = root.getGraphPoint(); + final GraphVertex v2 = next1.getGraphPoint(); + final GraphVertex v3 = next2.getGraphPoint(); HEdge v3Edge = new HEdge(v3, HEdge.INNER); @@ -83,7 +81,7 @@ public class Loop { HEdge.connect(prev, v3EdgeSib); HEdge.connect(v3EdgeSib, next2); - Triangle t = createTriangle(v1.getPoint(), v2.getPoint(), v3.getPoint(), root); + final Triangle t = createTriangle(v1.getPoint(), v2.getPoint(), v3.getPoint(), root); this.root = next2; return t; } @@ -272,24 +270,18 @@ public class Loop { * @return the triangle iff it satisfies, null otherwise */ private Triangle createTriangle(Vertex v1, Vertex v2, Vertex v3, HEdge rootT){ - final Triangle t = new Triangle(v1, v2, v3); - t.setVerticesBoundary(checkVerticesBoundary(rootT)); - return t; + return new Triangle(v1, v2, v3, checkVerticesBoundary(rootT)); } - private boolean[] checkVerticesBoundary(HEdge rootT) { + private boolean[] checkVerticesBoundary(final HEdge rootT) { final boolean[] boundary = new boolean[3]; - HEdge e1 = rootT; - HEdge e2 = rootT.getNext(); - HEdge e3 = rootT.getNext().getNext(); - - if(e1.getGraphPoint().isBoundaryContained()){ + if(rootT.getGraphPoint().isBoundaryContained()){ boundary[0] = true; } - if(e2.getGraphPoint().isBoundaryContained()){ + if(rootT.getNext().getGraphPoint().isBoundaryContained()){ boundary[1] = true; } - if(e3.getGraphPoint().isBoundaryContained()){ + if(rootT.getNext().getNext().getGraphPoint().isBoundaryContained()){ boundary[2] = true; } return boundary; |