-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathmesh.h
154 lines (126 loc) · 5.2 KB
/
mesh.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#ifndef MESH_H
#define MESH_H
#include <vector>
#include "vectors.h"
#include "hash.h"
class Vertex;
class Edge;
class BoundingBox;
class Face;
class Material;
class Primitive;
class ArgParser;
class Camera;
class Ray;
class Hit;
enum FACE_TYPE { FACE_TYPE_ORIGINAL, FACE_TYPE_RASTERIZED, FACE_TYPE_SUBDIVIDED };
// ======================================================================
// ======================================================================
// A class to store all objects in the scene. The quad faces of the
// mesh can be subdivided to improve the resolution of the radiosity
// solution. The original mesh is maintained for efficient occlusion
// testing.
class Mesh {
public:
// ===============================
// CONSTRUCTOR & DESTRUCTOR & LOAD
Mesh() { bbox = NULL; }
virtual ~Mesh();
void Load(const std::string &input_file, ArgParser *_args);
// ========
// VERTICES
int numVertices() const { return vertices.size(); }
Vertex* addVertex(const Vec3f &pos);
// look up vertex by index from original .obj file
Vertex* getVertex(int i) const {
assert (i >= 0 && i < numVertices());
return vertices[i]; }
// this creates a relationship between 3 vertices (2 parents, 1 child)
void setParentsChild(Vertex *p1, Vertex *p2, Vertex *child);
// this accessor will find a child vertex (if it exists) when given
// two parent vertices
Vertex* getChildVertex(Vertex *p1, Vertex *p2) const;
// =====
// EDGES
int numEdges() const { return edges.size(); }
// this efficiently looks for an edge with the given vertices, using a hash table
Edge* getEdge(Vertex *a, Vertex *b) const;
// =================
// ACCESS THE LIGHTS
std::vector<Face*>& getLights() { return original_lights; }
// ==================================
// ACCESS THE QUADS (for ray tracing)
int numOriginalQuads() const { return original_quads.size(); }
Face* getOriginalQuad(int i) const {
assert (i < numOriginalQuads());
return original_quads[i]; }
// =======================================
// ACCESS THE PRIMITIVES (for ray tracing)
int numPrimitives() const { return primitives.size(); }
Primitive* getPrimitive(int i) const {
assert (i >= 0 && i < numPrimitives());
return primitives[i]; }
// ACCESS THE PRIMITIVES (for radiosity)
int numRasterizedPrimitiveFaces() const { return rasterized_primitive_faces.size(); }
Face* getRasterizedPrimitiveFace(int i) const {
assert (i >= 0 && i < numRasterizedPrimitiveFaces());
return rasterized_primitive_faces[i]; }
// ==============================================================
// ACCESS THE SUBDIVIDED QUADS + RASTERIZED FACES (for radiosity)
int numFaces() const { return subdivided_quads.size() + rasterized_primitive_faces.size(); }
Face* getFace(int i) const {
int num_faces = numFaces();
assert (i >= 0 && i < num_faces);
if (i < (int)subdivided_quads.size()) return subdivided_quads[i];
else return getRasterizedPrimitiveFace(i-subdivided_quads.size()); }
// ============================
// CREATE OR SUBDIVIDE GEOMETRY
void addRasterizedPrimitiveFace(Vertex *a, Vertex *b, Vertex *c, Vertex *d, Material *material) {
addFace(a,b,c,d,material,FACE_TYPE_RASTERIZED); }
void addOriginalQuad(Vertex *a, Vertex *b, Vertex *c, Vertex *d, Material *material) {
addFace(a,b,c,d,material,FACE_TYPE_ORIGINAL); }
void addSubdividedQuad(Vertex *a, Vertex *b, Vertex *c, Vertex *d, Material *material) {
addFace(a,b,c,d,material,FACE_TYPE_SUBDIVIDED); }
// ===============
// OTHER ACCESSORS
BoundingBox* getBoundingBox() const { assert (bbox != NULL); return bbox; }
const Vec3f& getBackgroundColor() const { return background_color; }
Camera* getCamera() const { assert (camera != NULL); return camera; }
// ===============
// OTHER FUNCTIONS
void PaintWireframe();
void Subdivision();
private:
// ==================================================
// HELPER FUNCTIONS FOR CREATING/SUBDIVIDING GEOMETRY
Vertex* AddEdgeVertex(Vertex *a, Vertex *b);
Vertex* AddMidVertex(Vertex *a, Vertex *b, Vertex *c, Vertex *d);
void addFace(Vertex *a, Vertex *b, Vertex *c, Vertex *d, Material *material, enum FACE_TYPE face_type);
void removeFaceEdges(Face *f);
void addPrimitive(Primitive *p);
// ==============
// REPRESENTATION
ArgParser *args;
std::vector<Material*> materials;
Vec3f background_color;
Camera *camera;
// the bounding box of all rasterized faces in the scene
BoundingBox *bbox;
// the vertices & edges used by all quads (including rasterized primitives)
std::vector<Vertex*> vertices;
edgeshashtype edges;
vphashtype vertex_parents;
// the quads from the .obj file (before subdivision)
std::vector<Face*> original_quads;
// the quads from the .obj file that have non-zero emission value
std::vector<Face*> original_lights;
// all primitives (spheres, etc.)
std::vector<Primitive*> primitives;
// the primitives converted to quads
std::vector<Face*> rasterized_primitive_faces;
// the quads from the .obj file after subdivision
std::vector<Face*> subdivided_quads;
};
// ======================================================================
// ======================================================================
#endif