From 8cdbcc8d298743ebe503be2db639396c1b6d1609 Mon Sep 17 00:00:00 2001 From: Radek Oslejsek <oslejsek@fi.muni.cz> Date: Tue, 6 Apr 2021 21:29:18 +0200 Subject: [PATCH] MeshTriangle simplified --- .../analyst/visitors/mesh/Curvature.java | 271 +----------------- .../analyst/mesh/core/MeshFacetImpl.java | 14 +- .../analyst/mesh/core/MeshTriangle.java | 71 +++-- .../analyst/mesh/core/TriangleFan.java | 48 +++- .../analyst/mesh/core/MeshTriangleTest.java | 2 + 5 files changed, 104 insertions(+), 302 deletions(-) diff --git a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Curvature.java b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Curvature.java index b42c398b..cba70946 100644 --- a/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Curvature.java +++ b/Comparison/src/main/java/cz/fidentis/analyst/visitors/mesh/Curvature.java @@ -84,7 +84,7 @@ public class Curvature extends MeshVisitor { Cache cache = new Cache(facet); - final List<CurvTriangle> triangles = precomputeTriangles(facet); + //final List<CurvTriangle> triangles = precomputeTriangles(facet); for (int vertA = 0; vertA < facet.getNumberOfVertices(); vertA++) { TriangleFan oneRing = facet.getOneRingNeighborhood(vertA); @@ -155,6 +155,7 @@ public class Curvature extends MeshVisitor { } } + /* protected List<CurvTriangle> precomputeTriangles(MeshFacet facet) { List<CurvTriangle> ret = new ArrayList<>(facet.getNumTriangles()); for (MeshTriangle tri: facet) { @@ -162,6 +163,7 @@ public class Curvature extends MeshVisitor { } return ret; } + */ /** * Helper class that caches triangle characteristics used multiples times during the curvature computation. @@ -175,273 +177,6 @@ public class Curvature extends MeshVisitor { */ protected class CurvTriangle { - private final MeshFacet facet; - private final MeshTriangle tri; - - private final double v1Angle; - private final double v2Angle; - private final double v3Angle; - - private final double v1AngleCotang; - private final double v2AngleCotang; - private final double v3AngleCotang; - - public CurvTriangle(MeshFacet facet, MeshTriangle tri) { - this.facet = facet; - this.tri = tri; - - Vector3d a = new Vector3d(facet.getVertex(tri.index3).getPosition()); - a.sub(facet.getVertex(tri.index2).getPosition()); - - Vector3d b = new Vector3d(facet.getVertex(tri.index1).getPosition()); - b.sub(facet.getVertex(tri.index3).getPosition()); - - Vector3d c = new Vector3d(facet.getVertex(tri.index2).getPosition()); - c.sub(facet.getVertex(tri.index1).getPosition()); - - a.normalize(); - b.normalize(); - c.normalize(); - - b.scale(-1.0); - double cos1 = c.dot(b); - - c.scale(-1.0); - double cos2 = a.dot(c); - - a.scale(-1.0); - b.scale(-1.0); - double cos3 = a.dot(b); - - this.v1Angle = Math.acos(cos1); - this.v2Angle = Math.acos(cos2); - this.v3Angle = Math.acos(cos3); - - this.v1AngleCotang = 1.0 / Math.tan(v1Angle); - this.v2AngleCotang = 1.0 / Math.tan(v2Angle); - this.v3AngleCotang = 1.0 / Math.tan(v3Angle); - } - - public double area() { - return 0.5 * lengthSquaredAC(tri.vertex1) * lengthSquaredAB(tri.vertex1) * Math.sin(v1Angle); - } - - /** - * Returns vertex A. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return vertex A. - */ - public Vector3d vertA(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return tri.vertex1.getPosition(); - } else if (facetPoint == tri.vertex2) { - return tri.vertex2.getPosition(); - } else if (facetPoint == tri.vertex3) { - return tri.vertex3.getPosition(); - } - return null; - } - - /** - * Returns vertex B. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return vertex B. - */ - public Vector3d vertB(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return tri.vertex3.getPosition(); - } else if (facetPoint == tri.vertex2) { - return tri.vertex1.getPosition(); - } else if (facetPoint == tri.vertex3) { - return tri.vertex2.getPosition(); - } - return null; - } - - /** - * Returns vertex C. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return vertex C. - */ - public Vector3d vertC(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return tri.vertex2.getPosition(); - } else if (facetPoint == tri.vertex2) { - return tri.vertex3.getPosition(); - } else if (facetPoint == tri.vertex3) { - return tri.vertex1.getPosition(); - } - return null; - } - - /** - * Returns cached angle in the vertex A. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Alpha angle. - */ - public double alpha(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return v1Angle; - } else if (facetPoint == tri.vertex2) { - return v2Angle; - } else if (facetPoint == tri.vertex3) { - return v3Angle; - } - return Double.NaN; - } - - /** - * Returns cached angle in the vertex B. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Beta angle. - */ - public double beta(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return v3Angle; - } else if (facetPoint == tri.vertex2) { - return v1Angle; - } else if (facetPoint == tri.vertex3) { - return v2Angle; - } - return Double.NaN; - } - - /** - * Returns cached angle in the vertex C. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Gamma angle. - */ - public double gamma(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return v2Angle; - } else if (facetPoint == tri.vertex2) { - return v3Angle; - } else if (facetPoint == tri.vertex3) { - return v1Angle; - } - return Double.NaN; - } - - /** - * Returns cached cotangent of the angle in the vertex A. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Cotangent of the alpha angle. - */ - public double alphaCotan(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return v1AngleCotang; - } else if (facetPoint == tri.vertex2) { - return v2AngleCotang; - } else if (facetPoint == tri.vertex3) { - return v3AngleCotang; - } - return Double.NaN; - } - - /** - * Returns cached cotangent of the angle in the vertex B. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Cotangent of the beta angle. - */ - public double betaCotan(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return v3AngleCotang; - } else if (facetPoint == tri.vertex2) { - return v1AngleCotang; - } else if (facetPoint == tri.vertex3) { - return v2AngleCotang; - } - return Double.NaN; - } - - /** - * Returns cached cotangent of the angle in the vertex C. - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Cotangent of the gamma angle. - */ - public double gammaCotan(MeshPoint facetPoint) { - if (facetPoint == tri.vertex1) { - return v2AngleCotang; - } else if (facetPoint == tri.vertex2) { - return v3AngleCotang; - } else if (facetPoint == tri.vertex3) { - return v1AngleCotang; - } - return Double.NaN; - } - - /** - * Returns squared length of the edge AB (opposite to the vertex A). - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Squared length of the edge AB. - */ - public double lengthSquaredAB(MeshPoint facetPoint) { - Vector3d v = null; - if (facetPoint == tri.vertex1) { - v = new Vector3d(facet.getVertex(tri.index3).getPosition()); - v.sub(facet.getVertex(tri.index1).getPosition()); - } else if (facetPoint == tri.vertex2) { - v = new Vector3d(facet.getVertex(tri.index1).getPosition()); - v.sub(facet.getVertex(tri.index2).getPosition()); - } else if (facetPoint == tri.vertex3) { - v = new Vector3d(facet.getVertex(tri.index2).getPosition()); - v.sub(facet.getVertex(tri.index3).getPosition()); - } - return v.lengthSquared(); - } - - /** - * Returns squared length of the edge AC (opposite to the vertex B). - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Squared length of the edge AC. - */ - public double lengthSquaredAC(MeshPoint facetPoint) { - Vector3d v = null; - if (facetPoint == tri.vertex1) { - v = new Vector3d(facet.getVertex(tri.index2).getPosition()); - v.sub(facet.getVertex(tri.index1).getPosition()); - } else if (facetPoint == tri.vertex2) { - v = new Vector3d(facet.getVertex(tri.index3).getPosition()); - v.sub(facet.getVertex(tri.index2).getPosition()); - } else if (facetPoint == tri.vertex3) { - v = new Vector3d(facet.getVertex(tri.index1).getPosition()); - v.sub(facet.getVertex(tri.index3).getPosition()); - } - return v.lengthSquared(); - } - - /** - * Returns squared length of the edge BC (opposite to the vertex A). - * - * @param facetPoint Central point of the 1-ring neighborhood - * @return Squared length of the edge BC. - */ - public double lengthSquaredBC(MeshPoint facetPoint) { - Vector3d v = null; - if (facetPoint == tri.vertex1) { - v = new Vector3d(facet.getVertex(tri.index3).getPosition()); - v.sub(facet.getVertex(tri.index2).getPosition()); - v.sub(facetPoint.getPosition()); - } else if (facetPoint == tri.vertex2) { - v = new Vector3d(facet.getVertex(tri.index1).getPosition()); - v.sub(facet.getVertex(tri.index3).getPosition()); - } else if (facetPoint == tri.vertex3) { - v = new Vector3d(facet.getVertex(tri.index2).getPosition()); - v.sub(facet.getVertex(tri.index1).getPosition()); - } - return v.lengthSquared(); - } } /** diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java index 6511eb24..b2d53377 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacetImpl.java @@ -98,10 +98,10 @@ public class MeshFacetImpl implements MeshFacet { // calculate normals from corresponding triangles for (MeshTriangle t : this) { Vector3d triangleNormal = - (t.vertex3.subtractPosition(t.vertex1)).crossProduct(t.vertex2.subtractPosition(t.vertex1)).getPosition(); - normalMap.get(t.vertex1.getPosition()).add(triangleNormal); - normalMap.get(t.vertex2.getPosition()).add(triangleNormal); - normalMap.get(t.vertex3.getPosition()).add(triangleNormal); + (t.getPoint3().subtractPosition(t.getPoint1())).crossProduct(t.getPoint2().subtractPosition(t.getPoint1())).getPosition(); + normalMap.get(t.getPoint1().getPosition()).add(triangleNormal); + normalMap.get(t.getPoint2().getPosition()).add(triangleNormal); + normalMap.get(t.getPoint3().getPosition()).add(triangleNormal); } // normalize normals: @@ -132,9 +132,7 @@ public class MeshFacetImpl implements MeshFacet { for (Integer triI: adjacentTrianglesI) { List<Integer> triVerticesI = cornerTable.getIndexesOfVerticesByTriangleIndex(triI); MeshTriangle tri = new MeshTriangle( - getVertex(triVerticesI.get(0)), - getVertex(triVerticesI.get(1)), - getVertex(triVerticesI.get(2)), + this, triVerticesI.get(0), triVerticesI.get(1), triVerticesI.get(2)); @@ -204,7 +202,7 @@ public class MeshFacetImpl implements MeshFacet { int i2 = cornerTable.getRow(index + 1).getVertexIndex(); int i3 = cornerTable.getRow(index + 2).getVertexIndex(); - MeshTriangle tri = new MeshTriangle(vertices.get(i1), vertices.get(i2), vertices.get(i3), i1, i2, i3); + MeshTriangle tri = new MeshTriangle(MeshFacetImpl.this, i1, i2, i3); index += 3; return tri; diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshTriangle.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshTriangle.java index bcd476b7..75c24d04 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshTriangle.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshTriangle.java @@ -16,9 +16,11 @@ public class MeshTriangle implements Iterable<MeshPoint> { public static final double EPS = 0.001; // tollerance - public final MeshPoint vertex1; - public final MeshPoint vertex2; - public final MeshPoint vertex3; + //public final MeshPoint vertex1; + //public final MeshPoint vertex2; + //public final MeshPoint vertex3; + + private final MeshFacet facet; /** * Under which index is the corresponding vertex stored in the mesh facet @@ -39,13 +41,38 @@ public class MeshTriangle implements Iterable<MeshPoint> { * @param i2 which index is the second vertex stored in the mesh facet * @param i3 which index is the third vertex stored in the mesh facet */ - public MeshTriangle(MeshPoint v1, MeshPoint v2, MeshPoint v3, int i1, int i2, int i3) { - this.vertex1 = v1; - this.vertex2 = v2; - this.vertex3 = v3; + public MeshTriangle(MeshFacet facet, int i1, int i2, int i3) { + if (facet == null) { + throw new IllegalArgumentException("facet"); + } this.index1 = i1; this.index2 = i2; this.index3 = i3; + this.facet = facet; + } + + public Vector3d getVertex1() { + return facet.getVertex(index1).getPosition(); + } + + public Vector3d getVertex2() { + return facet.getVertex(index2).getPosition(); + } + + public Vector3d getVertex3() { + return facet.getVertex(index3).getPosition(); + } + + public MeshPoint getPoint1() { + return facet.getVertex(index1); + } + + public MeshPoint getPoint2() { + return facet.getVertex(index2); + } + + public MeshPoint getPoint3() { + return facet.getVertex(index3); } /** @@ -54,10 +81,10 @@ public class MeshTriangle implements Iterable<MeshPoint> { * @return normalized normal vector from the vertices. */ public Vector3d computeNormal() { - Vector3d ab = new Vector3d(vertex1.getPosition()); - ab.sub(vertex2.getPosition()); - Vector3d ac = new Vector3d(vertex1.getPosition()); - ac.sub(vertex3.getPosition()); + Vector3d ab = new Vector3d(getVertex1()); + ab.sub(getVertex2()); + Vector3d ac = new Vector3d(getVertex1()); + ac.sub(getVertex3()); Vector3d normal = new Vector3d(); normal.cross(ab, ac); normal.normalize(); @@ -101,11 +128,11 @@ public class MeshTriangle implements Iterable<MeshPoint> { } switch (counter++) { case 0: - return vertex1; + return facet.getVertex(index1); case 1: - return vertex2; + return facet.getVertex(index2); case 2: - return vertex3; + return facet.getVertex(index3); default: return null; } @@ -124,6 +151,10 @@ public class MeshTriangle implements Iterable<MeshPoint> { return voronoiPoint; } + MeshPoint vertex1 = facet.getVertex(index1); + MeshPoint vertex2 = facet.getVertex(index2); + MeshPoint vertex3 = facet.getVertex(index3); + double a = (vertex2.subtractPosition(vertex3)).abs(); double b = (vertex3.subtractPosition(vertex1)).abs(); double c = (vertex2.subtractPosition(vertex1)).abs(); @@ -202,7 +233,7 @@ public class MeshTriangle implements Iterable<MeshPoint> { protected Vector3d getProjectionToTrianglePlane(Vector3d point) { Vector3d normal = computeNormal(); Vector3d helperVector = new Vector3d(point); - helperVector.sub(vertex1.getPosition()); + helperVector.sub(getVertex1()); double dist = helperVector.dot(normal); Vector3d projection = new Vector3d(point); @@ -242,14 +273,10 @@ public class MeshTriangle implements Iterable<MeshPoint> { * @return perpendicular projection to the nearest edge */ protected Vector3d getProjectionToClosestEdge(Vector3d point) { - Vector3d v1 = vertex1.getPosition(); - Vector3d v2 = vertex2.getPosition(); - Vector3d v3 = vertex3.getPosition(); - double minDistance = Double.POSITIVE_INFINITY; Vector3d closestProjection = null; - Vector3d projection = getProjectionToEdge(point, v2, v1); + Vector3d projection = getProjectionToEdge(point, getVertex2(), getVertex1()); Vector3d aux = new Vector3d(point); aux.sub(projection); double dist = aux.length(); @@ -258,7 +285,7 @@ public class MeshTriangle implements Iterable<MeshPoint> { closestProjection = projection; } - projection = getProjectionToEdge(point, v3, v2); + projection = getProjectionToEdge(point, getVertex3(), getVertex2()); aux.sub(point, projection); dist = aux.length(); if (dist < minDistance) { @@ -266,7 +293,7 @@ public class MeshTriangle implements Iterable<MeshPoint> { closestProjection = projection; } - projection = getProjectionToEdge(point, v1, v3); + projection = getProjectionToEdge(point, getVertex1(), getVertex3()); aux.sub(point, projection); dist = aux.length(); if (dist < minDistance) { diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/TriangleFan.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/TriangleFan.java index 9536cbbb..cbf29e2b 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/TriangleFan.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/TriangleFan.java @@ -1,8 +1,10 @@ package cz.fidentis.analyst.mesh.core; import java.util.Collections; +import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import java.util.NoSuchElementException; import java.util.Objects; /** @@ -11,8 +13,10 @@ import java.util.Objects; * * @author Radek Oslejsek */ -public class TriangleFan { +public class TriangleFan implements Iterable<MeshTriangle> { + private final int centralVertex; + private final MeshFacet facet; private final List<Integer> vertices = new LinkedList<>(); private final List<Integer> triangles = new LinkedList<>(); @@ -28,6 +32,9 @@ public class TriangleFan { throw new IllegalArgumentException("facet"); } + centralVertex = vert; + this.facet = facet; + int vertRow = -1; for (int i = 0; i < facet.getCornerTable().getSize(); i++) { if (facet.getCornerTable().getRow(i).getVertexIndex() == vert) { @@ -39,7 +46,7 @@ public class TriangleFan { throw new IllegalArgumentException("vert"); } - computeOneRingData(facet, vertRow); + computeOneRingData(vertRow); } /** @@ -81,7 +88,7 @@ public class TriangleFan { return Collections.unmodifiableList(triangles); } - private void computeOneRingData(MeshFacet facet, int vertRow) { + private void computeOneRingData(int vertRow) { CornerTable ct = facet.getCornerTable(); int ringVertRow = ct.getIndexOfNextCornerInFace(vertRow); while (true) { @@ -108,5 +115,38 @@ public class TriangleFan { } triangles.add(ct.getIndexOfFace(ringVertRow)); } - } + } + + /** + * Vertex 1 of the returned triangle always corresponds to the central vertex + * around which the triangle fan is constructed. + * @return + */ + @Override + public Iterator<MeshTriangle> iterator() { + return new Iterator<MeshTriangle>() { + private int index; + + /** + * + * @param facet Mesh facet to iterate + */ + @Override + public boolean hasNext() { + return index < triangles.size(); + } + + @Override + public MeshTriangle next() { + if (!hasNext()) { + throw new NoSuchElementException(); + } + + MeshTriangle tri = new MeshTriangle(facet, centralVertex, index, index+1); + index++; + return tri; + } + }; + } + } diff --git a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/MeshTriangleTest.java b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/MeshTriangleTest.java index 9abe112d..1fd03eec 100644 --- a/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/MeshTriangleTest.java +++ b/MeshModel/src/test/java/cz/fidentis/analyst/mesh/core/MeshTriangleTest.java @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test; */ public class MeshTriangleTest { + /* protected MeshTriangle getTriangle() { MeshTriangle triangle = new MeshTriangle( new MeshPointImpl(new Vector3d(1, 0, 0), null, null), @@ -36,5 +37,6 @@ public class MeshTriangleTest { Assertions.assertEquals(new Vector3d(1, 0, 0), tri.getClosestPoint(new Vector3d(1, 0, -1))); Assertions.assertEquals(new Vector3d(1.2, 0.2, 0), tri.getClosestPoint(new Vector3d(1.2, 0.2, -1))); } + */ } -- GitLab