#include #include #include #include "../include/global.h" #include "../include/change.h" #define MAX_NUM_TRI 250 using namespace VMI; std::vector VMI::mVMISteps; Change *VMI::createChange (Mesh *mesh, int e) { Change *c; c = (Change*) malloc (sizeof(Change)); if (NULL == c) { fprintf (stderr, "no more memory for mesh changes"); exit(1); } c->e = e; c->u = mesh->edges[e].u; c->v = mesh->edges[e].v; c->modified = NULL; c->deleted = NULL; c->numDel = 0; c->numMod = 0; return c; } void VMI::deleteChange(Change *c) { if (NULL != c) { if (c->deleted != NULL) free(c->deleted); if (c->modified != NULL) free(c->modified); c->modified = NULL; c->deleted = NULL; c->numDel = 0; c->numMod = 0; free(c); c = NULL; } } void VMI::writeChange(FILE* file, Change *c) { int i; fputc('v',file); fputc('%',file); fprintf(file, " %d %d 0 0 0 ", c->v, c->u); for (i=0; inumDel; i++) { fprintf(file, "%d ", c->deleted[i].id); } fputc('&',file); for (i=0; inumMod; i++) { fprintf(file, " %d", c->modified[i].id); } fputc('\n',file); } void VMI::printChange(Change *c) { int i; if (NULL != c) { printf("e%d(%d,%d)\n",c->e,c->u,c->v); printf("d %d\n", c->numDel); for (i=0;inumDel;i++) { printf(" %d", c->deleted[i].id); } printf("\n"); printf("m %d\n", c->numMod); for (i=0;inumMod;i++) { printf(" %d", c->modified[i].id); } printf("\n"); } } void VMI::modifyTriangle(Triangle *t, int c, int p) { if ((int)t->indices[0] == c) t->indices[0]= p; if ((int)t->indices[1] == c) t->indices[1]= p; if ((int)t->indices[2] == c) t->indices[2]= p; } int VMI::isATriangleToModify(Triangle *t, int c, int p) { int u = t->indices[0], v = t->indices[1], w = t->indices[2]; if ((u == c) || (v == c) || (w == c)) return TRUE; return FALSE; } void VMI::modifyTriangles(Mesh *mesh, Change *c) { int i, t; for (i=0; inumMod; i++) { t = c->modified[i].id; modifyTriangle(&mesh->triangles[t], c->u, c->v); //printf("New area of triangle %d:\n", t); mesh->triangles[t].area = computeTriangleArea(mesh->vertices, &mesh->triangles[t]); computeTriangleNormal(mesh->vertices, &mesh->triangles[t]); } } void VMI::unmodifyTriangles(Mesh *mesh, Change *c) { int i, t; for (i=0; inumMod; i++) { t = c->modified[i].id; memcpy(&mesh->triangles[t], &c->modified[i], sizeof(Triangle)); /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0], mesh->triangles[t].indices[1], mesh->triangles[t].indices[2]);*/ } } void VMI::deleteTriangles(Mesh *mesh, Change *c) { int i, t; for (i=0; inumDel; i++) { t = c->deleted[i].id; //printf("Deleting triangle %d\n",t); mesh->triangles[t].enable = FALSE; mesh->currentNumTriangles--; } } void VMI::undeleteTriangles(Mesh *mesh, Change *c) { int i, t; for (i=0; inumDel; i++) { t = c->deleted[i].id; memcpy(&mesh->triangles[t], &c->deleted[i], sizeof(Triangle)); /*printf("t(%d %d %d)\n", mesh->triangles[t].indices[0], mesh->triangles[t].indices[1], mesh->triangles[t].indices[2]);*/ mesh->triangles[t].enable = TRUE; mesh->currentNumTriangles++; } } int VMI::getTrianglesToModify(Mesh *mesh, int c, int p, Triangle *modified) { GLuint i, num = 0; for (i=0; inumTriangles; i++) { if ((mesh->triangles[i].enable == TRUE) && isATriangleToModify(&mesh->triangles[i], c, p)) { //printf("Triangle to modify %d\n", i); // Save the original values of the triangle memcpy(&modified[num], &mesh->triangles[i], sizeof(Triangle)); num++; } } return num; } int VMI::isATriangleToDelete(Triangle *t, int c, int p) { int u = t->indices[0], v = t->indices[1], w = t->indices[2]; if (((u == c) && ( v == p)) || ((u == c) && ( w == p)) || ((v == c) && ( w == p))) return TRUE; if (((u == p) && ( v == c)) || ((u == p) && ( w == c)) || ((v == p) && ( w == c))) return TRUE; return FALSE; } int VMI::getTrianglesToDelete(Mesh *mesh, int numMod, Triangle *modified, Triangle *deleted, int c, int p) { int i, num = 0; GLuint t; for (i=0; itriangles[t], c, p)) { //printf("Triangle to delete %d\n",t); memcpy(&deleted[num], &modified[i], sizeof(Triangle)); num++; } } return num; } void VMI::printList(Triangle *list, int n) { int i; for (i=0; iu, c->v, m); int numDel = getTrianglesToDelete(mesh, numMod, m, d, c->u, c->v); int i; //printf("d %d\n",numDel); //printList(d, numDel); for (i=0; inumDel = numDel; // Free memory if (c->deleted != NULL) free(c->deleted); // Allocate memory c->deleted = (Triangle *)malloc(sizeof(Triangle) * numDel); if (c->deleted == NULL) { fprintf(stderr, "Error allocating memory\n"); exit(1); } memcpy(c->deleted, d, sizeof(Triangle) * numDel); c->numMod = numMod; // Free memory if (c->modified != NULL) free(c->modified); // Allocate memory c->modified = (Triangle *)malloc(sizeof(Triangle) * numMod); if (c->modified == NULL) { fprintf(stderr, "Error allocating memory\n"); exit(1); } memcpy(c->modified, m, sizeof(Triangle) * numMod); //printChange(c); //getchar(); } // Update the triangle mesh due to a heap node simplification void VMI::doChange(Mesh *mesh, Change *c) { modifyTriangles(mesh, c); deleteTriangles(mesh, c); mesh->vertices[c->u].enable = FALSE; mesh->currentNumVertices--; } void VMI::undoChange(Mesh *mesh, Change *c) { unmodifyTriangles(mesh, c); undeleteTriangles(mesh, c); mesh->vertices[c->u].enable = TRUE; mesh->currentNumVertices++; } // Save simplification sequence in Geometry Game Tools format. extern void VMI::saveSimplificationSequence(Change *c) { vmiStep step; step.mV0 = c->u; step.mV1 = c->v; // If only one triangle has been deleted. if (c->numDel == 1) { step.mT0 = c->deleted[0].id; step.mT1 = c->deleted[0].id; } // If two triangles have been deleted. else { step.mT0 = c->deleted[0].id; step.mT1 = c->deleted[1].id; } step.x = 0.0; step.y = 0.0; step.z = 0.0; // Write obligatory field. step.obligatory = 0; // List of new triangles. // For each modified triangle. for (int i = 0; i < c->numMod; i++) { step.mModfaces.push_back(c->modified[i].id); } // Add step to list of changes. mVMISteps.push_back(step); }