projet-rendu/Mesh.java

211 lines
5.9 KiB
Java
Raw Normal View History

2022-04-14 09:25:36 +00:00
import java.io.*;
2022-04-12 10:08:58 +00:00
import algebra.*;
/**
* Defines a triangle based mesh.
* A mesh is constructed by interpretting the data given in an OFF file.
2022-04-14 09:25:36 +00:00
*
2022-04-12 10:08:58 +00:00
* @author smondet gg cdehais
*/
public class Mesh {
private Vector[] vertices;
2022-04-14 09:25:36 +00:00
private int[] faces;
2022-04-12 10:08:58 +00:00
private double[] colors;
private Vector3[] normals;
private double[] texCoords;
2022-04-14 09:25:36 +00:00
private static String nextLine(BufferedReader in) throws Exception {
String r = in.readLine();
2022-04-12 10:08:58 +00:00
2022-04-14 09:25:36 +00:00
while (r.matches("\\s*#.*")) {
r = in.readLine();
2022-04-12 10:08:58 +00:00
}
return r;
}
/**
* Builds a Mesh object by reading in an OFF file.
* Does not support non triangular meshes.
2022-04-14 09:25:36 +00:00
*
2022-04-12 10:08:58 +00:00
* @filename path to OFF file.
*/
2022-04-14 09:25:36 +00:00
public Mesh(String filename) throws Exception {
BufferedReader in = new BufferedReader(new FileReader(filename));
String r = nextLine(in);
if (!r.equals("OFF")) {
throw new IOException("Invalid OFF file !");
2022-04-12 10:08:58 +00:00
}
r = nextLine(in);
2022-04-14 09:25:36 +00:00
String[] sar = r.split("\\s+");
2022-04-12 10:08:58 +00:00
/* Parse object properties */
2022-04-14 09:25:36 +00:00
int verts_nb = new Integer(sar[0]).intValue();
int faces_nb = new Integer(sar[1]).intValue();
int edges_nb = new Integer(sar[2]).intValue();
2022-04-12 10:08:58 +00:00
/* Parse vertices and attributes */
vertices = new Vector[verts_nb];
2022-04-14 09:25:36 +00:00
faces = new int[3 * faces_nb];
colors = new double[3 * verts_nb];
for (int i = 0; i < verts_nb; i++) {
2022-04-12 10:08:58 +00:00
r = nextLine(in);
2022-04-14 09:25:36 +00:00
sar = r.split("\\s+");
2022-04-12 10:08:58 +00:00
2022-04-14 09:25:36 +00:00
vertices[i] = new Vector("v" + i, 4);
vertices[i].set(0, new Double(sar[0]).doubleValue());
vertices[i].set(1, new Double(sar[1]).doubleValue());
vertices[i].set(2, new Double(sar[2]).doubleValue());
vertices[i].set(3, 1.0);
2022-04-12 10:08:58 +00:00
colors[3 * i + 0] = new Double(sar[3]).doubleValue();
colors[3 * i + 1] = new Double(sar[4]).doubleValue();
colors[3 * i + 2] = new Double(sar[5]).doubleValue();
/* optionnal texture coordinates */
if (sar.length >= 8) {
if (texCoords == null) {
2022-04-14 09:25:36 +00:00
texCoords = new double[2 * verts_nb];
2022-04-12 10:08:58 +00:00
}
2022-04-14 09:25:36 +00:00
texCoords[2 * i] = new Double(sar[6]).doubleValue();
texCoords[2 * i + 1] = new Double(sar[7]).doubleValue();
2022-04-12 10:08:58 +00:00
}
}
2022-04-14 09:25:36 +00:00
2022-04-12 10:08:58 +00:00
/* Parse faces */
for (int i = 0; i < faces_nb; i++) {
r = nextLine(in);
sar = r.split("\\s+");
int en = new Integer(sar[0]).intValue();
if (en != 3) {
throw new IOException("Non-triangular meshes not supported.");
}
2022-04-14 09:25:36 +00:00
faces[3 * i + 0] = new Integer(sar[1]).intValue();
faces[3 * i + 1] = new Integer(sar[2]).intValue();
faces[3 * i + 2] = new Integer(sar[3]).intValue();
2022-04-12 10:08:58 +00:00
}
in.close();
}
2022-04-14 09:25:36 +00:00
2022-04-12 10:08:58 +00:00
/**
* Gets the number of vertices in the mesh
*/
2022-04-14 09:25:36 +00:00
public int getNumVertices() {
2022-04-12 10:08:58 +00:00
return vertices.length;
}
/**
* Gets the number of faces in the mesh
*/
2022-04-14 09:25:36 +00:00
public int getNumFaces() {
2022-04-12 10:08:58 +00:00
return faces.length / 3;
}
/**
* Constructs a normal for each vertex of the mesh
*/
2022-04-14 09:25:36 +00:00
private Vector3[] computeNormals() {
2022-04-12 10:08:58 +00:00
normals = new Vector3[vertices.length];
2022-04-14 09:25:36 +00:00
// Compute per face normals and set the vertex normal to the average normals
// across faces
2022-04-12 10:08:58 +00:00
// to the vertex.
try {
for (int i = 0; i < 3 * getNumFaces(); i += 3) {
2022-04-14 11:32:08 +00:00
int index_v0 = faces[i + 0];
int index_v1 = faces[i + 1];
int index_v2 = faces[i + 2];
Vector3 v0 = new Vector3(vertices[index_v0]);
Vector3 v1 = new Vector3(vertices[index_v1]);
Vector3 v2 = new Vector3(vertices[index_v2]);
2022-04-12 10:08:58 +00:00
2022-04-14 09:39:54 +00:00
Vector3 bidule_gauche = new Vector3(v1);
bidule_gauche.subtract(v0);
Vector3 bidule_droite = new Vector3(v2);
bidule_droite.subtract(v0);
Vector3 n = bidule_gauche.cross(bidule_droite);
2022-04-12 10:08:58 +00:00
2022-04-14 09:25:36 +00:00
// ajoute la normale calculee a chq sommet de la face
for (int j = 0; j < 3; j++) {
Vector nj = normals[faces[i + j]];
2022-04-12 10:08:58 +00:00
if (nj == null) {
2022-04-14 09:25:36 +00:00
normals[faces[i + j]] = new Vector3(n);
normals[faces[i + j]].setName("n" + faces[i + j]);
2022-04-12 10:08:58 +00:00
} else {
2022-04-14 09:25:36 +00:00
nj.add(n);
2022-04-12 10:08:58 +00:00
}
2022-04-14 09:25:36 +00:00
}
2022-04-12 10:08:58 +00:00
}
2022-04-14 09:25:36 +00:00
} catch (InstantiationException e) {
System.out.println("Should not reach 1");
} catch (SizeMismatchException e) {
System.out.println("Should not reach 2");
}
2022-04-12 10:08:58 +00:00
2022-04-14 09:25:36 +00:00
// final round of normalization
for (int i = 0; i < normals.length; i++) {
2022-04-12 10:08:58 +00:00
if (normals[i] == null) { /* deals with orphans vertices */
2022-04-14 09:25:36 +00:00
normals[i] = new Vector3("n_orphan");
2022-04-12 10:08:58 +00:00
} else {
normals[i].normalize();
}
}
2022-04-14 09:25:36 +00:00
return normals;
2022-04-12 10:08:58 +00:00
}
/**
2022-04-14 09:25:36 +00:00
* Returns the vertices of the mesh
*/
public Vector[] getVertices() {
2022-04-12 10:08:58 +00:00
return vertices;
}
/**
* Return the normals associated to the vertices.
*/
2022-04-14 09:25:36 +00:00
public Vector3[] getNormals() {
2022-04-12 10:08:58 +00:00
if (normals == null) {
2022-04-14 09:25:36 +00:00
normals = computeNormals();
2022-04-12 10:08:58 +00:00
}
return normals;
}
/**
2022-04-14 09:25:36 +00:00
* Returns the faces of the mesh. The returned array contains 3*n integers, with
* n the number of faces.
2022-04-12 10:08:58 +00:00
* Each integer is an index into the array of Vector.
*/
2022-04-14 09:25:36 +00:00
public int[] getFaces() {
2022-04-12 10:08:58 +00:00
return faces;
}
/**
* Returns the colors of each vertex in the mesh.
*/
2022-04-14 09:25:36 +00:00
public double[] getColors() {
2022-04-12 10:08:58 +00:00
return colors;
}
/**
* Returns the texture coordinates of each vertex in the mesh.
*/
2022-04-14 09:25:36 +00:00
public double[] getTextureCoordinates() {
2022-04-12 10:08:58 +00:00
return texCoords;
}
}