📄 trianglemesh.java
字号:
//===========================================================================//=-------------------------------------------------------------------------=//= Module history: =//= - August 8 2005 - Gabriel Sarmiento / Lina Rojas: Original base version =//= - May 2 2006 - Oscar Chavarro: quality check, doIntersection doc/test =//= - May 3 2006 - Oscar Chavarro: fixed doIntersection error when testing =//= back facing triangles =//= - November 6 2006 - Oscar Chavarro: introduced bounding box and normal =//= interpolation =//= - November 13 2006 - Oscar Chavarro: re-structured and tested =//=-------------------------------------------------------------------------=//= References: =//= [DACH2006] Dachille, Frank IX. Kaufman, Arie. "Incremental Triangle =//= Voxelization", Center for Visual Computing and Department of =//= Computer Science, State University of New York at Stony Brook, 2000 =//===========================================================================package vsdk.toolkit.environment.geometry;// Java basic classesimport java.util.ArrayList;// VitralSDK classesimport vsdk.toolkit.common.Triangle;import vsdk.toolkit.common.Ray;import vsdk.toolkit.common.VSDK;import vsdk.toolkit.common.Matrix4x4;import vsdk.toolkit.common.Vertex;import vsdk.toolkit.common.Vector3D;import vsdk.toolkit.media.Image;import vsdk.toolkit.environment.Material;import vsdk.toolkit.environment.scene.SimpleBody;import vsdk.toolkit.gui.ProgressMonitor;import vsdk.toolkit.processing.ComputationalGeometry;/**This class represents a "basic" triangle mesh. Its model is based in a setof vertexes and triangles (the edges are not store explicitly, and therecan not be an edge not forming part of a triangle).This basic triangle mesh model can be associated with one and only onematerial (this could change in future), but can have multiple textures,and each texture can be mapped to a different set of triangles.As every model class or `Entity` in VSDK, this class only can represent(store in memory) the mesh model. It doesn´t provide persistence or renderingfunctionality, as this could be found at `io` and `render` packages.Nevertheles, this class will be highly coupled with both of those, somaking any change here will impact highly that code.This class does not ensure nor impose data integrity, and this will be the sole responsability of the cooperating utilities and applications.@todo Document more this class (include samples and data structure diagrams)@todo Generalize the material usage model, to conform similarly to current texture usage (i.e. allow multiple materials per mesh)@todo Make sure this is always using good names with complete words on it (rename methods and attributes)@todo Extend the model to allow dangling edges*/public class TriangleMesh extends Surface {//= Class attributes ======================================================== /// Check the general attribute description in superclass Entity. public static final long serialVersionUID = 20060807L; // Basic mesh data model private String name = "default"; private Vertex[] vertexes; private Triangle[] triangles; // Auxiliary components for data model private Material[] materials; private Image[] textures; /** textureRanges is a 2D array which contents mappings between the `triangles` and `textures` sets. Each pair <textureRanges[i][0], textureRanges[i][1]> means that the triangles from textureRanges[i-1][0] to textureRanges[i][0] (from triangle 0 when i = 0), are associated with the texture textureRanges[i][1] (or no texture for unspecified range or when textureRanges[i][1] contains a value out of textures array bounds). */ private int[][] textureRanges; /** materialRanges is a 2D array which contents mappings between the `triangles` and `materials` sets. Each pair <materialRanges[i][0], materialRanges[i][1]> means that the triangles from materialRanges[i-1][0] to materialRanges[i][0] (from triangle 0 when i = 0), are associated with the material materialRanges[i][1] (or no material for unspecified range or when materialRanges[i][1] contains a value out of materials array bounds). */ private int[][] materialRanges; // Auxiliary data structures for storage of parcial results and // preprocessing private double[] minMax; private int selectedTriangle; private SimpleBody boundingVolume; private GeometryIntersectionInformation lastInfo; private Ray lastRay; private TriangleMeshGroup triangleMeshGroupCache;//= Basic class management methods ========================================== public TriangleMesh() { lastInfo = new GeometryIntersectionInformation(); lastRay = null; minMax = null; boundingVolume = null; triangleMeshGroupCache = null; } public TriangleMesh(Vertex[] vertexes, Triangle[] triangles) { this.vertexes = vertexes; this.triangles = triangles; minMax = null; lastInfo = new GeometryIntersectionInformation(); lastRay = null; boundingVolume = null; triangleMeshGroupCache = null; } public String getName() { return this.name; } public Vertex[] getVertexes() { return this.vertexes; } public Vertex getVertexAt(int index) { return this.vertexes[index]; } public Triangle[] getTriangles() { return this.triangles; } public Triangle getTriangleAt(int index) { return this.triangles[index]; } public Material[] getMaterials() { return this.materials; } public Image[] getTextures() { return this.textures; } public Image getTextureAt(int index) { return this.textures[index]; } public void setName(String name) { this.name = name; } public void setVertexes(Vertex[] vertexes) { this.vertexes = vertexes; boundingVolume = null; } public void setTriangles(Triangle[] triangles) { this.triangles = triangles; boundingVolume = null; } public void setTextures(Image[] textures) { this.textures = textures; } public void setMaterials(Material[] materials) { this.materials = materials; } public void setTrianglesSize(int size) { this.triangles = new Triangle[size]; boundingVolume = null; } public void setVertexesSize(int size) { this.vertexes = new Vertex[size]; boundingVolume = null; } public void setTexturesSize(int size) { this.textures = new Image[size]; boundingVolume = null; } public void setVertexAt(int index, Vertex vertex) { this.vertexes[index] = vertex; boundingVolume = null; } public void setTriangleAt(int index, Triangle triangle) { this.triangles[index] = triangle; boundingVolume = null; } public void setTextureAt(int index, Image image) { this.textures[index] = image; boundingVolume = null; }//= Methods for managing textureRanges ====================================== public int[][] getTextureRanges() { return textureRanges; } /** Note this always returns an array with two (2) integers: the first one is an index to `triangles` array, the second one is an index to the `textures` array. */ public int[] getTextureRangeAt(int spanRange) { return textureRanges[spanRange]; } public void setTextureRanges(int ranges[][]) { textureRanges = ranges; }//= Methods for managing materialRanges ===================================== public int[][] getMaterialRanges() { return materialRanges; } /** Note this always returns an array with two (2) integers: the first one is an index to `triangles` array, the second one is an index to the `materials` array. */ public int[] getMaterialRangeAt(int spanRange) { return materialRanges[spanRange]; } public void setMaterialRanges(int ranges[][]) { materialRanges = ranges; }//= Fundamental geometry operations methods ================================= public void calculateNormals() { boundingVolume = null; for (int i = 0; i < triangles.length; i++) { Vertex v1 = vertexes[triangles[i].getPoint0()]; Vertex v2 = vertexes[triangles[i].getPoint1()]; Vertex v3 = vertexes[triangles[i].getPoint2()]; double ax = v2.getPosition().x - v1.getPosition().x; double ay = v2.getPosition().y - v1.getPosition().y; double az = v2.getPosition().z - v1.getPosition().z; double bx = v3.getPosition().x - v2.getPosition().x; double by = v3.getPosition().y - v2.getPosition().y; double bz = v3.getPosition().z - v2.getPosition().z; Vector3D a = new Vector3D(ax, ay, az); Vector3D b = new Vector3D(bx, by, bz); a.normalize(); b.normalize(); triangles[i].normal = a.crossProduct(b); triangles[i].normal.normalize(); } ArrayList<ArrayList<vsdk.toolkit.common.Triangle>> vecinos; vecinos = new ArrayList<ArrayList<vsdk.toolkit.common.Triangle>> (vertexes.length); for (int i = 0; i < vertexes.length; i++) { vecinos.add(new ArrayList<Triangle> ()); } for (int i = 0; i < triangles.length; i++) { vecinos.get(triangles[i].p0).add(triangles[i]); vecinos.get(triangles[i].p1).add(triangles[i]); vecinos.get(triangles[i].p2).add(triangles[i]); } for (int i = 0; i < vertexes.length; i++) { vertexes[i].setNormal(new Vector3D(0, 0, 0)); for (int j = 0; j < vecinos.get(i).size(); j++) { vertexes[i].getNormal().x += vecinos.get(i).get(j).normal.x; vertexes[i].getNormal().y += vecinos.get(i).get(j).normal.y; vertexes[i].getNormal().z += vecinos.get(i).get(j).normal.z; } vertexes[i].getNormal().normalize(); vertexes[i].setIncidentTriangles(vecinos.get(i)); } } /** In the triangle meshes the vector normal directions must be consistent with the triangle normal, which direction depends on triangle order (clockwise or counterclockwise). This method checks for inverted normals, and invert them to make it consistent with triangle orientation order. Note that this methods recalculate triangle surface normals. */ public void reorientateNormals() { int i; Vertex a, b, c; Vector3D u, v, n; for ( i = 0; i < triangles.length; i++ ) { a = vertexes[triangles[i].p0]; b = vertexes[triangles[i].p1]; c = vertexes[triangles[i].p2]; u = b.position.substract(a.position); v = c.position.substract(a.position); triangles[i].normal = u.crossProduct(v); triangles[i].normal.normalize(); if ( triangles[i].normal.dotProduct(a.normal) < 0 ) { a.normal = a.normal.multiply(-1); } if ( triangles[i].normal.dotProduct(b.normal) < 0 ) { b.normal = b.normal.multiply(-1); } if ( triangles[i].normal.dotProduct(c.normal) < 0 ) { c.normal = c.normal.multiply(-1); } } } /** Needed for supplying the Geometry.getMinMax operation */ private void calculateMinMaxPositions() { boundingVolume = null; if ( minMax == null ) { minMax = new double[6]; double minX = Double.MAX_VALUE; double minY = Double.MAX_VALUE; double minZ = Double.MAX_VALUE; double maxX = -Double.MAX_VALUE; double maxY = -Double.MAX_VALUE; double maxZ = -Double.MAX_VALUE; int i; for ( i = 0; i < vertexes.length; i++ ) { double x = vertexes[i].getPosition().x; double y = vertexes[i].getPosition().y; double z = vertexes[i].getPosition().z; if ( x < minX ) minX = x; if ( y < minY ) minY = y; if ( z < minZ ) minZ = z;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -