diff --git a/build/dust3d.pro b/build/dust3d.pro index 06f8a778..930d75a2 100644 --- a/build/dust3d.pro +++ b/build/dust3d.pro @@ -16,8 +16,8 @@ SOURCES += main.cpp \ bmesh.c \ matrix.c \ convexhull.c \ - tri2quad.c \ - hashtable.c + hashtable.c \ + osutil.cpp HEADERS += mainwindow.h \ render.h \ @@ -27,5 +27,6 @@ HEADERS += mainwindow.h \ bmesh.h \ matrix.h \ convexhull.h \ - tri2quad.h \ - hashtable.h \ No newline at end of file + hashtable.h \ + 3dstruct.h \ + osutil.h \ No newline at end of file diff --git a/src/3dstruct.h b/src/3dstruct.h new file mode 100644 index 00000000..1e0bcb79 --- /dev/null +++ b/src/3dstruct.h @@ -0,0 +1,21 @@ +#ifndef _3DSTRUCT_H +#define _3DSTRUCT_H +#include "vector3d.h" + +typedef struct { + vec3 pt[3]; +} triangle; + +typedef struct { + vec3 pt[4]; +} quad; + +typedef struct face3 { + int indices[3]; +} face3; + +typedef struct face4 { + int indices[4]; +} face4; + +#endif diff --git a/src/bmesh.c b/src/bmesh.c index fd3e2d8b..c07179ba 100644 --- a/src/bmesh.c +++ b/src/bmesh.c @@ -8,7 +8,6 @@ #include "array.h" #include "matrix.h" #include "convexhull.h" -#include "tri2quad.h" #include "draw.h" #define BMESH_STEP_DISTANCE 0.4 @@ -556,6 +555,10 @@ static void addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull, } } +#include "osutil.h" +static int showFaceIndex = 0; +static long long lastShowFaceIndexIncTime = 0; + static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { int result = 0; bmeshBallIterator iterator; @@ -566,7 +569,6 @@ static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { } ball->roundColor = bm->roundColor; if (BMESH_BALL_TYPE_ROOT == ball->type && 4 == ball->index) { - tri2QuadContext *t2q; convexHull *hull; bmeshBall *outmostBall = 0; int outmostBallFirstVertexIndex = 0; @@ -575,12 +577,6 @@ static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { fprintf(stderr, "%s:convexHullCreate failed.\n", __FUNCTION__); return -1; } - t2q = tri2QuadContextCreate(); - if (!t2q) { - fprintf(stderr, "%s:tri2QuadContextCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return -1; - } glColor3f(0.0, 0.0, 0.0); drawDebugPrintf("root <%f,%f,%f>", ball->position.x, ball->position.y, ball->position.z); @@ -600,48 +596,54 @@ static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { } convexHullGenerate(hull); convexHullUnifyNormals(hull, &ball->position); - { - int triIndex; - for (triIndex = 0; triIndex < convexHullGetTriangleNum(hull); - ++triIndex) { - triangle *tri = (triangle *)convexHullGetTriangle(hull, triIndex); - tri2QuadAddTriangle(t2q, tri); - } - } - tri2QuadConvert(t2q); - glPushMatrix(); - /* + if (lastShowFaceIndexIncTime + 300 < osGetMilliseconds()) { + if (showFaceIndex > convexHullGetFace3Num(hull)) { + showFaceIndex = 0; + } else { + showFaceIndex++; + } + lastShowFaceIndexIncTime = osGetMilliseconds(); + } + glColor3f(1.0f, 1.0f, 1.0f); { int triIndex; - for (triIndex = 0; triIndex < convexHullGetTriangleNum(hull); + for (triIndex = 0; triIndex < convexHullGetFace3Num(hull); ++triIndex) { - triangle *tri = (triangle *)convexHullGetTriangle(hull, triIndex); - //if (triIndex > displayTriangleFaceIndex) { - // continue; - //} - drawTriangle(tri); + triangle tri; + face3 *face = (face3 *)convexHullGetFace3(hull, triIndex); + tri.pt[0] = *convexHullGetVertex(hull, face->indices[0]); + tri.pt[1] = *convexHullGetVertex(hull, face->indices[1]); + tri.pt[2] = *convexHullGetVertex(hull, face->indices[2]); + if (triIndex > showFaceIndex) { + break; + } + drawTriangle(&tri); } } glColor3f(0.0f, 0.0f, 0.0f); { int triIndex; int j; - glColor3f(1.0f, 1.0f, 1.0f); - for (triIndex = 0; triIndex < convexHullGetTriangleNum(hull); + for (triIndex = 0; triIndex < convexHullGetFace3Num(hull); ++triIndex) { - triangle *tri = (triangle *)convexHullGetTriangle(hull, triIndex); + triangle tri; + face3 *face = (face3 *)convexHullGetFace3(hull, triIndex); + tri.pt[0] = *convexHullGetVertex(hull, face->indices[0]); + tri.pt[1] = *convexHullGetVertex(hull, face->indices[1]); + tri.pt[2] = *convexHullGetVertex(hull, face->indices[2]); glBegin(GL_LINE_STRIP); for (j = 0; j < 3; ++j) { - glVertex3f(tri->pt[j].x, tri->pt[j].y, tri->pt[j].z); + glVertex3f(tri.pt[j].x, tri.pt[j].y, tri.pt[j].z); } - glVertex3f(tri->pt[0].x, tri->pt[0].y, tri->pt[0].z); + glVertex3f(tri.pt[0].x, tri.pt[0].y, tri.pt[0].z); glEnd(); } } - */ + + /* glColor3f(1.0f, 1.0f, 1.0f); { int triIndex; @@ -698,11 +700,10 @@ static int bmeshStichFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { glVertex3f(q->pt[0].x, q->pt[0].y, q->pt[0].z); glEnd(); } - } + }*/ glPopMatrix(); convexHullDestroy(hull); - tri2QuadContextDestroy(t2q); } for (child = bmeshGetBallFirstChild(bm, ball, &iterator); child; diff --git a/src/convexhull.c b/src/convexhull.c index a0156143..27c0b276 100644 --- a/src/convexhull.c +++ b/src/convexhull.c @@ -4,7 +4,6 @@ #include "convexhull.h" #include "array.h" #include "hashtable.h" -#include "draw.h" // // Implement Gift wrapping method which describled in http://dccg.upc.edu/people/vera/wp-content/uploads/2014/11/GA2014-ConvexHulls3D-Roger-Hernando.pdf @@ -18,19 +17,14 @@ typedef struct { int orderOnPlane; } converHullVertex; -typedef struct face { - int indices[3]; -} face; - struct convexHull { array *vertexArray; array *todoArray; - array *faceArray; + array *face3Array; int nextTodoIndex; unsigned int *openEdgeExistMap; - hashtable *faceHashtable; - face findFace; - triangle returnTriangle; + hashtable *face3Hashtable; + face3 findFace3; }; typedef struct { @@ -39,28 +33,33 @@ typedef struct { int thirdVertex; } todo; -face *convexHullGetFaceByHashtableParam(convexHull *hull, +static int cantorPair(int k1, int k2) { + return (k1 + k2) * (k1 + k2 + 1) / 2 + k2; +} + +face3 *convexHullGetFaceByHashtableParam(convexHull *hull, const void *param) { int index = (char *)param - (char *)0; if (0 == index) { - return &hull->findFace; + return &hull->findFace3; } - return (face *)arrayGetItem(hull->faceArray, index - 1); + return (face3 *)arrayGetItem(hull->face3Array, index - 1); } static int faceHash(void *userData, const void *node) { - face *triIdx = convexHullGetFaceByHashtableParam( + face3 *triIdx = convexHullGetFaceByHashtableParam( (convexHull *)userData, node); - return triIdx->indices[0] * triIdx->indices[1] * triIdx->indices[2]; + return cantorPair(cantorPair(triIdx->indices[0], triIdx->indices[1]), + triIdx->indices[2]); } static int faceCompare(void *userData, const void *node1, const void *node2) { - face *triIdx1 = convexHullGetFaceByHashtableParam( + face3 *triIdx1 = convexHullGetFaceByHashtableParam( (convexHull *)userData, node1); - face *triIdx2 = convexHullGetFaceByHashtableParam( + face3 *triIdx2 = convexHullGetFaceByHashtableParam( (convexHull *)userData, node2); - return memcmp(triIdx1, triIdx2, sizeof(face)); + return memcmp(triIdx1, triIdx2, sizeof(face3)); } convexHull *convexHullCreate(void) { @@ -81,15 +80,15 @@ convexHull *convexHullCreate(void) { convexHullDestroy(hull); return 0; } - hull->faceArray = arrayCreate(sizeof(face)); - if (!hull->faceArray) { + hull->face3Array = arrayCreate(sizeof(face3)); + if (!hull->face3Array) { fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__); convexHullDestroy(hull); return 0; } - hull->faceHashtable = hashtableCreate(TRIANGLE_INDEX_HASHTABLE_SIZE, + hull->face3Hashtable = hashtableCreate(TRIANGLE_INDEX_HASHTABLE_SIZE, faceHash, faceCompare, hull); - if (!hull->faceHashtable) { + if (!hull->face3Hashtable) { fprintf(stderr, "%s:hashtableCreate failed.\n", __FUNCTION__); convexHullDestroy(hull); return 0; @@ -163,9 +162,9 @@ static int sortface(const void *first, const void *second) { return *firstIndex - *secondIndex; } -int convexHullAddFace(convexHull *hull, int firstVertex, int secondVertex, +int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex, int thirdVertex) { - face *tri; + face3 *tri; converHullVertex *vtx1; converHullVertex *vtx2; converHullVertex *vtx3; @@ -191,21 +190,21 @@ int convexHullAddFace(convexHull *hull, int firstVertex, int secondVertex, return 0; } } - memset(&hull->findFace, 0, sizeof(hull->findFace)); - hull->findFace.indices[0] = firstVertex; - hull->findFace.indices[1] = secondVertex; - hull->findFace.indices[2] = thirdVertex; - if (0 == hashtableGet(hull->faceHashtable, 0)) { - qsort(hull->findFace.indices, 3, - sizeof(hull->findFace.indices[0]), sortface); - newTri = arrayGetLength(hull->faceArray); - if (0 != arraySetLength(hull->faceArray, newTri + 1)) { + memset(&hull->findFace3, 0, sizeof(hull->findFace3)); + hull->findFace3.indices[0] = firstVertex; + hull->findFace3.indices[1] = secondVertex; + hull->findFace3.indices[2] = thirdVertex; + qsort(hull->findFace3.indices, 3, + sizeof(hull->findFace3.indices[0]), sortface); + if (0 == hashtableGet(hull->face3Hashtable, 0)) { + newTri = arrayGetLength(hull->face3Array); + if (0 != arraySetLength(hull->face3Array, newTri + 1)) { fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); return -1; } - tri = (face *)arrayGetItem(hull->faceArray, newTri); - *tri = hull->findFace; - if (0 != hashtableInsert(hull->faceHashtable, + tri = (face3 *)arrayGetItem(hull->face3Array, newTri); + *tri = hull->findFace3; + if (0 != hashtableInsert(hull->face3Hashtable, (char *)0 + newTri + 1)) { fprintf(stderr, "%s:hashtableInsert failed.\n", __FUNCTION__); return -1; @@ -222,8 +221,8 @@ static void convexHullReleaseForGenerate(convexHull *hull) { void convexHullDestroy(convexHull *hull) { arrayDestroy(hull->vertexArray); arrayDestroy(hull->todoArray); - arrayDestroy(hull->faceArray); - hashtableDestroy(hull->faceHashtable); + arrayDestroy(hull->face3Array); + hashtableDestroy(hull->face3Hashtable); convexHullReleaseForGenerate(hull); free(hull); } @@ -290,7 +289,8 @@ int convexHullGenerate(convexHull *hull) { todo *t = (todo *)arrayGetItem(hull->todoArray, hull->nextTodoIndex++); index1 = t->firstVertex; index2 = t->secondVertex; - if (convexHullEdgeExsits(hull, index1, index2)) { + if (convexHullEdgeExsits(hull, index1, index2) || + convexHullEdgeExsits(hull, index2, index1)) { continue; } convexHullMarkEdgeAsExsits(hull, index1, index2); @@ -298,8 +298,7 @@ int convexHullGenerate(convexHull *hull) { if (-1 == index3) { continue; } - convexHullAddFace(hull, index1, index2, index3); - convexHullAddTodo(hull, index1, index2, index3); + convexHullAddFace3(hull, index1, index2, index3); convexHullAddTodo(hull, index2, index3, index1); convexHullAddTodo(hull, index3, index1, index2); } @@ -308,9 +307,9 @@ int convexHullGenerate(convexHull *hull) { int convexHullUnifyNormals(convexHull *hull, vec3 *origin) { int i; - for (i = 0; i < arrayGetLength(hull->faceArray); ++i) { - face *triIdx = (face *)arrayGetItem( - hull->faceArray, i); + for (i = 0; i < arrayGetLength(hull->face3Array); ++i) { + face3 *triIdx = (face3 *)arrayGetItem( + hull->face3Array, i); converHullVertex *p1 = (converHullVertex *)arrayGetItem( hull->vertexArray, triIdx->indices[0]); converHullVertex *p2 = (converHullVertex *)arrayGetItem( @@ -330,19 +329,16 @@ int convexHullUnifyNormals(convexHull *hull, vec3 *origin) { return 0; } -int convexHullGetTriangleNum(convexHull *hull) { - return arrayGetLength(hull->faceArray); +face3 *convexHullGetFace3(convexHull *hull, int faceIndex) { + return (face3 *)arrayGetItem(hull->face3Array, faceIndex); } -triangle *convexHullGetTriangle(convexHull *hull, int index) { - int i; - face *triIdx = (face *)arrayGetItem( - hull->faceArray, index); - memset(&hull->returnTriangle, 0, sizeof(hull->returnTriangle)); - for (i = 0; i < 3; ++i) { - converHullVertex *vertex = (converHullVertex *)arrayGetItem( - hull->vertexArray, triIdx->indices[i]); - hull->returnTriangle.pt[i] = vertex->pt; - } - return &hull->returnTriangle; +vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex) { + converHullVertex *vertex = (converHullVertex *)arrayGetItem( + hull->vertexArray, vertexIndex); + return &vertex->pt; +} + +int convexHullGetFace3Num(convexHull *hull) { + return arrayGetLength(hull->face3Array); } diff --git a/src/convexhull.h b/src/convexhull.h index 067d83dc..4d62e0c9 100644 --- a/src/convexhull.h +++ b/src/convexhull.h @@ -1,7 +1,6 @@ #ifndef CONVEX_HULL_H #define CONVEX_HULL_H -#include "vector3d.h" -#include "draw.h" +#include "3dstruct.h" typedef struct convexHull convexHull; convexHull *convexHullCreate(void); @@ -10,8 +9,9 @@ int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane, void convexHullDestroy(convexHull *hull); int convexHullGenerate(convexHull *hull); int convexHullUnifyNormals(convexHull *hull, vec3 *origin); -int convexHullGetTriangleNum(convexHull *hull); -triangle *convexHullGetTriangle(convexHull *hull, int index); +int convexHullGetFace3Num(convexHull *hull); +face3 *convexHullGetFace3(convexHull *hull, int faceIndex); +vec3 *convexHullGetVertex(convexHull *hull, int vertexIndex); int convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, int vertex3); #endif diff --git a/src/draw.h b/src/draw.h index e623c439..450885fd 100644 --- a/src/draw.h +++ b/src/draw.h @@ -1,6 +1,6 @@ #ifndef DRAW_SPHERE_H #define DRAW_SPHERE_H -#include "vector3d.h" +#include "3dstruct.h" #ifdef __APPLE__ #include #else @@ -11,19 +11,6 @@ extern "C" { #endif -typedef struct { - vec3 pt[3]; -} triangle; - -typedef struct { - vec3 pt[4]; -} quad; - -typedef struct { - int npoly; - triangle *poly; -} object; - int drawInit(void); int drawSphere(vec3 *origin, float radius, int slices, int stacks); void drawTriangle(triangle *poly); diff --git a/src/osutil.cpp b/src/osutil.cpp new file mode 100644 index 00000000..744200d4 --- /dev/null +++ b/src/osutil.cpp @@ -0,0 +1,6 @@ +#include "osutil.h" +#include + +long long osGetMilliseconds(void) { + return (long long)QDateTime::currentMSecsSinceEpoch(); +} diff --git a/src/osutil.h b/src/osutil.h new file mode 100644 index 00000000..5450cec9 --- /dev/null +++ b/src/osutil.h @@ -0,0 +1,14 @@ +#ifndef OS_UTIL_H +#define OS_UTIL_H + +#ifdef __cplusplus +extern "C" { +#endif + +long long osGetMilliseconds(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/tri2quad.c b/src/tri2quad.c deleted file mode 100644 index e01c5bde..00000000 --- a/src/tri2quad.c +++ /dev/null @@ -1,324 +0,0 @@ -#include -#include -#include -#include -#include "tri2quad.h" -#include "vector3d.h" -#include "array.h" -#include "hashtable.h" - -#define EDGE_HASHTABLE_SIZE 100 - -typedef struct edge { - vec3 p1; - vec3 p2; - int inputA; - int inputB; - int score; -} edge; - -typedef struct inputTriangle { - triangle tri; - float area; - vec3 normal; - int merged; -} inputTriangle; - -struct tri2QuadContext { - array *inputArray; - array *triangleArray; - array *quadArray; - array *edgeArray; - hashtable *edgeHashtable; - edge findEdge; -}; - -static edge *tri2QuadGetEdgeByHashtableParam(tri2QuadContext *ctx, - const void *param) { - int edgeIndex = (char *)param - (char *)0; - if (0 == edgeIndex) { - return &ctx->findEdge; - } - return (edge *)arrayGetItem(ctx->edgeArray, edgeIndex - 1); -} - -static int edgeHash(void *userData, const void *node) { - edge *e = tri2QuadGetEdgeByHashtableParam((tri2QuadContext *)userData, node); - return (int)(e->p1.x + 1) * (e->p1.y + 1) * (e->p1.z + 1) * - (e->p2.x + 1) * (e->p2.y + 1) * (e->p2.z + 1); -} - -static int edgeCompare(void *userData, const void *node1, const void *node2) { - const edge *e1 = (const edge *)tri2QuadGetEdgeByHashtableParam( - (tri2QuadContext *)userData, node1); - const edge *e2 = (const edge *)tri2QuadGetEdgeByHashtableParam( - (tri2QuadContext *)userData, node2); - if ((0 == memcmp(&e1->p1, &e2->p1, sizeof(e1->p1)) && - 0 == memcmp(&e1->p2, &e2->p2, sizeof(e1->p1))) || - (0 == memcmp(&e1->p1, &e2->p2, sizeof(e1->p1)) && - 0 == memcmp(&e1->p2, &e2->p1, sizeof(e1->p1)))) { - return 0; - } - return -1; -} - -tri2QuadContext *tri2QuadContextCreate(void) { - tri2QuadContext *ctx = (tri2QuadContext *)calloc(1, sizeof(tri2QuadContext)); - if (!ctx) { - fprintf(stderr, "%s:Insufficient memory.", __FUNCTION__); - return 0; - } - ctx->inputArray = arrayCreate(sizeof(inputTriangle)); - if (!ctx->inputArray) { - fprintf(stderr, "%s:arrayCreate failed.", __FUNCTION__); - tri2QuadContextDestroy(ctx); - return 0; - } - ctx->triangleArray = arrayCreate(sizeof(triangle)); - if (!ctx->triangleArray) { - fprintf(stderr, "%s:arrayCreate failed.", __FUNCTION__); - tri2QuadContextDestroy(ctx); - return 0; - } - ctx->quadArray = arrayCreate(sizeof(quad)); - if (!ctx->quadArray) { - fprintf(stderr, "%s:arrayCreate failed.", __FUNCTION__); - tri2QuadContextDestroy(ctx); - return 0; - } - ctx->edgeHashtable = hashtableCreate(EDGE_HASHTABLE_SIZE, edgeHash, - edgeCompare, ctx); - if (!ctx->edgeHashtable) { - fprintf(stderr, "%s:hashtableCreate failed.", __FUNCTION__); - tri2QuadContextDestroy(ctx); - return 0; - } - ctx->edgeArray = arrayCreate(sizeof(edge)); - if (!ctx->edgeArray) { - fprintf(stderr, "%s:arrayCreate failed.", __FUNCTION__); - tri2QuadContextDestroy(ctx); - return 0; - } - return ctx; -} - -int tri2QuadAddTriangle(tri2QuadContext *ctx, triangle *tri) { - int newInputIndex; - inputTriangle *newInput; - newInputIndex = arrayGetLength(ctx->inputArray); - if (0 != arraySetLength(ctx->inputArray, newInputIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.", __FUNCTION__); - return -1; - } - newInput = (inputTriangle *)arrayGetItem(ctx->inputArray, newInputIndex); - newInput->merged = 0; - newInput->tri = *tri; - newInput->area = vec3TriangleArea(&tri->pt[0], &tri->pt[1], &tri->pt[2]); - vec3Normal(&tri->pt[0], &tri->pt[1], &tri->pt[2], &newInput->normal); - return newInputIndex; -} - -static edge *tri2QuadFindEdge(tri2QuadContext *ctx, - vec3 *p1, vec3 *p2) { - int edgeIndex; - ctx->findEdge.p1 = *p1; - ctx->findEdge.p2 = *p2; - edgeIndex = (char *)hashtableGet(ctx->edgeHashtable, (char *)0) - (char *)0; - if (0 == edgeIndex) { - return 0; - } - return (edge *)arrayGetItem(ctx->edgeArray, edgeIndex - 1); -} - -static int tri2QuadAddInitialEdge(tri2QuadContext *ctx, - vec3 *p1, vec3 *p2, int inputIndex) { - edge *existedEdge = tri2QuadFindEdge(ctx, p1, p2); - if (!existedEdge) { - edge *newEdge; - int newEdgeIndex = arrayGetLength(ctx->edgeArray); - if (0 != arraySetLength(ctx->edgeArray, newEdgeIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed(newEdgeIndex:%d).", - __FUNCTION__, newEdgeIndex); - return -1; - } - newEdge = (edge *)arrayGetItem(ctx->edgeArray, newEdgeIndex); - newEdge->p1 = *p1; - newEdge->p2 = *p2; - if (0 != hashtableInsert(ctx->edgeHashtable, - (char *)0 + newEdgeIndex + 1)) { - fprintf(stderr, "%s:hashtableInsert failed.", __FUNCTION__); - return -1; - } - newEdge->inputA = inputIndex; - newEdge->inputB = -1; - newEdge->score = 0; - } else { - existedEdge->inputB = inputIndex; - } - return 0; -} - -static int tri2QuadAddOutputQuad(tri2QuadContext *ctx, vec3 *first, - vec3 *second, vec3 *third, vec3 *fourth) { - quad *q; - int newQuadIndex = arrayGetLength(ctx->quadArray); - if (0 != arraySetLength(ctx->quadArray, newQuadIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed(newQuadIndex:%d).", __FUNCTION__, - newQuadIndex); - return -1; - } - q = (quad *)arrayGetItem(ctx->quadArray, newQuadIndex); - memset(q, 0, sizeof(quad)); - q->pt[0] = *first; - q->pt[1] = *second; - q->pt[2] = *third; - q->pt[3] = *fourth; - return newQuadIndex; -} - -static int tri2QuadAddOutputTriangle(tri2QuadContext *ctx, vec3 *first, - vec3 *second, vec3 *third) { - triangle *tri; - int newTriangleIndex = arrayGetLength(ctx->triangleArray); - if (0 != arraySetLength(ctx->triangleArray, newTriangleIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed(newTriangleIndex:%d).", - __FUNCTION__, newTriangleIndex); - return -1; - } - tri = (triangle *)arrayGetItem(ctx->triangleArray, newTriangleIndex); - memset(tri, 0, sizeof(triangle)); - tri->pt[0] = *first; - tri->pt[1] = *second; - tri->pt[2] = *third; - return newTriangleIndex; -} - -static int tri2QuadAddOutputQuadByEdgeAndInput(tri2QuadContext *ctx, edge *e, - inputTriangle *input1, inputTriangle *input2) { - vec3 outputPt[4]; - int i; - int nextSaveToIndex; - memset(outputPt, 0, sizeof(outputPt)); - nextSaveToIndex = 0; - for (i = 0; i < 3; ++i) { - vec3 *pt = &input1->tri.pt[i]; - if (0 == memcmp(&e->p1, pt, sizeof(e->p1))) { - outputPt[nextSaveToIndex] = *pt; - nextSaveToIndex += 2; - } else if (0 == memcmp(&e->p2, pt, sizeof(e->p2))) { - outputPt[nextSaveToIndex] = *pt; - nextSaveToIndex += 2; - } else { - outputPt[1] = *pt; - } - } - for (i = 0; i < 3; ++i) { - vec3 *pt = &input2->tri.pt[i]; - if (0 != memcmp(&e->p1, pt, sizeof(e->p1)) && - 0 != memcmp(&e->p2, pt, sizeof(e->p2))) { - outputPt[3] = *pt; - break; - } - } - return tri2QuadAddOutputQuad(ctx, &outputPt[0], &outputPt[1], - &outputPt[2], &outputPt[3]); -} - -static int sortEdgeByScoreDesc(const void *first, const void *second) { - const edge *e1 = (const edge *)first; - const edge *e2 = (const edge *)second; - return e2->score - e1->score; -} - -int tri2QuadConvert(tri2QuadContext *ctx) { - int inputIndex; - int edgeIndex; - - for (inputIndex = 0; inputIndex < arrayGetLength(ctx->inputArray); - ++inputIndex) { - inputTriangle *inputItem = (inputTriangle *)arrayGetItem(ctx->inputArray, - inputIndex); - tri2QuadAddInitialEdge(ctx, &inputItem->tri.pt[0], &inputItem->tri.pt[1], - inputIndex); - tri2QuadAddInitialEdge(ctx, &inputItem->tri.pt[1], &inputItem->tri.pt[2], - inputIndex); - tri2QuadAddInitialEdge(ctx, &inputItem->tri.pt[2], &inputItem->tri.pt[0], - inputIndex); - } - for (edgeIndex = 0; edgeIndex < arrayGetLength(ctx->edgeArray); ++edgeIndex) { - edge *e = (edge *)arrayGetItem(ctx->edgeArray, edgeIndex); - inputTriangle *input1; - inputTriangle *input2; - if (-1 != e->inputA && -1 != e->inputB) { - input1 = (inputTriangle *)arrayGetItem(ctx->inputArray, - e->inputA); - input2 = (inputTriangle *)arrayGetItem(ctx->inputArray, - e->inputB); - e->score = (int)((input1->area + input2->area) * - vec3DotProduct(&input1->normal, &input2->normal) * 100); - } - } - qsort(arrayGetItem(ctx->edgeArray, 0), arrayGetLength(ctx->edgeArray), - sizeof(edge), sortEdgeByScoreDesc); - - // - // After qsort, the edge indices inside the hashtable are no longer right. - // - - hashtableDestroy(ctx->edgeHashtable); - ctx->edgeHashtable = 0; - - for (edgeIndex = 0; edgeIndex < arrayGetLength(ctx->edgeArray); ++edgeIndex) { - edge *e = (edge *)arrayGetItem(ctx->edgeArray, edgeIndex); - inputTriangle *input1; - inputTriangle *input2; - if (-1 != e->inputA && -1 != e->inputB) { - input1 = (inputTriangle *)arrayGetItem(ctx->inputArray, - e->inputA); - input2 = (inputTriangle *)arrayGetItem(ctx->inputArray, - e->inputB); - if (!input1->merged && !input2->merged) { - //input1->merged = 1; - //input2->merged = 1; - //tri2QuadAddOutputQuadByEdgeAndInput(ctx, e, input1, input2); - } - } - } - - for (inputIndex = 0; inputIndex < arrayGetLength(ctx->inputArray); - ++inputIndex) { - inputTriangle *inputItem = (inputTriangle *)arrayGetItem(ctx->inputArray, - inputIndex); - if (!inputItem->merged) { - tri2QuadAddOutputTriangle(ctx, &inputItem->tri.pt[0], - &inputItem->tri.pt[1], &inputItem->tri.pt[2]); - } - } - - return 0; -} - -int tri2QuadGetTriangleNum(tri2QuadContext *ctx) { - return arrayGetLength(ctx->triangleArray); -} - -triangle *tri2QuadGetTriangle(tri2QuadContext *ctx, int index) { - return (triangle *)arrayGetItem(ctx->triangleArray, index); -} - -int tri2QuadGetQuadNum(tri2QuadContext *ctx) { - return arrayGetLength(ctx->quadArray); -} - -quad *tri2QuadGetQuad(tri2QuadContext *ctx, int index) { - return (quad *)arrayGetItem(ctx->quadArray, index); -} - -void tri2QuadContextDestroy(tri2QuadContext *ctx) { - arrayDestroy(ctx->inputArray); - arrayDestroy(ctx->triangleArray); - arrayDestroy(ctx->quadArray); - hashtableDestroy(ctx->edgeHashtable); - arrayDestroy(ctx->edgeArray); - free(ctx); -} diff --git a/src/tri2quad.h b/src/tri2quad.h deleted file mode 100644 index f7053b9c..00000000 --- a/src/tri2quad.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef TRI2QUAD_H -#define TRI2QUAD_H -#include "draw.h" - -typedef struct tri2QuadContext tri2QuadContext; - -tri2QuadContext *tri2QuadContextCreate(void); -int tri2QuadAddTriangle(tri2QuadContext *ctx, triangle *tri); -int tri2QuadConvert(tri2QuadContext *ctx); -int tri2QuadGetTriangleNum(tri2QuadContext *ctx); -triangle *tri2QuadGetTriangle(tri2QuadContext *ctx, int index); -int tri2QuadGetQuadNum(tri2QuadContext *ctx); -quad *tri2QuadGetQuad(tri2QuadContext *ctx, int index); -void tri2QuadContextDestroy(tri2QuadContext *ctx); - -#endif -