int R3Mesh:: WriteOff(const char *filename) { // Open file FILE *fp = fopen(filename, "w"); if (!fp) { fprintf(stderr, "Unable to open file %s\n", filename); return 0; } // Write header fprintf(fp, "OFF\n"); fprintf(fp, "%d %d %d\n", NVertices(), NFaces(), 0); // Write vertices for (int i = 0; i < NVertices(); i++) { R3MeshVertex *vertex = Vertex(i); const R3Point& p = vertex->position; fprintf(fp, "%g %g %g\n", p.X(), p.Y(), p.Z()); vertex->id = i; } // Write Faces for (int i = 0; i < NFaces(); i++) { R3MeshFace *face = Face(i); fprintf(fp, "%d", (int) face->vertices.size()); for (unsigned int j = 0; j < face->vertices.size(); j++) { fprintf(fp, " %d", face->vertices[j]->id); } fprintf(fp, "\n"); } // Close file fclose(fp); // Return number of faces return NFaces(); }
R3Mesh:: ~R3Mesh(void) { // Delete faces for (int i = 0; i < NFaces(); i++) { R3MeshFace *f = Face(i); delete f; } // Delete vertices for (int i = 0; i < NVertices(); i++) { R3MeshVertex *v = Vertex(i); delete v; } }
void CurveShape::CollectStats(StatsManager& stats) { StatsCounterVariable* curves = stats.GetVariable<StatsCounterVariable>("Shapes", "Curve Sets"); StatsCounterVariable* segments = stats.GetVariable<StatsCounterVariable>("Shapes", "Curve Segments"); StatsCounterVariable* vertices = stats.GetVariable<StatsCounterVariable>("Shapes", "Curve Segments Vertices"); StatsCounterVariable* memory = stats.GetVariable<StatsCounterVariable>("Shapes", "Memory"); curves->Increment(); segments->Increment(NSegments()); vertices->Increment(NVertices()); memory->Increment(sizeof(*this) + posArray.getMemoryAllocated() + segmentArray.getMemoryAllocated() + (HasVertexTangent())?tangentArray.getMemoryAllocated():0 + (HasVertexRadius())?radiusArray.getMemoryAllocated():0 + (HasVertexTexCoord())?uvArray.getMemoryAllocated():0); }
int R3Mesh:: WriteRay(const char *filename) { // Open file FILE *fp; if (!(fp = fopen(filename, "w"))) { fprintf(stderr, "Unable to open file %s", filename); return 0; } // Write vertices for (int i = 0; i < NVertices(); i++) { R3MeshVertex *vertex = Vertex(i); const R3Point& p = vertex->position; const R3Vector& n = vertex->normal; const R2Point& t = vertex->texcoords; fprintf(fp, "#vertex %g %g %g %g %g %g %g %g\n", p.X(), p.Y(), p.Z(), n.X(), n.Y(), n.Z(), t.X(), t.Y()); vertex->id = i; } // Write faces for (int i = 0; i < NFaces(); i++) { R3MeshFace *face = Face(i); int nvertices = face->vertices.size(); fprintf(fp, "#shape_polygon 0 %d ", nvertices); for (int j = 0; j < nvertices; j++) { R3MeshVertex *v = face->vertices[j]; fprintf(fp, "%d ", v->id); } fprintf(fp, "\n"); } // Close file fclose(fp); // Return number of faces written return NFaces(); }
int R3Mesh:: ReadOff(const char *filename) { // Open file FILE *fp; if (!(fp = fopen(filename, "r"))) { fprintf(stderr, "Unable to open file %s\n", filename); return 0; } // Read file int nverts = 0; int nfaces = 0; int nedges = 0; int line_count = 0; int vertex_count = 0; int face_count = 0; char buffer[1024]; char header[64]; while (fgets(buffer, 1023, fp)) { // Increment line counter line_count++; // Skip white space char *bufferp = buffer; while (isspace(*bufferp)) bufferp++; // Skip blank lines and comments if (*bufferp == '#') continue; if (*bufferp == '\0') continue; // Check section if (nverts == 0) { // Read header keyword if (strstr(bufferp, "OFF")) { // Check if counts are on first line int tmp; if (sscanf(bufferp, "%s%d%d%d", header, &tmp, &nfaces, &nedges) == 4) { nverts = tmp; } } else { // Read counts from second line if ((sscanf(bufferp, "%d%d%d", &nverts, &nfaces, &nedges) != 3) || (nverts == 0)) { fprintf(stderr, "Syntax error reading header on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } } } else if (vertex_count < nverts) { // Read vertex coordinates double x, y, z; if (sscanf(bufferp, "%lf%lf%lf", &x, &y, &z) != 3) { fprintf(stderr, "Syntax error with vertex coordinates on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } // Create vertex CreateVertex(R3Point(x, y, z), R3zero_vector, R2zero_point); // Increment counter vertex_count++; } else if (face_count < nfaces) { // Read number of vertices in face int face_nverts = 0; bufferp = strtok(bufferp, " \t"); if (bufferp) face_nverts = atoi(bufferp); else { fprintf(stderr, "Syntax error with face on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } // Read vertex indices for face vector<R3MeshVertex *> face_vertices; for (int i = 0; i < face_nverts; i++) { R3MeshVertex *v = NULL; bufferp = strtok(NULL, " \t"); if (bufferp) v = Vertex(atoi(bufferp)); else { fprintf(stderr, "Syntax error with face on line %d in file %s\n", line_count, filename); fclose(fp); return 0; } // Add vertex to vector face_vertices.push_back(v); } // Create face CreateFace(face_vertices); // Increment counter face_count++; } else { // Should never get here fprintf(stderr, "Found extra text starting at line %d in file %s\n", line_count, filename); break; } } // Check whether read all vertices if ((vertex_count != nverts) || (NVertices() < nverts)) { fprintf(stderr, "Expected %d vertices, but read %d vertex lines and created %d vertices in file %s\n", nverts, vertex_count, NVertices(), filename); } // Check whether read all faces if ((face_count != nfaces) || (NFaces() < nfaces)) { fprintf(stderr, "Expected %d faces, but read %d face lines and created %d faces in file %s\n", nfaces, face_count, NFaces(), filename); } // Close file fclose(fp); // Return number of faces read return NFaces(); }
void R3Model:: Draw(const R3DrawFlags draw_flags) const { // Check triangles if (!triangles) return; if (triangles->NTriangles() == 0) return; assert(triangle_materials.NEntries() == NTriangles()); assert(material_triangles.NEntries() == NMaterials()); // Draw model if (draw_flags != 0) { # if (DRAW_METHOD == DRAW_WITH_VBO) // Initialize material R3null_material.Draw(TRUE); // Create VBO if (opengl_id == 0) { // Load materials for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Load(); } // Create VBO vertex array VBOVertex *vbo_vertices = new VBOVertex [ NVertices() ]; for (int i = 0; i < NVertices(); i++) { R3TriangleVertex *vertex = Vertex(i); const R3Point& position = vertex->Position(); const R2Point& texcoords = vertex->TextureCoords(); vbo_vertices[i].x = position.X(); vbo_vertices[i].y = position.Y(); vbo_vertices[i].z = position.Z(); vbo_vertices[i].s = texcoords.X(); vbo_vertices[i].t = texcoords.Y(); vertex->SetMark(i); } // Create VBO triangle array GLint *vbo_triangles = new GLint [ 3 * NTriangles() ]; for (int i = 0; i < NTriangles(); i++) { R3Triangle *triangle = Triangle(i); R3TriangleVertex *v0 = triangle->Vertex(0); R3TriangleVertex *v1 = triangle->Vertex(0); R3TriangleVertex *v2 = triangle->Vertex(0); vbo_triangles[3*i+0] = v0->Mark(); vbo_triangles[3*i+1] = v1->Mark(); vbo_triangles[3*i+2] = v2->Mark(); } // Create VBO for vertices glGenBuffers(1, &opengl_id); glBindBuffer(GL_ARRAY_BUFFER, opengl_id); glBufferData(GL_ARRAY_BUFFER, NVertices() * sizeof(VBOVertex), vbo_vertices, GL_STATIC_DRAW); // Create VBO for triangles glGenBuffers(1, &opengl_id2); glBindBuffer(GL_ARRAY_BUFFER, opengl_id2); glBufferData(GL_ELEMENT_BUFFER, 3 * NTriangles() * sizeof(GLuint), vbo_triangles, GL_STATIC_DRAW); // Delete VBO data delete [] vbo_vertices; delete [] vbo_triangles; } // Draw VBO glBindBuffer(GL_ARRAY_BUFFER, opengl_id); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(VBOVertex), (void *) 0); glTexCoordPointer(2, GL_FLOAT, sizeof(VBOVertex), (void *) (3 * sizeof(GLfloat))); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, opengl_id2); glDrawElements(GL_TRIANGLES, NTriangles(), GL_UNSIGNED_INT, (void *) 0); glDisableClientState(GL_VERTEX_ARRAY); glDisableClientState(GL_TEXTURE_COORD_ARRAY); // Reset material R3null_material.Draw(TRUE); # elif (DRAW_METHOD == DRAW_WITH_DISPLAY_LIST) // Initialize material R3null_material.Draw(TRUE); // Create display list if (opengl_id == 0) { // Load materials for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Load(); } // Begin display list R3Model *model = (R3Model *) this; model->opengl_id = glGenLists(1); glNewList(opengl_id, GL_COMPILE); // Draw triangles for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Draw(); glBegin(GL_TRIANGLES); for (int j = 0; j < material_triangles[i]->NEntries(); j++) { R3Triangle *triangle = material_triangles[i]->Kth(j); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadTextureCoords(v0->TextureCoords()); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadTextureCoords(v1->TextureCoords()); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadTextureCoords(v2->TextureCoords()); R3LoadPoint(v2->Position()); } glEnd(); } // End display list glEndList(); } // Call display list glCallList(opengl_id); // Reset material R3null_material.Draw(TRUE); # else // Draw individual triangles for (int i = 0; i < NMaterials(); i++) { R3Material *material = Material(i); material->Draw(); glBegin(GL_TRIANGLES); for (int j = 0; j < material_triangles[i]->NEntries(); j++) { R3Triangle *triangle = material_triangles[i]->Kth(j); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadTextureCoords(v0->TextureCoords()); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadTextureCoords(v1->TextureCoords()); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadTextureCoords(v2->TextureCoords()); R3LoadPoint(v2->Position()); } glEnd(); } # endif } else { // Draw triangles glBegin(GL_TRIANGLES); for (int i = 0; i < NTriangles(); i++) { R3Triangle *triangle = Triangle(i); R3LoadNormal(triangle->Normal()); R3TriangleVertex *v0 = triangle->Vertex(0); R3LoadPoint(v0->Position()); R3TriangleVertex *v1 = triangle->Vertex(1); R3LoadPoint(v1->Position()); R3TriangleVertex *v2 = triangle->Vertex(2); R3LoadPoint(v2->Position()); } glEnd(); } }