From bc5f6d81eac8aad7bd6a9b72681159e3c0051d08 Mon Sep 17 00:00:00 2001 From: Radek Oslejsek <oslejsek@fi.muni.cz> Date: Sun, 24 May 2020 14:15:49 +0200 Subject: [PATCH] Adapted interface of MeshModel toward a component-based decomposition --- .../analyst/symmetry/TriangleOBSOLETE.java | 102 ------------------ .../analyst/mesh/core/BoundingBox.java | 92 +++++----------- .../fidentis/analyst/mesh/core/MeshFacet.java | 23 ++++ .../analyst/mesh/core/MeshFacetImpl.java | 62 ++++++++++- .../fidentis/analyst/mesh/core/MeshModel.java | 3 +- .../analyst/mesh/core/MeshTriangle.java | 92 ++-------------- 6 files changed, 118 insertions(+), 256 deletions(-) delete mode 100644 Comparison/src/main/java/cz/fidentis/analyst/symmetry/TriangleOBSOLETE.java diff --git a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/TriangleOBSOLETE.java b/Comparison/src/main/java/cz/fidentis/analyst/symmetry/TriangleOBSOLETE.java deleted file mode 100644 index 23d91944..00000000 --- a/Comparison/src/main/java/cz/fidentis/analyst/symmetry/TriangleOBSOLETE.java +++ /dev/null @@ -1,102 +0,0 @@ -package cz.fidentis.analyst.symmetry; - -/** - * - * @author Natália Bebjaková - * - * Helping representation of triangle in symmetry estimate - */ - -public class Triangle { - protected int vertex1; - protected int vertex2; - protected int vertex3; - - /** - * Creates new triangle - * - * @param v1 first vertex - * @param v2 second vertex - * @param v3 third vertex - */ - public Triangle(int v1, int v2, int v3) { - this.vertex1 = v1; - this.vertex2 = v2; - this.vertex3 = v3; - } - /** - * - * @return first vertex of triangle - */ - public int getVertex1() { - return vertex1; - } - - /** - * - * @param vertex1 new vertex - */ - public void setVertex1(int vertex1) { - this.vertex1 = vertex1; - } - - /** - * - * @return second vertex of triangle - */ - public int getVertex2() { - return vertex2; - } - - /** - * - * @param vertex2 new vertex - */ - public void setVertex2(int vertex2) { - this.vertex2 = vertex2; - } - - /** - * - * @return third vertex of triangle - */ - public int getVertex3() { - return vertex3; - } - - /** - * - * @param vertex3 new vertex - */ - public void setVertex3(int vertex3) { - this.vertex3 = vertex3; - } - - /** - * Triangles are same if they have same vertices - * - * @param obj other triangle - * @return true if two triangles are same - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof Triangle) { - Triangle t = (Triangle)obj; - if (((this.vertex1 == t.vertex1) || (this.vertex1 == t.vertex2) || (this.vertex1 == t.vertex3)) && - ((this.vertex2 == t.vertex1) || (this.vertex2 == t.vertex2) || (this.vertex2 == t.vertex3)) && - ((this.vertex3 == t.vertex1) || (this.vertex3 == t.vertex2) || (this.vertex3 == t.vertex3))) { - return (true); - } - } - return (false); - } - - /** - * - * @return hascode of the triangle - */ - @Override - public int hashCode() { - return (this.vertex1 * 100 ^ this.vertex2 * 100 ^ this.vertex3); - } -} diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/BoundingBox.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/BoundingBox.java index 16be89d8..97d990ef 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/BoundingBox.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/BoundingBox.java @@ -1,7 +1,5 @@ -package cz.fidentis.analyst.symmetry; +package cz.fidentis.analyst.mesh.core; -import cz.fidentis.analyst.mesh.core.MeshPoint; -import cz.fidentis.analyst.mesh.core.MeshPointImpl; import java.util.List; import javax.vecmath.Vector3d; @@ -14,13 +12,24 @@ import javax.vecmath.Vector3d; */ public class BoundingBox { - private boolean isMinMaxValid; private MeshPoint maxPoint; private MeshPoint minPoint; private MeshPoint midPoint; private double maxDiag; - private final List<MeshPoint> points; + /** + * Creates bounding box that is automatically maintained with respect to given array. + * @param points array of points, must not be null or pempty + * @throws IllegalArgumentException if the @code{points} param is null or empty + */ + public BoundingBox(List<MeshPoint> points) { + if (points == null || points.isEmpty()) { + throw new IllegalArgumentException("points"); + } + this.computeMinMax(points); + this.computeMidDiag(); + } + /** * * @return max point of the bounding box @@ -29,14 +38,6 @@ public class BoundingBox { return maxPoint; } - /** - * - * @param point new max point of the bounding box - */ - public void setMaxPoint(MeshPoint point) { - this.maxPoint = point; - } - /** * * @return middle point of the bounding box @@ -45,14 +46,6 @@ public class BoundingBox { return midPoint; } - /** - * - * @param point new middle point of the bounding box - */ - public void setMidPoint(MeshPoint point) { - this.midPoint = point; - } - /** * * @return min point of the bounding box @@ -62,34 +55,17 @@ public class BoundingBox { } /** - * - * @param point new min point of the bounding box - */ - public void setMinPoint(MeshPoint point) { - this.minPoint = point; - } - - /** - * Creates bounding box that is automatically maintained with respect to given array. - * @param points array of points + * Return volume diagonal of the bounding box. + * @return maximal diagonal of bounding box */ - public BoundingBox(List<MeshPoint> points) { - this.points = points; - this.validateMinMax(); - this.validateMidDiag(); - } - - /** - * @return point array that is managed by curent bounding box. - */ - public List<MeshPoint> getPoints() { - return points; + public double getMaxDiag() { + return maxDiag; } /** * Recomputes the BoundingBox from all points - */ - private void validateMinMax() { + */ + private void computeMinMax(List<MeshPoint> points) { minPoint = new MeshPointImpl(new Vector3d(Double.MAX_VALUE,Double.MAX_VALUE,Double.MAX_VALUE), null, null); maxPoint = new MeshPointImpl(new Vector3d(-100000.0,-100000.0,-100000.0), null, null); @@ -104,30 +80,17 @@ public class BoundingBox { maxPoint.getPosition().y = Math.max(maxPoint.getPosition().y, point.getPosition().y); maxPoint.getPosition().z = Math.max(maxPoint.getPosition().z, point.getPosition().z); } - isMinMaxValid = true; - this.validateMidDiag(); } /** * Recompute mid-point and max diagonal length. */ - private void validateMidDiag() { + private void computeMidDiag() { midPoint = (minPoint.addPosition(maxPoint)).multiplyPosition(0.5); MeshPoint diag = maxPoint.subtractPosition(minPoint); this.maxDiag = diag.abs(); } - /** - * Return volume diagonal of the bounding box. - * @return maximal diagonal of bounding box - */ - public double getMaxDiag() { - if (!isMinMaxValid) { - this.validateMinMax(); - } - return maxDiag; - } - /** * Returns description of BoundignBox. * @@ -136,14 +99,11 @@ public class BoundingBox { @Override public String toString() { String str = "BoundingBox: "; - if (this.minPoint == null || this.maxPoint == null || this.midPoint == null) { - return str += "undefined (there are no points)"; - } - str += "\n"; - str += "\t" + "- min point : " + this.minPoint + "\n"; - str += "\t" + "- max point : " + this.maxPoint + "\n"; - str += "\t" + "- mid point : " + this.midPoint + "\n"; - str += "\t" + "- max diag : " + this.maxDiag + "\n"; + str += System.lineSeparator(); + str += "\t" + "- min point : " + this.minPoint + System.lineSeparator(); + str += "\t" + "- max point : " + this.maxPoint + System.lineSeparator(); + str += "\t" + "- mid point : " + this.midPoint + System.lineSeparator(); + str += "\t" + "- max diag : " + this.maxDiag + System.lineSeparator(); return str; } } \ No newline at end of file diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java index 9f662046..3a700479 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshFacet.java @@ -44,4 +44,27 @@ public interface MeshFacet { * @return corner table */ CornerTable getCornerTable(); + + /** + * Returns the mesh as a list of individial triangles. + * @return the list of individial triangles. + */ + List<MeshTriangle> asTriangles(); + + /** + * Computes and returns bounding box of the mesh facet. + * @return bounding box of the mesh facet. + */ + BoundingBox getBoundingBox(); + + /** + * Returns true if normals of vertices are calculated. + * @return true if normals of vertices are calculated. + */ + boolean hasVertexNormals(); + + /** + * Calculates normals of vertices from normals of triangles. + */ + void calculateVertexNormals(); } 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 301548ec..10cd36d9 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 @@ -1,7 +1,11 @@ package cz.fidentis.analyst.mesh.core; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import javax.vecmath.Vector3d; /** * MashFacet @@ -26,9 +30,7 @@ public class MeshFacetImpl implements MeshFacet { * @param facet copied MeshFacet */ public MeshFacetImpl(MeshFacet facet) { - for (MeshPoint vertex: facet.getVertices()) { - vertices.add(new MeshPointImpl(vertex)); - } + vertices.addAll(facet.getVertices()); // encapsulation preserved - vertices MeshPoints are immutable) cornerTable = new CornerTable(facet.getCornerTable()); } @@ -49,12 +51,64 @@ public class MeshFacetImpl implements MeshFacet { @Override public List<MeshPoint> getVertices() { - return vertices; + return Collections.unmodifiableList(vertices); } @Override public CornerTable getCornerTable() { return cornerTable; } + + @Override + public List<MeshTriangle> asTriangles() { + List<MeshTriangle> ret = new ArrayList<>(); + for (int i = 0; i < cornerTable.getSize(); i += 3) { + ret.add(new MeshTriangle( + vertices.get(cornerTable.getRow(i + 0).getVertexIndex()), + vertices.get(cornerTable.getRow(i + 1).getVertexIndex()), + vertices.get(cornerTable.getRow(i + 2).getVertexIndex()))); + } + return ret; + } + + public BoundingBox getBoundingBox() { + return new BoundingBox(this.vertices); + } + + @Override + public boolean hasVertexNormals() { + return !this.vertices.isEmpty() && this.vertices.get(0).getNormal() != null; + } + + /** + * REPLACE WITH BETTER IMPLEMENTATION + * @throws RuntimeException if there are duplicate meth points in the mesh facet + */ + @Override + public void calculateVertexNormals() { + Map<Vector3d, Vector3d> normalMap = new HashMap<>(); // key = mesh point, value = normal + + // init normals: + for (MeshPoint point: vertices) { + if (normalMap.put(point.getPosition(), new Vector3d(0, 0, 0)) != null) { + throw new RuntimeException("Duplicate mesh point in the MeshFacet: " + point); + } + } + + // calculate normals from corresponding triangles + for (MeshTriangle t : asTriangles()) { + Vector3d triangleNormal = + (t.vertex3.subtractPosition(t.vertex1)).crossProduct(t.vertex2.subtractPosition(t.vertex1)).getPosition(); + normalMap.get(t.vertex1).add(triangleNormal); + normalMap.get(t.vertex2).add(triangleNormal); + normalMap.get(t.vertex3).add(triangleNormal); + } + + // normalize normals: + for (Vector3d normal: normalMap.values()) { + normal.normalize(); + } + } + } diff --git a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java index 38a7b9c6..9ab6d00c 100644 --- a/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java +++ b/MeshModel/src/main/java/cz/fidentis/analyst/mesh/core/MeshModel.java @@ -24,8 +24,7 @@ public class MeshModel { * @param meshModel copied MeshModel */ public MeshModel(MeshModel meshModel) { - for (MeshFacet facet : - meshModel.facets) { + for (MeshFacet facet: meshModel.facets) { facets.add(new MeshFacetImpl(facet)); } } 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 23d91944..ce92a488 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 @@ -1,16 +1,17 @@ -package cz.fidentis.analyst.symmetry; +package cz.fidentis.analyst.mesh.core; /** * * @author Natália Bebjaková * - * Helping representation of triangle in symmetry estimate + * Adapter for the corner table representing a single triangle of the @code{MeshFacet}. */ -public class Triangle { - protected int vertex1; - protected int vertex2; - protected int vertex3; +public class MeshTriangle { + + public final MeshPoint vertex1; + public final MeshPoint vertex2; + public final MeshPoint vertex3; /** * Creates new triangle @@ -19,84 +20,11 @@ public class Triangle { * @param v2 second vertex * @param v3 third vertex */ - public Triangle(int v1, int v2, int v3) { + public MeshTriangle(MeshPoint v1, MeshPoint v2, MeshPoint v3) { this.vertex1 = v1; this.vertex2 = v2; this.vertex3 = v3; } - /** - * - * @return first vertex of triangle - */ - public int getVertex1() { - return vertex1; - } - - /** - * - * @param vertex1 new vertex - */ - public void setVertex1(int vertex1) { - this.vertex1 = vertex1; - } - - /** - * - * @return second vertex of triangle - */ - public int getVertex2() { - return vertex2; - } - - /** - * - * @param vertex2 new vertex - */ - public void setVertex2(int vertex2) { - this.vertex2 = vertex2; - } - - /** - * - * @return third vertex of triangle - */ - public int getVertex3() { - return vertex3; - } - - /** - * - * @param vertex3 new vertex - */ - public void setVertex3(int vertex3) { - this.vertex3 = vertex3; - } - - /** - * Triangles are same if they have same vertices - * - * @param obj other triangle - * @return true if two triangles are same - */ - @Override - public boolean equals(Object obj) { - if (obj instanceof Triangle) { - Triangle t = (Triangle)obj; - if (((this.vertex1 == t.vertex1) || (this.vertex1 == t.vertex2) || (this.vertex1 == t.vertex3)) && - ((this.vertex2 == t.vertex1) || (this.vertex2 == t.vertex2) || (this.vertex2 == t.vertex3)) && - ((this.vertex3 == t.vertex1) || (this.vertex3 == t.vertex2) || (this.vertex3 == t.vertex3))) { - return (true); - } - } - return (false); - } - - /** - * - * @return hascode of the triangle - */ - @Override - public int hashCode() { - return (this.vertex1 * 100 ^ this.vertex2 * 100 ^ this.vertex3); - } + + } -- GitLab