From a4569fbe1ef2c94ab38c38a2134bcc5354aa4942 Mon Sep 17 00:00:00 2001 From: Jeremy Hu Date: Tue, 31 Jan 2017 08:26:24 +0930 Subject: [PATCH] Handle out of memory in one place --- build/dust3d.pro | 10 +- src/array.c | 35 ++- src/array.h | 4 +- src/bmesh.c | 429 +++++++----------------------------- src/convexhull.c | 334 +++++++--------------------- src/convexhull.h | 8 +- src/{hashtable.c => dict.c} | 129 ++++++++--- src/dict.h | 16 ++ src/dmemory.c | 36 +++ src/dmemory.h | 9 + src/hashtable.h | 15 -- src/render.cpp | 2 +- src/subdivide.c | 246 ++++----------------- src/subdivide.h | 4 +- 14 files changed, 390 insertions(+), 887 deletions(-) rename src/{hashtable.c => dict.c} (51%) create mode 100644 src/dict.h create mode 100644 src/dmemory.c create mode 100644 src/dmemory.h delete mode 100644 src/hashtable.h diff --git a/build/dust3d.pro b/build/dust3d.pro index 843a5723..c3509d64 100644 --- a/build/dust3d.pro +++ b/build/dust3d.pro @@ -16,10 +16,11 @@ SOURCES += main.cpp \ bmesh.c \ matrix.c \ convexhull.c \ - hashtable.c \ + dict.c \ osutil.cpp \ subdivide.c \ - skinnedmesh.c + skinnedmesh.c \ + dmemory.c HEADERS += mainwindow.h \ render.h \ @@ -29,8 +30,9 @@ HEADERS += mainwindow.h \ bmesh.h \ matrix.h \ convexhull.h \ - hashtable.h \ + dict.h \ 3dstruct.h \ osutil.h \ subdivide.h \ - skinnedmesh.h \ No newline at end of file + skinnedmesh.h \ + dmemory.h \ No newline at end of file diff --git a/src/array.c b/src/array.c index b5abdee4..fb050a81 100644 --- a/src/array.c +++ b/src/array.c @@ -1,6 +1,7 @@ #include #include #include +#include "dmemory.h" #include "array.h" struct array { @@ -11,34 +12,29 @@ struct array { }; array *arrayCreate(int nodeSize) { - array *arr = (array *)calloc(1, sizeof(array)); - if (!arr) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } + array *arr = dcalloc(1, sizeof(array)); arr->nodeSize = nodeSize; return arr; } -int arraySetLength(array *arr, int length) { +int arrayGetNodeSize(array *arr) { + return arr->nodeSize; +} + +void arraySetLength(array *arr, int length) { char *newNodes; if (length > arr->capacity) { int newCapacity = (arr->capacity + 1) * 2; if (newCapacity < length) { newCapacity = length; } - newNodes = (char *)realloc(arr->nodes, arr->nodeSize * newCapacity); - if (!newNodes) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return -1; - } + newNodes = drealloc(arr->nodes, arr->nodeSize * newCapacity); memset(newNodes + arr->nodeSize * arr->capacity, 0, arr->nodeSize * (newCapacity - arr->capacity)); arr->capacity = newCapacity; arr->nodes = newNodes; } arr->length = length; - return 0; } void *arrayGetItem(array *arr, int index) { @@ -54,16 +50,19 @@ int arrayGetLength(array *arr) { void arrayDestroy(array *arr) { if (arr) { - free(arr->nodes); - free(arr); + dfree(arr->nodes); + dfree(arr); } } void *arrayNewItem(array *arr) { int newIndex = arrayGetLength(arr); - if (0 != arraySetLength(arr, newIndex + 1)) { - fprintf(stderr, "%s:arraySetLength.\n", __FUNCTION__); - return 0; - } + arraySetLength(arr, newIndex + 1); return arrayGetItem(arr, newIndex); } + +void *arrayNewItemClear(array *arr) { + void *ptr = arrayNewItem(arr); + memset(ptr, 0, arr->nodeSize); + return ptr; +} diff --git a/src/array.h b/src/array.h index 8ab8350d..e4189cf1 100644 --- a/src/array.h +++ b/src/array.h @@ -8,10 +8,12 @@ extern "C" { typedef struct array array; array *arrayCreate(int nodeSize); +int arrayGetNodeSize(array *arr); void *arrayGetItem(array *arr, int index); int arrayGetLength(array *arr); -int arraySetLength(array *arr, int length); +void arraySetLength(array *arr, int length); void *arrayNewItem(array *arr); +void *arrayNewItemClear(array *arr); void arrayDestroy(array *arr); #ifdef __cplusplus diff --git a/src/bmesh.c b/src/bmesh.c index 966cd221..f40cacf3 100644 --- a/src/bmesh.c +++ b/src/bmesh.c @@ -4,9 +4,10 @@ #include #include #include +#include "dmemory.h" #include "bmesh.h" #include "array.h" -#include "hashtable.h" +#include "dict.h" #include "matrix.h" #include "convexhull.h" #include "subdivide.h" @@ -37,97 +38,50 @@ struct bmesh { subdivModel *model; subdivModel *subdivModel; array *modelVertexArray; - hashtable *modelVertexHashtable; + dict *modelVertexDict; bmeshModelVertex findModelVertex; }; static bmeshModelVertex *bmeshFindModelVertex(bmesh *bm, vec3 *vertex) { - int index; - bm->findModelVertex.vertex = *vertex; - index = (char *)hashtableGet(bm->modelVertexHashtable, (char *)0) - (char *)0; - if (0 == index) { - return 0; - } - return (bmeshModelVertex *)arrayGetItem(bm->modelVertexArray, index - 1); + return dictFind(bm->modelVertexDict, vertex); } static int bmeshAddModelVertex(bmesh *bm, vec3 *vertex) { bmeshModelVertex *v = bmeshFindModelVertex(bm, vertex); if (!v) { - v = (bmeshModelVertex *)arrayNewItem(bm->modelVertexArray); - if (!v) { - fprintf(stderr, "%s:arrayNewItem failed.\n", __FUNCTION__); - return -1; - } - memset(v, 0, sizeof(bmeshModelVertex)); + v = dictGetClear(bm->modelVertexDict, vertex); v->vertex = *vertex; v->indexOnModel = subdivAddVertex(bm->model, &v->vertex); - if (-1 == hashtableInsert(bm->modelVertexHashtable, - (char *)0 + arrayGetLength(bm->modelVertexArray))) { - fprintf(stderr, "%s:hashtableInsert failed.\n", __FUNCTION__); - return -1; - } } return v->indexOnModel; } -static int bmeshAddQuadToModel(bmesh *bm, quad *q) { +static void bmeshAddQuadToModel(bmesh *bm, quad *q) { int indices[4]; indices[0] = bmeshAddModelVertex(bm, &q->pt[0]); indices[1] = bmeshAddModelVertex(bm, &q->pt[1]); indices[2] = bmeshAddModelVertex(bm, &q->pt[2]); indices[3] = bmeshAddModelVertex(bm, &q->pt[3]); - if (-1 == indices[0] || -1 == indices[1] || -1 == indices[2] || - -1 == indices[3]) { - fprintf(stderr, "%s:bmeshAddModelVertex failed.\n", __FUNCTION__); - return -1; - } - if (-1 == subdivAddQuadFace(bm->model, indices[0], indices[1], indices[2], - indices[3])) { - fprintf(stderr, "%s:subdivAddQuadFace failed.\n", __FUNCTION__); - return -1; - } - return 0; + subdivAddQuadFace(bm->model, indices[0], indices[1], indices[2], indices[3]); } -static int bmeshAddTriangleToModel(bmesh *bm, triangle *t) { +static void bmeshAddTriangleToModel(bmesh *bm, triangle *t) { int indices[3]; indices[0] = bmeshAddModelVertex(bm, &t->pt[0]); indices[1] = bmeshAddModelVertex(bm, &t->pt[1]); indices[2] = bmeshAddModelVertex(bm, &t->pt[2]); - if (-1 == indices[0] || -1 == indices[1] || -1 == indices[2]) { - fprintf(stderr, "%s:bmeshAddModelVertex failed.\n", __FUNCTION__); - return -1; - } - if (-1 == subdivAddTriangleFace(bm->model, indices[0], indices[1], - indices[2])) { - fprintf(stderr, "%s:subdivAddTriangleFace failed.\n", __FUNCTION__); - return -1; - } - return 0; -} - -bmeshModelVertex *bmeshGetModelVertexByHashtableParam(void *userData, - const void *node) { - bmesh *bm = (bmesh *)userData; - int index = (char *)node - (char *)0; - if (0 == index) { - return &bm->findModelVertex; - } - return (bmeshModelVertex *)arrayGetItem(bm->modelVertexArray, index - 1); + subdivAddTriangleFace(bm->model, indices[0], indices[1], indices[2]); } static int modelVertexHash(void *userData, const void *node) { - bmeshModelVertex *v = bmeshGetModelVertexByHashtableParam(userData, node); + const bmeshModelVertex *v = node; return abs(*((int *)v)); } static int modelVertexCompare(void *userData, const void *firstNode, const void *secondNode) { - bmeshModelVertex *v1 = bmeshGetModelVertexByHashtableParam(userData, - firstNode); - bmeshModelVertex *v2 = bmeshGetModelVertexByHashtableParam(userData, - secondNode); + const bmeshModelVertex *v1 = firstNode; + const bmeshModelVertex *v2 = secondNode; if (0 == v1->vertex.x - v2->vertex.x && 0 == v1->vertex.y - v2->vertex.y && 0 == v1->vertex.z - v2->vertex.z) { @@ -137,54 +91,16 @@ static int modelVertexCompare(void *userData, const void *firstNode, } bmesh *bmeshCreate(void) { - bmesh *bm = (bmesh *)calloc(1, sizeof(bmesh)); - if (!bm) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } + bmesh *bm = dcalloc(1, sizeof(bmesh)); bm->ballArray = arrayCreate(sizeof(bmeshBall)); - if (!bm->ballArray) { - fprintf(stderr, "%s:arrayCreate bmeshBall failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } bm->boneArray = arrayCreate(sizeof(bmeshBone)); - if (!bm->boneArray) { - fprintf(stderr, "%s:arrayCreate bmeshBone failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } bm->indexArray = arrayCreate(sizeof(bmeshBallIndex)); - if (!bm->indexArray) { - fprintf(stderr, "%s:arrayCreate bmeshBallIndex failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } bm->quadArray = arrayCreate(sizeof(quad)); - if (!bm->quadArray) { - fprintf(stderr, "%s:arrayCreate quad failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } bm->model = subdivCreateModel(); - if (!bm->model) { - fprintf(stderr, "%s:subdivCreateModel failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } bm->modelVertexArray = arrayCreate(sizeof(bmeshModelVertex)); - if (!bm->modelVertexArray) { - fprintf(stderr, "%s:arrayCreate quad failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } - bm->modelVertexHashtable = hashtableCreate(BMESH_MODEL_VERTEX_HASHTABLE_SIZE, + bm->modelVertexDict = dictCreate(bm->modelVertexArray, + BMESH_MODEL_VERTEX_HASHTABLE_SIZE, modelVertexHash, modelVertexCompare, bm); - if (!bm->modelVertexHashtable) { - fprintf(stderr, "%s:hashtableCreate quad failed.\n", __FUNCTION__); - bmeshDestroy(bm); - return 0; - } bm->rootBallIndex = -1; bm->roundColor = 0; return bm; @@ -198,8 +114,8 @@ void bmeshDestroy(bmesh *bm) { subdivDestroyModel(bm->model); subdivDestroyModel(bm->subdivModel); arrayDestroy(bm->modelVertexArray); - hashtableDestroy(bm->modelVertexHashtable); - free(bm); + dictDestroy(bm->modelVertexDict); + dfree(bm); } int bmeshGetBallNum(bmesh *bm) { @@ -211,11 +127,11 @@ int bmeshGetBoneNum(bmesh *bm) { } bmeshBall *bmeshGetBall(bmesh *bm, int index) { - return (bmeshBall *)arrayGetItem(bm->ballArray, index); + return arrayGetItem(bm->ballArray, index); } bmeshBone *bmeshGetBone(bmesh *bm, int index) { - return (bmeshBone *)arrayGetItem(bm->boneArray, index); + return arrayGetItem(bm->boneArray, index); } int bmeshAddBall(bmesh *bm, bmeshBall *ball) { @@ -224,10 +140,7 @@ int bmeshAddBall(bmesh *bm, bmeshBall *ball) { ball->firstChildIndex = -1; ball->childrenIndices = 0; ball->notFitHull = 0; - if (0 != arraySetLength(bm->ballArray, index + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } + arraySetLength(bm->ballArray, index + 1); memcpy(arrayGetItem(bm->ballArray, index), ball, sizeof(bmeshBall)); if (BMESH_BALL_TYPE_ROOT == ball->type) { bm->rootBallIndex = index; @@ -235,41 +148,26 @@ int bmeshAddBall(bmesh *bm, bmeshBall *ball) { return index; } -static int bmeshAddChildBallRelation(bmesh *bm, int parentBallIndex, +static void bmeshAddChildBallRelation(bmesh *bm, int parentBallIndex, int childBallIndex) { bmeshBall *parentBall = bmeshGetBall(bm, parentBallIndex); bmeshBallIndex *indexItem; int newChildIndex = arrayGetLength(bm->indexArray); - if (0 != arraySetLength(bm->indexArray, newChildIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } - indexItem = (bmeshBallIndex *)arrayGetItem(bm->indexArray, newChildIndex); + arraySetLength(bm->indexArray, newChildIndex + 1); + indexItem = arrayGetItem(bm->indexArray, newChildIndex); indexItem->ballIndex = childBallIndex; indexItem->nextChildIndex = parentBall->firstChildIndex; parentBall->firstChildIndex = newChildIndex; parentBall->childrenIndices++; - return 0; } int bmeshAddBone(bmesh *bm, bmeshBone *bone) { int index = arrayGetLength(bm->boneArray); bone->index = index; - if (0 != arraySetLength(bm->boneArray, index + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } + arraySetLength(bm->boneArray, index + 1); memcpy(arrayGetItem(bm->boneArray, index), bone, sizeof(bmeshBone)); - if (0 != bmeshAddChildBallRelation(bm, bone->firstBallIndex, - bone->secondBallIndex)) { - fprintf(stderr, "%s:bmeshAddChildBallRelation failed.\n", __FUNCTION__); - return -1; - } - if (0 != bmeshAddChildBallRelation(bm, bone->secondBallIndex, - bone->firstBallIndex)) { - fprintf(stderr, "%s:bmeshAddChildBallRelation failed.\n", __FUNCTION__); - return -1; - } + bmeshAddChildBallRelation(bm, bone->firstBallIndex, bone->secondBallIndex); + bmeshAddChildBallRelation(bm, bone->secondBallIndex, bone->firstBallIndex); return index; } @@ -283,79 +181,21 @@ static int bmeshAddInbetweenBallBetween(bmesh *bm, secondBall->radius * frac; vec3Lerp(&firstBall->position, &secondBall->position, frac, &newBall.position); - if (-1 == bmeshAddBall(bm, &newBall)) { - fprintf(stderr, "%s:bmeshAddBall failed.\n", __FUNCTION__); - return -1; - } - if (-1 == bmeshAddChildBallRelation(bm, parentBallIndex, newBall.index)) { - fprintf(stderr, "%s:bmeshAddChildBallRelation failed.\n", __FUNCTION__); - return -1; - } + bmeshAddBall(bm, &newBall); + bmeshAddChildBallRelation(bm, parentBallIndex, newBall.index); return newBall.index; } -/* -static int bmeshGenerateBallCrossSection(bmesh *bm, bmeshBall *ball, - vec3 *boneDirection, vec3 *localYaxis, vec3 *localZaxis) { - //int i; - //quad q; - vec3 z, y; - //vec3Scale(localYaxis, ball->radius, &y); - //vec3Scale(localZaxis, ball->radius, &z); - vec3Sub(&ball->position, &y, &q.pt[0]); - vec3Add(&q.pt[0], &z, &q.pt[0]); - vec3Sub(&ball->position, &y, &q.pt[1]); - vec3Sub(&q.pt[1], &z, &q.pt[1]); - vec3Add(&ball->position, &y, &q.pt[2]); - vec3Sub(&q.pt[2], &z, &q.pt[2]); - vec3Add(&ball->position, &y, &q.pt[3]); - vec3Add(&q.pt[3], &z, &q.pt[3]); - ball->crossSection = q; - ball->boneDirection = *boneDirection; - if (-1 == bmeshAddQuad(bm, &q)) { - fprintf(stderr, "%s:meshAddQuad failed.\n", __FUNCTION__); - return -1; - } - if (connectWithQuad >= 0) { - for (i = 0; i < 4; ++i) { - quad face; - quad *lastQ = bmeshGetQuad(bm, connectWithQuad); - face.pt[0].x = lastQ->pt[(0 + i) % 4].x; - face.pt[0].y = lastQ->pt[(0 + i) % 4].y; - face.pt[0].z = lastQ->pt[(0 + i) % 4].z; - face.pt[1].x = q.pt[(0 + i) % 4].x; - face.pt[1].y = q.pt[(0 + i) % 4].y; - face.pt[1].z = q.pt[(0 + i) % 4].z; - face.pt[2].x = q.pt[(1 + i) % 4].x; - face.pt[2].y = q.pt[(1 + i) % 4].y; - face.pt[2].z = q.pt[(1 + i) % 4].z; - face.pt[3].x = lastQ->pt[(1 + i) % 4].x; - face.pt[3].y = lastQ->pt[(1 + i) % 4].y; - face.pt[3].z = lastQ->pt[(1 + i) % 4].z; - if (-1 == bmeshAddQuad(bm, &face)) { - fprintf(stderr, "%s:meshAddQuad failed.\n", __FUNCTION__); - return -1; - } - } - } - return 0; -}*/ - static void generateYZfromBoneDirection(vec3 *boneDirection, vec3 *localYaxis, vec3 *localZaxis) { vec3 worldYaxis = {0, 1, 0}; - vec3 worldXaxis = {1, 0, 0}; - //if (0 == vec3Angle(boneDirection, &worldYaxis)) { - // vec3CrossProduct(&worldXaxis, boneDirection, localYaxis); - //} else { - vec3CrossProduct(&worldYaxis, boneDirection, localYaxis); - //} + vec3CrossProduct(&worldYaxis, boneDirection, localYaxis); vec3Normalize(localYaxis); vec3CrossProduct(localYaxis, boneDirection, localZaxis); vec3Normalize(localZaxis); } -static int bmeshGenerateInbetweenBallsBetween(bmesh *bm, +static void bmeshGenerateInbetweenBallsBetween(bmesh *bm, int firstBallIndex, int secondBallIndex) { float step; float distance; @@ -368,8 +208,9 @@ static int bmeshGenerateInbetweenBallsBetween(bmesh *bm, bmeshBall *secondBall = bmeshGetBall(bm, secondBallIndex); bmeshBall *newBall; float intvalDist; + if (secondBall->roundColor == bm->roundColor) { - return 0; + return; } vec3Sub(&firstBall->position, &secondBall->position, &boneDirection); @@ -392,9 +233,6 @@ static int bmeshGenerateInbetweenBallsBetween(bmesh *bm, float frac = offset / distance; parentBallIndex = bmeshAddInbetweenBallBetween(bm, firstBall, secondBall, frac, parentBallIndex); - if (-1 == parentBallIndex) { - return -1; - } newBall = bmeshGetBall(bm, parentBallIndex); newBall->localYaxis = localYaxis; newBall->localZaxis = localZaxis; @@ -404,20 +242,13 @@ static int bmeshGenerateInbetweenBallsBetween(bmesh *bm, } else if (distance > step) { parentBallIndex = bmeshAddInbetweenBallBetween(bm, firstBall, secondBall, 0.5, parentBallIndex); - if (-1 == parentBallIndex) { - return -1; - } newBall = bmeshGetBall(bm, parentBallIndex); newBall->localYaxis = localYaxis; newBall->localZaxis = localZaxis; newBall->boneDirection = normalizedBoneDirection; } } - if (-1 == bmeshAddChildBallRelation(bm, parentBallIndex, secondBallIndex)) { - fprintf(stderr, "%s:bmeshAddChildBallRelation failed.\n", __FUNCTION__); - return -1; - } - return 0; + bmeshAddChildBallRelation(bm, parentBallIndex, secondBallIndex); } bmeshBall *bmeshGetBallFirstChild(bmesh *bm, bmeshBall *ball, @@ -435,7 +266,7 @@ bmeshBall *bmeshGetBallNextChild(bmesh *bm, bmeshBall *ball, if (-1 == *iterator) { return 0; } - indexItem = (bmeshBallIndex *)arrayGetItem(bm->indexArray, *iterator); + indexItem = arrayGetItem(bm->indexArray, *iterator); *iterator = indexItem->nextChildIndex; return bmeshGetBall(bm, indexItem->ballIndex); } @@ -447,7 +278,7 @@ bmeshBall *bmeshGetRootBall(bmesh *bm) { return bmeshGetBall(bm, bm->rootBallIndex); } -static int bmeshGenerateInbetweenBallsFrom(bmesh *bm, int parentBallIndex) { +static void bmeshGenerateInbetweenBallsFrom(bmesh *bm, int parentBallIndex) { bmeshBallIterator iterator; int ballIndex; bmeshBall *parent; @@ -456,8 +287,9 @@ static int bmeshGenerateInbetweenBallsFrom(bmesh *bm, int parentBallIndex) { parent = bmeshGetBall(bm, parentBallIndex); if (parent->roundColor == bm->roundColor) { - return 0; + return; } + parent->roundColor = bm->roundColor; // @@ -471,26 +303,11 @@ static int bmeshGenerateInbetweenBallsFrom(bmesh *bm, int parentBallIndex) { oldChildrenIndices = parent->childrenIndices; parent->childrenIndices = 0; - for (; - ball; - ball = bmeshGetBallNextChild(bm, parent, &iterator)) { + for (; ball; ball = bmeshGetBallNextChild(bm, parent, &iterator)) { ballIndex = ball->index; - if (0 != bmeshGenerateInbetweenBallsBetween(bm, parentBallIndex, - ballIndex)) { - fprintf(stderr, - "%s:bmeshGenerateInbetweenBallsBetween failed(parentBallIndex:%d).\n", - __FUNCTION__, parentBallIndex); - return -1; - } - if (0 != bmeshGenerateInbetweenBallsFrom(bm, ballIndex)) { - fprintf(stderr, - "%s:bmeshGenerateInbetweenBallsFrom failed(ballIndex:%d).\n", - __FUNCTION__, ballIndex); - return -1; - } + bmeshGenerateInbetweenBallsBetween(bm, parentBallIndex, ballIndex); + bmeshGenerateInbetweenBallsFrom(bm, ballIndex); } - - return 0; } int bmeshGenerateInbetweenBalls(bmesh *bm) { @@ -499,7 +316,8 @@ int bmeshGenerateInbetweenBalls(bmesh *bm) { return -1; } bm->roundColor++; - return bmeshGenerateInbetweenBallsFrom(bm, bm->rootBallIndex); + bmeshGenerateInbetweenBallsFrom(bm, bm->rootBallIndex); + return 0; } int bmeshGetQuadNum(bmesh *bm) { @@ -507,25 +325,21 @@ int bmeshGetQuadNum(bmesh *bm) { } quad *bmeshGetQuad(bmesh *bm, int index) { - return (quad *)arrayGetItem(bm->quadArray, index); + return arrayGetItem(bm->quadArray, index); } int bmeshAddQuad(bmesh *bm, quad *q) { int index = arrayGetLength(bm->quadArray); - if (0 != arraySetLength(bm->quadArray, index + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } + arraySetLength(bm->quadArray, index + 1); memcpy(arrayGetItem(bm->quadArray, index), q, sizeof(quad)); return index; } -static int bmeshSweepFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { - int result = 0; +static void bmeshSweepFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { bmeshBallIterator iterator; bmeshBall *child = 0; if (bm->roundColor == ball->roundColor) { - return 0; + return; } ball->roundColor = bm->roundColor; if (BMESH_BALL_TYPE_KEY == ball->type) { @@ -555,18 +369,14 @@ static int bmeshSweepFrom(bmesh *bm, bmeshBall *parent, bmeshBall *ball) { for (child = bmeshGetBallFirstChild(bm, ball, &iterator); child; child = bmeshGetBallNextChild(bm, ball, &iterator)) { - result = bmeshSweepFrom(bm, ball, child); - if (0 != result) { - fprintf(stderr, "%s:bmeshSweepFrom failed.\n", __FUNCTION__); - return result; - } + bmeshSweepFrom(bm, ball, child); } - return result; } int bmeshSweep(bmesh *bm) { bm->roundColor++; - return bmeshSweepFrom(bm, 0, bmeshGetRootBall(bm)); + bmeshSweepFrom(bm, 0, bmeshGetRootBall(bm)); + return 0; } static int isDistanceEnoughForConvexHull(bmeshBall *root, @@ -609,7 +419,7 @@ static bmeshBall *bmeshFindParentBallForConvexHull(bmesh *bm, bmeshBall *root, bm->parentBallStack[depth - 1]); } -static int addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull, +static void addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull, bmeshBall **outmostBall, int *outmostBallFirstVertexIndex) { vec3 z, y; quad q; @@ -635,11 +445,6 @@ static int addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull, ballForConvexHull->index, 2); vertexIndex[3] = convexHullAddVertex(hull, &q.pt[3], ballForConvexHull->index, 3); - if (-1 == vertexIndex[0] || -1 == vertexIndex[1] || -1 == vertexIndex[2] || - -1 == vertexIndex[3]) { - fprintf(stderr, "%s:convexHullAddVertex failed.\n", __FUNCTION__); - return -1; - } if (*outmostBall) { if (ballForConvexHull->radius > (*outmostBall)->radius) { @@ -652,14 +457,8 @@ static int addBallToHull(convexHull *hull, bmeshBall *ballForConvexHull, *outmostBall = ballForConvexHull; *outmostBallFirstVertexIndex = vertexIndex[0]; } - - return 0; } -#include "osutil.h" -int showFaceIndex = 10000000; -static long long lastShowFaceIndexIncTime = 0; - static convexHull *createConvexHullForBall(bmesh *bm, int depth, bmeshBall *ball, int *needRetry) { convexHull *hull; @@ -676,74 +475,33 @@ static convexHull *createConvexHullForBall(bmesh *bm, int depth, *needRetry = 0; ballPtrArray = arrayCreate(sizeof(bmeshBall *)); - if (!ballPtrArray) { - fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__); - return 0; - } hull = convexHullCreate(); - if (!hull) { - fprintf(stderr, "%s:convexHullCreate failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - return 0; - } if (BMESH_BALL_TYPE_KEY == ball->type) { bmeshBall reduceBall = *ball; reduceBall.radius *= 0.4; - if (-1 == addBallToHull(hull, &reduceBall, - &outmostBall, &outmostBallFirstVertexIndex)) { - fprintf(stderr, "%s:addBallToHull failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } + addBallToHull(hull, &reduceBall, &outmostBall, + &outmostBallFirstVertexIndex); } for (child = bmeshGetBallFirstChild(bm, ball, &iterator); child; child = bmeshGetBallNextChild(bm, ball, &iterator)) { ballForConvexHull = bmeshFindChildBallForConvexHull(bm, ball, child); - ballPtr = (bmeshBall **)arrayNewItem(ballPtrArray); - if (!ballPtr) { - fprintf(stderr, "%s:arrayNewItem failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } + ballPtr = arrayNewItem(ballPtrArray); *ballPtr = ballForConvexHull; - if (-1 == addBallToHull(hull, ballForConvexHull, - &outmostBall, &outmostBallFirstVertexIndex)) { - fprintf(stderr, "%s:addBallToHull failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } + addBallToHull(hull, ballForConvexHull, &outmostBall, + &outmostBallFirstVertexIndex); } if (depth > 0 && depth - 1 < BMESH_MAX_PARENT_BALL_DEPTH) { ballForConvexHull = bmeshFindParentBallForConvexHull(bm, ball, depth - 1, bm->parentBallStack[depth - 1]); ballPtr = (bmeshBall **)arrayNewItem(ballPtrArray); - if (!ballPtr) { - fprintf(stderr, "%s:arrayNewItem failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } *ballPtr = ballForConvexHull; - if (-1 == addBallToHull(hull, ballForConvexHull, - &outmostBall, &outmostBallFirstVertexIndex)) { - fprintf(stderr, "%s:addBallToHull failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } + addBallToHull(hull, ballForConvexHull, &outmostBall, + &outmostBallFirstVertexIndex); } if (outmostBall) { - if (-1 == convexHullAddTodo(hull, outmostBallFirstVertexIndex + 0, - outmostBallFirstVertexIndex + 1, outmostBallFirstVertexIndex + 2)) { - fprintf(stderr, "%s:convexHullAddTodo failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } + convexHullAddTodo(hull, outmostBallFirstVertexIndex + 0, + outmostBallFirstVertexIndex + 1, outmostBallFirstVertexIndex + 2); } for (i = 0; i < arrayGetLength(ballPtrArray); ++i) { @@ -751,12 +509,7 @@ static convexHull *createConvexHullForBall(bmesh *bm, int depth, ballItem->flagForHull = 0; } - if (-1 == convexHullGenerate(hull)) { - fprintf(stderr, "%s:convexHullGenerate failed.\n", __FUNCTION__); - arrayDestroy(ballPtrArray); - convexHullDestroy(hull); - return 0; - } + convexHullGenerate(hull); convexHullUnifyNormals(hull, &ball->position); convexHullMergeTriangles(hull); @@ -764,7 +517,7 @@ static convexHull *createConvexHullForBall(bmesh *bm, int depth, for (i = 0; i < convexHullGetFaceNum(hull); ++i) { convexHullFace *f = (convexHullFace *)convexHullGetFace(hull, i); if (-1 != f->plane) { - bmeshBall *ballItem = (bmeshBall *)arrayGetItem(bm->ballArray, f->plane); + bmeshBall *ballItem = arrayGetItem(bm->ballArray, f->plane); ballItem->flagForHull = 1; f->vertexNum = 0; } @@ -804,13 +557,14 @@ static convexHull *createConvexHullForBall(bmesh *bm, int depth, return hull; } -static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) { +static void bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) { bmeshBallIterator iterator; bmeshBall *child; - int result = 0; + if (bm->roundColor == ball->roundColor) { - return 0; + return; } + if (depth < BMESH_MAX_PARENT_BALL_DEPTH) { bm->parentBallStack[depth] = ball; } @@ -841,19 +595,13 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) { q.pt[1] = convexHullGetVertex(hull, face->u.q.indices[1])->pt; q.pt[2] = convexHullGetVertex(hull, face->u.q.indices[2])->pt; q.pt[3] = convexHullGetVertex(hull, face->u.q.indices[3])->pt; - result = bmeshAddQuadToModel(bm, &q); - if (-1 == result) { - break; - } + bmeshAddQuadToModel(bm, &q); } else if (3 == face->vertexNum) { triangle t; t.pt[0] = convexHullGetVertex(hull, face->u.t.indices[0])->pt; t.pt[1] = convexHullGetVertex(hull, face->u.t.indices[1])->pt; t.pt[2] = convexHullGetVertex(hull, face->u.t.indices[2])->pt; - result = bmeshAddTriangleToModel(bm, &t); - if (-1 == result) { - break; - } + bmeshAddTriangleToModel(bm, &t); } } convexHullDestroy(hull); @@ -863,19 +611,15 @@ static int bmeshStichFrom(bmesh *bm, int depth, bmeshBall *ball) { for (child = bmeshGetBallFirstChild(bm, ball, &iterator); child; child = bmeshGetBallNextChild(bm, ball, &iterator)) { - result = bmeshStichFrom(bm, depth + 1, child); - if (0 != result) { - fprintf(stderr, "%s:bmeshSweepFrom failed.\n", __FUNCTION__); - return result; - } + bmeshStichFrom(bm, depth + 1, child); } - return result; } int bmeshStitch(bmesh *bm) { bm->roundColor++; memset(bm->parentBallStack, 0, sizeof(bm->parentBallStack)); - return bmeshStichFrom(bm, 0, bmeshGetRootBall(bm)); + bmeshStichFrom(bm, 0, bmeshGetRootBall(bm)); + return 0; } static void rollQuadVertexs(quad *q) { @@ -938,11 +682,7 @@ static int bmeshAddWallsBetweenQuadsToModel(bmesh *bm, vec3 *origin, quad *q1, wall.pt[j] = oldWall.pt[3 - j]; } } - result = bmeshAddQuadToModel(bm, &wall); - if (-1 == result) { - break; - } - //drawQuad(&wall); + bmeshAddQuadToModel(bm, &wall); } return result; } @@ -960,15 +700,15 @@ static bmeshBall *bmeshFindChildBallForInbetweenMesh(bmesh *bm, bmeshBall *ball) return bmeshFindChildBallForInbetweenMesh(bm, child); } -static int bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth, +static void bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth, bmeshBall *ball) { - int result = 0; bmeshBallIterator iterator; bmeshBall *child = 0; bmeshBall *parent; quad currentFace, childFace; + if (bm->roundColor == ball->roundColor) { - return 0; + return; } if (depth < BMESH_MAX_PARENT_BALL_DEPTH) { bm->parentBallStack[depth] = ball; @@ -986,10 +726,7 @@ static int bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth, calculateBallQuad(&fakeBall, &childFace); bmeshAddWallsBetweenQuadsToModel(bm, &ball->position, ¤tFace, &childFace); - result = bmeshAddQuadToModel(bm, &childFace); - if (-1 == result) { - return result; - } + bmeshAddQuadToModel(bm, &childFace); drawQuad(&childFace); } } @@ -1002,11 +739,8 @@ static int bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth, //} else { child = bmeshFindChildBallForInbetweenMesh(bm, child); calculateBallQuad(child, &childFace); - result = bmeshAddWallsBetweenQuadsToModel(bm, &ball->position, ¤tFace, + bmeshAddWallsBetweenQuadsToModel(bm, &ball->position, ¤tFace, &childFace); - if (-1 == result) { - return result; - } //} ball->meshGenerated = 1; child->meshGenerated = 1; @@ -1015,20 +749,15 @@ static int bmeshGenerateInbetweenMeshFrom(bmesh *bm, int depth, for (child = bmeshGetBallFirstChild(bm, ball, &iterator); child; child = bmeshGetBallNextChild(bm, ball, &iterator)) { - result = bmeshGenerateInbetweenMeshFrom(bm, depth + 1, child); - if (0 != result) { - fprintf(stderr, "%s:bmeshGenerateInbetweenMeshFrom failed.\n", - __FUNCTION__); - return result; - } + bmeshGenerateInbetweenMeshFrom(bm, depth + 1, child); } - return result; } int bmeshGenerateInbetweenMesh(bmesh *bm) { bm->roundColor++; memset(bm->parentBallStack, 0, sizeof(bm->parentBallStack)); - return bmeshGenerateInbetweenMeshFrom(bm, 0, bmeshGetRootBall(bm)); + bmeshGenerateInbetweenMeshFrom(bm, 0, bmeshGetRootBall(bm)); + return 0; } int bmeshGenerate(bmesh *bm) { diff --git a/src/convexhull.c b/src/convexhull.c index a1108feb..7b776a82 100644 --- a/src/convexhull.c +++ b/src/convexhull.c @@ -2,9 +2,10 @@ #include #include #include +#include "dmemory.h" #include "convexhull.h" #include "array.h" -#include "hashtable.h" +#include "dict.h" #include "draw.h" // @@ -32,11 +33,9 @@ struct convexHull { array *faceArray; int nextTodoIndex; unsigned int *openEdgeProcessedMap; - hashtable *face3Hashtable; - face3 findFace3; + dict *face3Dict; array *edgeArray; - hashtable *edgeHashtable; - edge findEdge; + dict *edgeDict; }; typedef struct { @@ -49,46 +48,26 @@ static int cantorPair(int k1, int k2) { return (k1 + k2) * (k1 + k2 + 1) / 2 + k2; } -face3 *convexHullGetFaceByHashtableParam(void *userData, const void *node) { - convexHull *hull = (convexHull *)userData; - int index = (char *)node - (char *)0; - if (0 == index) { - return &hull->findFace3; - } - return (face3 *)arrayGetItem(hull->faceArray, index - 1); -} - static int face3Hash(void *userData, const void *node) { - face3 *face = convexHullGetFaceByHashtableParam(userData, node); + const face3 *face = node; return cantorPair(cantorPair(face->indices[0], face->indices[1]), face->indices[2]); } -edge *convexHullGetEdgeByHashtableParam(void *userData, const void *node) { - convexHull *hull = (convexHull *)userData; - int index = (char *)node - (char *)0; - if (0 == index) { - return &hull->findEdge; - } - return (edge *)arrayGetItem(hull->edgeArray, index - 1); -} - static int edgeHash(void *userData, const void *node) { - edge *e = convexHullGetEdgeByHashtableParam(userData, node); + const edge *e = node; return e->p1 < e->p2 ? cantorPair(e->p1, e->p2) : cantorPair(e->p2, e->p1); } static int face3Compare(void *userData, const void *node1, const void *node2) { - face3 *f1 = convexHullGetFaceByHashtableParam(userData, node1); - face3 *f2 = convexHullGetFaceByHashtableParam(userData, node2); - return memcmp(f1, f2, sizeof(face3)); + return memcmp(node1, node2, sizeof(face3)); } static int edgeCompare(void *userData, const void *node1, const void *node2) { - edge *e1 = convexHullGetEdgeByHashtableParam(userData, node1); - edge *e2 = convexHullGetEdgeByHashtableParam(userData, node2); + const edge *e1 = node1; + const edge *e2 = node2; if ((e1->p1 == e2->p1 && e1->p2 == e2->p2) || (e1->p2 == e2->p1 && e1->p1 == e2->p2)) { return 0; @@ -97,74 +76,34 @@ static int edgeCompare(void *userData, const void *node1, } convexHull *convexHullCreate(void) { - convexHull *hull = (convexHull *)calloc(1, sizeof(convexHull)); - if (!hull) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } + convexHull *hull = dcalloc(1, sizeof(convexHull)); hull->vertexArray = arrayCreate(sizeof(convexHullVertex)); - if (!hull->vertexArray) { - fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return 0; - } hull->todoArray = arrayCreate(sizeof(todo)); - if (!hull->todoArray) { - fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return 0; - } hull->faceArray = arrayCreate(sizeof(convexHullFace)); - if (!hull->faceArray) { - fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return 0; - } - hull->face3Hashtable = hashtableCreate(FACE3_HASHTABLE_SIZE, + hull->face3Dict = dictCreate(hull->faceArray, FACE3_HASHTABLE_SIZE, face3Hash, face3Compare, hull); - if (!hull->face3Hashtable) { - fprintf(stderr, "%s:hashtableCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return 0; - } hull->edgeArray = arrayCreate(sizeof(edge)); - if (!hull->edgeArray) { - fprintf(stderr, "%s:arrayCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return 0; - } - hull->edgeHashtable = hashtableCreate(EDGE_HASHTABLE_SIZE, + hull->edgeDict = dictCreate(hull->edgeArray, EDGE_HASHTABLE_SIZE, edgeHash, edgeCompare, hull); - if (!hull->edgeHashtable) { - fprintf(stderr, "%s:hashtableCreate failed.\n", __FUNCTION__); - convexHullDestroy(hull); - return 0; - } return hull; } edge *convexHullFindEdge(convexHull *hull, int p1, int p2) { - int index; - hull->findEdge.p1 = p1; - hull->findEdge.p2 = p2; - index = (char *)hashtableGet(hull->edgeHashtable, 0) - (char *)0; - if (0 == index) { - return 0; - } - return arrayGetItem(hull->edgeArray, index - 1); + edge findEdge; + findEdge.p1 = p1; + findEdge.p2 = p2; + return dictFind(hull->edgeDict, &findEdge); } -int convexHullAddEdge(convexHull *hull, int p1, int p2, int hill, +void convexHullAddEdge(convexHull *hull, int p1, int p2, int hill, int face) { - edge *e = convexHullFindEdge(hull, p1, p2); + edge findEdge; + edge *e; + findEdge.p1 = p1; + findEdge.p2 = p2; + e = dictFind(hull->edgeDict, &findEdge); if (!e) { - int newIndex = arrayGetLength(hull->edgeArray); - if (0 != arraySetLength(hull->edgeArray, newIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } - e = (edge *)arrayGetItem(hull->edgeArray, newIndex); - memset(e, 0, sizeof(edge)); + e = dictGetClear(hull->edgeDict, &findEdge); e->p1 = p1; e->p2 = p2; e->hill1 = hill; @@ -174,17 +113,12 @@ int convexHullAddEdge(convexHull *hull, int p1, int p2, int hill, vec3Normal((vec3 *)arrayGetItem(hull->vertexArray, e->p1), (vec3 *)arrayGetItem(hull->vertexArray, e->p2), (vec3 *)arrayGetItem(hull->vertexArray, e->hill1), &e->hill1Normal); - if (0 != hashtableInsert(hull->edgeHashtable, (char *)0 + newIndex + 1)) { - fprintf(stderr, "%s:hashtableInsert failed.\n", __FUNCTION__); - return -1; - } - return 0; + return; } assert(-1 == e->hill2); assert(-1 == e->face2); e->hill2 = hill; e->face2 = face; - return 0; } void convexHullMarkEdgeAsProcessed(convexHull *hull, int firstVertex, @@ -212,41 +146,20 @@ int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane, int orderOnPlane) { convexHullVertex *vtx; int newVertex = arrayGetLength(hull->vertexArray); - if (0 != arraySetLength(hull->vertexArray, newVertex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } - vtx = (convexHullVertex *)arrayGetItem(hull->vertexArray, newVertex); + arraySetLength(hull->vertexArray, newVertex + 1); + vtx = arrayGetItem(hull->vertexArray, newVertex); vtx->plane = plane; vtx->orderOnPlane = orderOnPlane; vtx->pt = *vertex; return newVertex; } -int convexHullAddTodoNoCheck(convexHull *hull, int firstVertex, +void convexHullAddTodoNoCheck(convexHull *hull, int firstVertex, int secondVertex, int thirdVertex) { - todo *t; - int newEdge = arrayGetLength(hull->todoArray); - if (firstVertex < 0 || secondVertex < 0) { - fprintf(stderr, "%s:Invalid params(firstVertex:%d secondVertex:%d).\n", - __FUNCTION__, firstVertex, secondVertex); - return -1; - } - if (0 != arraySetLength(hull->todoArray, newEdge + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } - t = (todo *)arrayGetItem(hull->todoArray, newEdge); - memset(t, 0, sizeof(todo)); + todo *t = arrayNewItemClear(hull->todoArray); t->firstVertex = firstVertex; t->secondVertex = secondVertex; t->thirdVertex = thirdVertex; - return 0; -} - -static int isInAdjacentOrder(int order1, int order2) { - return ((order1 + 1) % 4 == order2 || - (order2 + 1) % 4 == order1); } static int sortface(const void *first, const void *second) { @@ -255,7 +168,7 @@ static int sortface(const void *first, const void *second) { return *firstIndex - *secondIndex; } -int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex, +void convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex, int thirdVertex) { face3 *tri; convexHullVertex *vtx1; @@ -263,62 +176,35 @@ int convexHullAddFace3(convexHull *hull, int firstVertex, int secondVertex, convexHullVertex *vtx3; int newTri; int facePlane = -1; + face3 findFace3; - vtx1 = (convexHullVertex *)arrayGetItem(hull->vertexArray, firstVertex); - vtx2 = (convexHullVertex *)arrayGetItem(hull->vertexArray, secondVertex); - vtx3 = (convexHullVertex *)arrayGetItem(hull->vertexArray, thirdVertex); + vtx1 = arrayGetItem(hull->vertexArray, firstVertex); + vtx2 = arrayGetItem(hull->vertexArray, secondVertex); + vtx3 = arrayGetItem(hull->vertexArray, thirdVertex); if (vtx1->plane == vtx2->plane && vtx1->plane == vtx3->plane) { facePlane = vtx1->plane; } - /* - if (vtx1->plane == vtx2->plane) { - if (!isInAdjacentOrder(vtx1->orderOnPlane, vtx2->orderOnPlane)) { - return 0; - } - } - if (vtx1->plane == vtx3->plane) { - if (!isInAdjacentOrder(vtx1->orderOnPlane, vtx3->orderOnPlane)) { - return 0; - } - } - if (vtx2->plane == vtx3->plane) { - if (!isInAdjacentOrder(vtx2->orderOnPlane, vtx3->orderOnPlane)) { - return 0; - } - }*/ - - 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)) { + memset(&findFace3, 0, sizeof(findFace3)); + findFace3.indices[0] = firstVertex; + findFace3.indices[1] = secondVertex; + findFace3.indices[2] = thirdVertex; + qsort(&findFace3.indices, 3, sizeof(findFace3.indices[0]), sortface); + if (!dictFind(hull->face3Dict, &findFace3)) { newTri = arrayGetLength(hull->faceArray); - if (0 != arraySetLength(hull->faceArray, newTri + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } - tri = (face3 *)arrayGetItem(hull->faceArray, newTri); + tri = dictGetClear(hull->face3Dict, &findFace3); + *tri = findFace3; ((convexHullFace *)tri)->vertexNum = 3; ((convexHullFace *)tri)->plane = facePlane; - *tri = hull->findFace3; - if (0 != hashtableInsert(hull->face3Hashtable, - (char *)0 + newTri + 1)) { - fprintf(stderr, "%s:hashtableInsert failed.\n", __FUNCTION__); - return -1; - } convexHullAddEdge(hull, firstVertex, secondVertex, thirdVertex, newTri); convexHullAddEdge(hull, secondVertex, thirdVertex, firstVertex, newTri); convexHullAddEdge(hull, thirdVertex, firstVertex, secondVertex, newTri); } - return 0; } static void convexHullReleaseForGenerate(convexHull *hull) { - free(hull->openEdgeProcessedMap); + dfree(hull->openEdgeProcessedMap); hull->openEdgeProcessedMap = 0; } @@ -327,31 +213,26 @@ void convexHullDestroy(convexHull *hull) { arrayDestroy(hull->todoArray); arrayDestroy(hull->faceArray); arrayDestroy(hull->edgeArray); - hashtableDestroy(hull->edgeHashtable); - hashtableDestroy(hull->face3Hashtable); + dictDestroy(hull->edgeDict); + dictDestroy(hull->face3Dict); convexHullReleaseForGenerate(hull); - free(hull); + dfree(hull); } -static int convexHullPrepareForGenerate(convexHull *hull) { - free(hull->openEdgeProcessedMap); - hull->openEdgeProcessedMap = (unsigned int *)calloc( +static void convexHullPrepareForGenerate(convexHull *hull) { + dfree(hull->openEdgeProcessedMap); + hull->openEdgeProcessedMap = dcalloc( arrayGetLength(hull->vertexArray) * arrayGetLength(hull->vertexArray) / (sizeof(unsigned int) * 8) + 1, sizeof(unsigned int)); - if (!hull->openEdgeProcessedMap) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return -1; - } hull->nextTodoIndex = 0; - return 0; } int convexHullGetNextVertex(convexHull *hull, int p1Index, int p2Index, int p3Index) { - vec3 *p1 = (vec3 *)arrayGetItem(hull->vertexArray, p1Index); - vec3 *p2 = (vec3 *)arrayGetItem(hull->vertexArray, p2Index); - vec3 *p3 = (vec3 *)arrayGetItem(hull->vertexArray, p3Index); + vec3 *p1 = arrayGetItem(hull->vertexArray, p1Index); + vec3 *p2 = arrayGetItem(hull->vertexArray, p2Index); + vec3 *p3 = arrayGetItem(hull->vertexArray, p3Index); vec3 beginNormal; vec3 endNormal; int i; @@ -363,8 +244,7 @@ int convexHullGetNextVertex(convexHull *hull, int p1Index, int p2Index, for (i = 0; i < arrayGetLength(hull->vertexArray); ++i) { if (i != p1Index && i != p2Index && i != p3Index) { - vec3Normal(p1, p2, (vec3 *)arrayGetItem(hull->vertexArray, i), - &endNormal); + vec3Normal(p1, p2, arrayGetItem(hull->vertexArray, i), &endNormal); angle = vec3Angle(&beginNormal, &endNormal); if (angle > maxAngle) { candidateIndex = i; @@ -376,26 +256,18 @@ int convexHullGetNextVertex(convexHull *hull, int p1Index, int p2Index, return candidateIndex; } -int convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, +void convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, int vertex3) { if (!convexHullOpenEdgeProcessed(hull, vertex1, vertex2)) { - return convexHullAddTodoNoCheck(hull, vertex1, vertex2, vertex3); + convexHullAddTodoNoCheck(hull, vertex1, vertex2, vertex3); } - return 0; } -extern int showFaceIndex; - static int convexHullCanAddFace3(convexHull *hull, int index1, int index2, int index3) { int i; int indices[] = {index1, index2, index3}; - if (showFaceIndex == arrayGetLength(hull->faceArray)) { - drawDebugPrintf("showFaceIndex:%d can add (%d,%d,%d)", showFaceIndex, - index1, index2, index3); - } - for (i = 0; i < 3; ++i) { int p1 = indices[i]; int p2 = indices[(i + 1) % 3]; @@ -412,15 +284,6 @@ static int convexHullCanAddFace3(convexHull *hull, int index1, int index2, (vec3 *)arrayGetItem(hull->vertexArray, hill), &normal); angle = vec3Angle(&e->hill1Normal, &normal); - if (showFaceIndex == arrayGetLength(hull->faceArray)) { - drawDebugPrintf("showFaceIndex:%d angle:%f (%d,%d,%d)", - showFaceIndex, angle, e->p1, e->p2, e->hill1); - drawSphere((vec3 *)arrayGetItem(hull->vertexArray, 9), - 0.1, 36, 24); - drawSphere((vec3 *)arrayGetItem(hull->vertexArray, 6), - 0.1, 36, 24); - } - if (angle < 1) { return 0; } @@ -429,15 +292,12 @@ static int convexHullCanAddFace3(convexHull *hull, int index1, int index2, return 1; } -int convexHullGenerate(convexHull *hull) { +void convexHullGenerate(convexHull *hull) { int index1, index2, index3; convexHullReleaseForGenerate(hull); - if (0 != convexHullPrepareForGenerate(hull)) { - fprintf(stderr, "%s:convexHullPrepareForGenerate failed.\n", __FUNCTION__); - return -1; - } + convexHullPrepareForGenerate(hull); while (hull->nextTodoIndex < arrayGetLength(hull->todoArray)) { - todo *t = (todo *)arrayGetItem(hull->todoArray, hull->nextTodoIndex++); + todo *t = arrayGetItem(hull->todoArray, hull->nextTodoIndex++); index1 = t->firstVertex; index2 = t->secondVertex; if (convexHullOpenEdgeProcessed(hull, index1, index2) || @@ -452,28 +312,19 @@ int convexHullGenerate(convexHull *hull) { if (!convexHullCanAddFace3(hull, index1, index2, index3)) { continue; } - if (showFaceIndex == arrayGetLength(hull->faceArray)) { - drawDebugPrintf("showFaceIndex:%d added face3 (%d,%d,%d)", - showFaceIndex, index1, index2, index3); - } convexHullAddFace3(hull, index1, index2, index3); convexHullAddTodo(hull, index2, index3, index1); convexHullAddTodo(hull, index3, index1, index2); } - return 0; } -int convexHullUnifyNormals(convexHull *hull, vec3 *origin) { +void convexHullUnifyNormals(convexHull *hull, vec3 *origin) { int i; for (i = 0; i < arrayGetLength(hull->faceArray); ++i) { - face3 *triIdx = (face3 *)arrayGetItem( - hull->faceArray, i); - convexHullVertex *p1 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, triIdx->indices[0]); - convexHullVertex *p2 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, triIdx->indices[1]); - convexHullVertex *p3 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, triIdx->indices[2]); + face3 *triIdx = arrayGetItem(hull->faceArray, i); + convexHullVertex *p1 = arrayGetItem(hull->vertexArray, triIdx->indices[0]); + convexHullVertex *p2 = arrayGetItem(hull->vertexArray, triIdx->indices[1]); + convexHullVertex *p3 = arrayGetItem(hull->vertexArray, triIdx->indices[2]); vec3 normal; vec3 o2v; vec3Normal(&p1->pt, &p2->pt, &p3->pt, &normal); @@ -484,7 +335,6 @@ int convexHullUnifyNormals(convexHull *hull, vec3 *origin) { triIdx->indices[2] = index; } } - return 0; } static int sortEdgeByScore(const void *first, const void *second) { @@ -507,38 +357,20 @@ static void rollTriangleIndices(face3 *face) { } } -int convexHullMergeTriangles(convexHull *hull) { +void convexHullMergeTriangles(convexHull *hull) { int edgeIndex; for (edgeIndex = 0; edgeIndex < arrayGetLength(hull->edgeArray); ++edgeIndex) { - edge *e = (edge *)arrayGetItem(hull->edgeArray, edgeIndex); + edge *e = arrayGetItem(hull->edgeArray, edgeIndex); if (-1 != e->face1 && -1 != e->face2) { - //face3 *f1 = (face3 *)arrayGetItem(hull->faceArray, e->face1); - //face3 *f2 = (face3 *)arrayGetItem(hull->faceArray, e->face2); vec3 f1normal; vec3 f2normal; const vec3 yAxis = {0, 1, 0}; - /* - convexHullVertex *f1p1 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, f1->indices[0]); - convexHullVertex *f1p2 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, f1->indices[1]); - convexHullVertex *f1p3 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, f1->indices[2]); - convexHullVertex *f2p1 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, f2->indices[0]); - convexHullVertex *f2p2 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, f2->indices[1]); - convexHullVertex *f2p3 = (convexHullVertex *)arrayGetItem( - hull->vertexArray, f2->indices[2]); - vec3Normal(&f1p1->pt, &f1p2->pt, &f1p3->pt, &f1normal); - vec3Normal(&f2p1->pt, &f2p2->pt, &f2p3->pt, &f2normal); - */ - vec3 *v1 = (vec3 *)arrayGetItem(hull->vertexArray, e->p1); - vec3 *v2 = (vec3 *)arrayGetItem(hull->vertexArray, e->p2); - vec3 *vHill1 = (vec3 *)arrayGetItem(hull->vertexArray, e->hill1); - vec3 *vHill2 = (vec3 *)arrayGetItem(hull->vertexArray, e->hill2); + vec3 *v1 = arrayGetItem(hull->vertexArray, e->p1); + vec3 *v2 = arrayGetItem(hull->vertexArray, e->p2); + vec3 *vHill1 = arrayGetItem(hull->vertexArray, e->hill1); + vec3 *vHill2 = arrayGetItem(hull->vertexArray, e->hill2); vec3 v12; vec3Sub(v1, v2, &v12); vec3Normal(v1, vHill1, v2, &f1normal); @@ -554,17 +386,15 @@ int convexHullMergeTriangles(convexHull *hull) { // // After sort by score, the edge hashmap can not be used anymore. // - hashtableDestroy(hull->edgeHashtable); - hull->edgeHashtable = 0; + dictDestroy(hull->edgeDict); + hull->edgeDict = 0; for (edgeIndex = 0; edgeIndex < arrayGetLength(hull->edgeArray); ++edgeIndex) { - edge *e = (edge *)arrayGetItem(hull->edgeArray, edgeIndex); + edge *e = arrayGetItem(hull->edgeArray, edgeIndex); if (-1 != e->face1 && -1 != e->face2) { - convexHullFace *f1 = (convexHullFace *)arrayGetItem(hull->faceArray, - e->face1); - convexHullFace *f2 = (convexHullFace *)arrayGetItem(hull->faceArray, - e->face2); + convexHullFace *f1 = arrayGetItem(hull->faceArray, e->face1); + convexHullFace *f2 = arrayGetItem(hull->faceArray, e->face2); if (3 == f1->vertexNum && 3 == f2->vertexNum) { if (e->angleBetweenFaces <= 40 && f1->plane == f2->plane) { @@ -575,33 +405,23 @@ int convexHullMergeTriangles(convexHull *hull) { f1->u.q.indices[2] = e->hill2; f1->vertexNum = 4; f2->vertexNum = 0; - //if (edgeIndex >= 12 && edgeIndex <= 12) { - // drawDebugPoint((vec3 *)arrayGetItem( - // hull->vertexArray, e->p1), edgeIndex); - // drawDebugPoint((vec3 *)arrayGetItem( - // hull->vertexArray, e->p2), edgeIndex); - //} } } } } // After merge, face3 hashtable can not be used anymore. - hashtableDestroy(hull->face3Hashtable); - hull->face3Hashtable = 0; - - return 0; + dictDestroy(hull->face3Dict); + hull->face3Dict = 0; } convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex) { - convexHullFace *face = (convexHullFace *)arrayGetItem(hull->faceArray, - faceIndex); + convexHullFace *face = arrayGetItem(hull->faceArray, faceIndex); return face; } convexHullVertex *convexHullGetVertex(convexHull *hull, int vertexIndex) { - convexHullVertex *vertex = (convexHullVertex *)arrayGetItem( - hull->vertexArray, vertexIndex); + convexHullVertex *vertex = arrayGetItem(hull->vertexArray, vertexIndex); return vertex; } diff --git a/src/convexhull.h b/src/convexhull.h index 2c5db4e3..2f517948 100644 --- a/src/convexhull.h +++ b/src/convexhull.h @@ -23,12 +23,12 @@ convexHull *convexHullCreate(void); int convexHullAddVertex(convexHull *hull, vec3 *vertex, int plane, int orderOnPlane); void convexHullDestroy(convexHull *hull); -int convexHullGenerate(convexHull *hull); -int convexHullUnifyNormals(convexHull *hull, vec3 *origin); -int convexHullMergeTriangles(convexHull *hull); +void convexHullGenerate(convexHull *hull); +void convexHullUnifyNormals(convexHull *hull, vec3 *origin); +void convexHullMergeTriangles(convexHull *hull); int convexHullGetFaceNum(convexHull *hull); convexHullFace *convexHullGetFace(convexHull *hull, int faceIndex); convexHullVertex *convexHullGetVertex(convexHull *hull, int vertexIndex); -int convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, int vertex3); +void convexHullAddTodo(convexHull *hull, int vertex1, int vertex2, int vertex3); #endif diff --git a/src/hashtable.c b/src/dict.c similarity index 51% rename from src/hashtable.c rename to src/dict.c index 08ee1274..9fb22ed8 100644 --- a/src/hashtable.c +++ b/src/dict.c @@ -2,8 +2,8 @@ #include #include #include -#include "hashtable.h" -#include "array.h" +#include "dmemory.h" +#include "dict.h" typedef struct hashtableEntry { const void *node; @@ -15,14 +15,22 @@ typedef struct hashtableKey { int firstEntryIndex; } hashtableKey; -struct hashtable { +typedef struct hashtable { array *keyArray; array *entryArray; int bucketSize; int (*hashCallback)(void *userData, const void *node); int (*compareCallback)(void *userData, const void *node1, const void *node2); void *userData; -}; +} hashtable; + +void hashtableDestroy(hashtable *ht) { + if (ht) { + arrayDestroy(ht->keyArray); + arrayDestroy(ht->entryArray); + dfree(ht); + } +} hashtable *hashtableCreate(int bucketSize, int (*hashCallback)(void *userData, const void *node), @@ -50,23 +58,10 @@ hashtable *hashtableCreate(int bucketSize, ht->hashCallback = hashCallback; ht->compareCallback = compareCallback; ht->userData = userData; - if (0 != arraySetLength(ht->keyArray, bucketSize)) { - fprintf(stderr, "%s:arraySetLength failed(bucketSize:%d).\n", __FUNCTION__, - bucketSize); - hashtableDestroy(ht); - return 0; - } + arraySetLength(ht->keyArray, bucketSize); return ht; } -void hashtableDestroy(hashtable *ht) { - if (ht) { - arrayDestroy(ht->keyArray); - arrayDestroy(ht->entryArray); - free(ht); - } -} - static int hashtableGetNodeHash(hashtable *ht, const void *node) { return (int)((unsigned int)ht->hashCallback(ht->userData, node) % ht->bucketSize); @@ -88,26 +83,19 @@ static hashtableEntry *findEntry(hashtable *ht, hashtableKey *key, return 0; } -int hashtableInsert(hashtable *ht, const void *node) { +static void hashtableInsert(hashtable *ht, const void *keyNode, + const void *node) { int newEntryIndex; - int hash = hashtableGetNodeHash(ht, node); - hashtableKey *key = (hashtableKey *)arrayGetItem(ht->keyArray, hash); - hashtableEntry *entry = findEntry(ht, key, node); - if (entry) { - return -1; - } + hashtableEntry *entry; + int hash = hashtableGetNodeHash(ht, keyNode); + hashtableKey *key = arrayGetItem(ht->keyArray, hash); newEntryIndex = arrayGetLength(ht->entryArray); - if (0 != arraySetLength(ht->entryArray, newEntryIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed(newEntryIndex:%d).\n", - __FUNCTION__, newEntryIndex); - return -1; - } - entry = (hashtableEntry *)arrayGetItem(ht->entryArray, newEntryIndex); + arraySetLength(ht->entryArray, newEntryIndex + 1); + entry = arrayGetItem(ht->entryArray, newEntryIndex); entry->node = node; entry->nextEntryIndex = 0 == key->entryNum ? -1 : key->firstEntryIndex; key->firstEntryIndex = newEntryIndex; key->entryNum++; - return 0; } void *hashtableGet(hashtable *ht, const void *node) { @@ -115,3 +103,80 @@ void *hashtableGet(hashtable *ht, const void *node) { hashtableKey *key = (hashtableKey *)arrayGetItem(ht->keyArray, hash); return findEntry(ht, key, node); } + +struct dict { + hashtable *ht; + array *arr; + int (*hashCallback)(void *userData, const void *key); + int (*compareCallback)(void *userData, const void *key1, const void *key2); + void *userData; + void *findKey; +}; + +static const void *dictKeyTranslate(dict *dct, const void *key) { + if (0 == key) { + key = dct->findKey; + } else { + key = arrayGetItem(dct->arr, ((char *)key - 0) - 1); + } + return key; +} + +static int dictHash(void *userData, const void *key) { + dict *dct = userData; + return dct->hashCallback(dct->userData, dictKeyTranslate(dct, key)); +} + +static int dictCompare(void *userData, const void *key1, const void *key2) { + dict *dct = userData; + return dct->compareCallback(dct->userData, dictKeyTranslate(dct, key1), + dictKeyTranslate(dct, key2)); +} + +dict *dictCreate(array *arr, int bucketSize, + int (*hashCallback)(void *userData, const void *key), + int (*compareCallback)(void *userData, const void *key1, const void *key2), + void *userData) { + dict *dct = dcalloc(1, sizeof(dict)); + dct->arr = arr; + dct->hashCallback = hashCallback; + dct->compareCallback = compareCallback; + dct->userData = userData; + dct->findKey = 0; + dct->ht = hashtableCreate(bucketSize, dictHash, dictCompare, dct); + return dct; +} + +void dictDestroy(dict *dct) { + if (dct && dct->ht) { + hashtableDestroy(dct->ht); + } + dfree(dct); +} + +void *dictFind(dict *dct, void *key) { + int index; + dct->findKey = key; + index = (char *)hashtableGet(dct->ht, 0) - 0; + if (0 == index) { + return 0; + } + return arrayGetItem(dct->arr, index - 1); +} + +void *dictGet(dict *dct, void *key) { + void *value = dictFind(dct, key); + if (!value) { + int newIndex = arrayGetLength(dct->arr); + value = arrayNewItem(dct->arr); + dct->findKey = key; + hashtableInsert(dct->ht, 0, (char *)0 + newIndex + 1); + } + return value; +} + +void *dictGetClear(dict *dct, void *key) { + void *ptr = dictGet(dct, key); + memset(ptr, 0, arrayGetNodeSize(dct->arr)); + return ptr; +} diff --git a/src/dict.h b/src/dict.h new file mode 100644 index 00000000..89b61c95 --- /dev/null +++ b/src/dict.h @@ -0,0 +1,16 @@ +#ifndef DICT_H +#define DICT_H +#include "array.h" + +typedef struct dict dict; +dict *dictCreate(array *arr, int bucketSize, + int (*hashCallback)(void *userData, const void *key), + int (*compareCallback)(void *userData, const void *key1, const void *key2), + void *userData); +void dictDestroy(dict *dct); +void *dictFind(dict *dct, void *key); +void *dictGet(dict *dct, void *key); +void *dictGetClear(dict *dct, void *key); + +#endif + diff --git a/src/dmemory.c b/src/dmemory.c new file mode 100644 index 00000000..492f54c9 --- /dev/null +++ b/src/dmemory.c @@ -0,0 +1,36 @@ +#include +#include +#include "dmemory.h" + +static void outOfMemory(void) { + fprintf(stderr, "Out of memory\n"); + abort(); +} + +void *dmalloc(int size) { + void *ptr = malloc(size); + if (!ptr) { + outOfMemory(); + } + return ptr; +} + +void *dcalloc(int nitems, int size) { + void *ptr = calloc(nitems, size); + if (!ptr) { + outOfMemory(); + } + return ptr; +} + +void *drealloc(void *ptr, int size) { + ptr = realloc(ptr, size); + if (!ptr) { + outOfMemory(); + } + return ptr; +} + +void dfree(void *ptr) { + free(ptr); +} diff --git a/src/dmemory.h b/src/dmemory.h new file mode 100644 index 00000000..4952b56f --- /dev/null +++ b/src/dmemory.h @@ -0,0 +1,9 @@ +#ifndef DMEMORY_H +#define DMEMORY_H + +void *dmalloc(int size); +void *dcalloc(int nitems, int size); +void *drealloc(void *ptr, int size); +void dfree(void *ptr); + +#endif diff --git a/src/hashtable.h b/src/hashtable.h deleted file mode 100644 index 8915162d..00000000 --- a/src/hashtable.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef HASHTABLE_H -#define HASHTABLE_H - -typedef struct hashtable hashtable; - -hashtable *hashtableCreate(int bucketSize, - int (*hashCallback)(void *userData, const void *node), - int (*compareCallback)(void *userData, const void *node1, const void *node2), - void *userData); -void hashtableDestroy(hashtable *ht); -int hashtableInsert(hashtable *ht, const void *node); -void *hashtableGet(hashtable *ht, const void *node); - -#endif - diff --git a/src/render.cpp b/src/render.cpp index e04f14c0..155ff144 100644 --- a/src/render.cpp +++ b/src/render.cpp @@ -340,7 +340,7 @@ void Render::paintGL() { if (0 == bm) { bmeshBall ball; bmeshBone bone; - int i; + unsigned int i; bm = bmeshCreate(); for (i = 0; i < sizeof(bmeshTestBalls) / sizeof(bmeshTestBalls[0]); ++i) { diff --git a/src/subdivide.c b/src/subdivide.c index f0fd6ea0..fa2faac2 100644 --- a/src/subdivide.c +++ b/src/subdivide.c @@ -1,6 +1,7 @@ #include #include #include +#include "dmemory.h" #include "subdivide.h" #include "draw.h" @@ -82,34 +83,14 @@ static void initFace(subdivFace *f) { } subdivModel *subdivCreateModel(void) { - subdivModel *model = (subdivModel *)calloc(1, sizeof(subdivModel)); - if (!model) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } + subdivModel *model = (subdivModel *)dcalloc(1, sizeof(subdivModel)); model->faceLink = -1; model->edgeLink = -1; model->vertexLink = -1; model->vertexArray = arrayCreate(sizeof(subdivVertex)); - if (!model->vertexArray) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } model->faceArray = arrayCreate(sizeof(subdivFace)); - if (!model->faceArray) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } model->edgeArray = arrayCreate(sizeof(subdivEdge)); - if (!model->edgeArray) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } model->indexArray = arrayCreate(sizeof(subdivLink)); - if (!model->indexArray) { - fprintf(stderr, "%s:Insufficient memory.\n", __FUNCTION__); - return 0; - } return model; } @@ -119,18 +100,15 @@ void subdivDestroyModel(subdivModel *model) { arrayDestroy(model->faceArray); arrayDestroy(model->edgeArray); arrayDestroy(model->indexArray); - free(model); + dfree(model); } } static int allocLink(subdivModel *model, int index) { subdivLink *linkItem; int newLink = arrayGetLength(model->indexArray); - if (0 != arraySetLength(model->indexArray, newLink + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return -1; - } - linkItem = (subdivLink *)arrayGetItem(model->indexArray, newLink); + arraySetLength(model->indexArray, newLink + 1); + linkItem = arrayGetItem(model->indexArray, newLink); linkItem->index = index; linkItem->nextLink = -1; return newLink; @@ -142,25 +120,21 @@ static int subdivLinkElement(subdivModel *model, int current, int order) { subdivLink *linkItem; iterator = current; for (i = 0; i <= order && -1 != iterator; ++i) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, iterator); + linkItem = arrayGetItem(model->indexArray, iterator); element = linkItem->index; iterator = linkItem->nextLink; } return element; } -static int pushLink(subdivModel *model, int *link, int *num, int index) { +static void pushLink(subdivModel *model, int *link, int *num, int index) { int newLink = allocLink(model, index); int i, iterator; subdivLink *linkItem = 0; - if (-1 == newLink) { - fprintf(stderr, "%s:allocLink failed.\n", __FUNCTION__); - return -1; - } if (-1 != *link) { iterator = *link; for (i = 0; i < *num; ++i) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, iterator); + linkItem = arrayGetItem(model->indexArray, iterator); iterator = linkItem->nextLink; } linkItem->nextLink = newLink; @@ -168,34 +142,23 @@ static int pushLink(subdivModel *model, int *link, int *num, int index) { *link = newLink; } (*num)++; - return 0; } static subdivVertex *allocVertex(subdivModel *model) { subdivVertex *vertex; int newVertexIndex = arrayGetLength(model->vertexArray); - if (0 != arraySetLength(model->vertexArray, newVertexIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return 0; - } + arraySetLength(model->vertexArray, newVertexIndex + 1); vertex = arrayGetItem(model->vertexArray, newVertexIndex); initVertex(vertex); vertex->index = newVertexIndex; - if (0 != pushLink(model, &model->vertexLink, &model->vertexNum, - vertex->index)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } + pushLink(model, &model->vertexLink, &model->vertexNum, vertex->index); return vertex; } static subdivEdge *allocEdge(subdivModel *model) { subdivEdge *edge; int newEdgeIndex = arrayGetLength(model->edgeArray); - if (0 != arraySetLength(model->edgeArray, newEdgeIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return 0; - } + arraySetLength(model->edgeArray, newEdgeIndex + 1); edge = arrayGetItem(model->edgeArray, newEdgeIndex); initEdge(edge); edge->index = newEdgeIndex; @@ -205,10 +168,7 @@ static subdivEdge *allocEdge(subdivModel *model) { static subdivFace *allocFace(subdivModel *model) { subdivFace *face; int newFaceIndex = arrayGetLength(model->faceArray); - if (0 != arraySetLength(model->faceArray, newFaceIndex + 1)) { - fprintf(stderr, "%s:arraySetLength failed.\n", __FUNCTION__); - return 0; - } + arraySetLength(model->faceArray, newFaceIndex + 1); face = arrayGetItem(model->faceArray, newFaceIndex); initFace(face); face->index = newFaceIndex; @@ -219,21 +179,21 @@ static subdivVertex *getVertex(subdivModel *model, int index) { if (-1 == index) { return 0; } - return (subdivVertex *)arrayGetItem(model->vertexArray, index); + return arrayGetItem(model->vertexArray, index); } static subdivEdge *getEdge(subdivModel *model, int index) { if (-1 == index) { return 0; } - return (subdivEdge *)arrayGetItem(model->edgeArray, index); + return arrayGetItem(model->edgeArray, index); } static subdivFace *getFace(subdivModel *model, int index) { if (-1 == index) { return 0; } - return (subdivFace *)arrayGetItem(model->faceArray, index); + return arrayGetItem(model->faceArray, index); } static int isHoleEdge(subdivModel *model, int e) { @@ -250,10 +210,6 @@ static int edgePoint(subdivModel *model, int e) { int nv = getEdge(model, e)->edgePt; if (-1 == nv) { subdivVertex *newVertex = allocVertex(model); - if (!newVertex) { - fprintf(stderr, "%s:allocVertex failed.\n", __FUNCTION__); - return 0; - } nv = newVertex->index; getEdge(model, e)->edgePt = nv; getEdge(model, e)->avg = getVertex(model, getEdge(model, e)->v[0])->v; @@ -266,15 +222,11 @@ static int edgePoint(subdivModel *model, int e) { while (-1 != iterator) { int f; int fp; - subdivLink *linkItem = (subdivLink *)arrayGetItem(model->indexArray, + subdivLink *linkItem = arrayGetItem(model->indexArray, iterator); f = linkItem->index; iterator = linkItem->nextLink; fp = facePoint(model, f); - if (-1 == fp) { - fprintf(stderr, "%s:facePoint failed.\n", __FUNCTION__); - return 0; - } vec3Add(&getVertex(model, nv)->v, &getVertex(model, fp)->v, &getVertex(model, nv)->v); } @@ -293,18 +245,13 @@ static int facePoint(subdivModel *model, int f) { int iterator; int i; subdivVertex *newVertex = allocVertex(model); - if (!newVertex) { - fprintf(stderr, "%s:allocVertex failed.\n", __FUNCTION__); - return 0; - } nv = newVertex->index; getFace(model, f)->avg = nv; iterator = getFace(model, f)->vertexLink; i = 0; while (-1 != iterator) { int p; - subdivLink *linkItem = (subdivLink *)arrayGetItem(model->indexArray, - iterator); + subdivLink *linkItem = arrayGetItem(model->indexArray, iterator); p = linkItem->index; iterator = linkItem->nextLink; if (!i) { @@ -345,27 +292,19 @@ static int updatedPoint(subdivModel *model, int p) { } newVertex = allocVertex(model); - if (!newVertex) { - fprintf(stderr, "%s:allocVertex failed.\n", __FUNCTION__); - return 0; - } nv = newVertex->index; getVertex(model, p)->newVertexIndex = nv; if (isHoleVertex(model, p)) { getVertex(model, nv)->v = getVertex(model, p)->v; iterator = getVertex(model, p)->edgeLink; while (-1 != iterator) { - link = (subdivLink *)arrayGetItem(model->indexArray, iterator); + link = arrayGetItem(model->indexArray, iterator); e = link->index; iterator = link->nextLink; if (!isHoleEdge(model, e)) { continue; } ep = edgePoint(model, e); - if (-1 == ep) { - fprintf(stderr, "%s:edgePoint failed.\n", __FUNCTION__); - return 0; - } vec3Add(&getVertex(model, nv)->v, &getVertex(model, ep)->v, &getVertex(model, nv)->v); n++; @@ -376,26 +315,18 @@ static int updatedPoint(subdivModel *model, int p) { n = getVertex(model, p)->faceNum; iterator = getVertex(model, p)->faceLink; while (-1 != iterator) { - link = (subdivLink *)arrayGetItem(model->indexArray, iterator); + link = arrayGetItem(model->indexArray, iterator); f = link->index; iterator = link->nextLink; facePt = facePoint(model, f); - if (-1 == facePt) { - fprintf(stderr, "%s:facePoint failed.\n", __FUNCTION__); - return 0; - } vec3Add(&sum, &getVertex(model, facePt)->v, &sum); } iterator = getVertex(model, p)->edgeLink; while (-1 != iterator) { - link = (subdivLink *)arrayGetItem(model->indexArray, iterator); + link = arrayGetItem(model->indexArray, iterator); e = link->index; iterator = link->nextLink; ep = edgePoint(model, e); - if (-1 == ep) { - fprintf(stderr, "%s:edgePoint failed.\n", __FUNCTION__); - return 0; - } scaleAdd(&sum, &getVertex(model, ep)->v, 2, &sum); } vec3Scale(&sum, 1.0 / n, &sum); @@ -407,7 +338,7 @@ static int updatedPoint(subdivModel *model, int p) { return nv; } -int subdivCalculteNorms(subdivModel *model) { +void subdivCalculteNorms(subdivModel *model) { int i, j, n; int faceIterator; int nextFaceIterator; @@ -423,16 +354,16 @@ int subdivCalculteNorms(subdivModel *model) { faceIterator = model->faceLink; j = 0; while (-1 != faceIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, faceIterator); + linkItem = arrayGetItem(model->indexArray, faceIterator); f = getFace(model, linkItem->index); nextFaceIterator = linkItem->nextLink; vertexIterator = f->vertexLink; n = f->vertexNum; i = 0; while (-1 != vertexIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, faceIterator); + linkItem = arrayGetItem(model->indexArray, faceIterator); f = getFace(model, linkItem->index); - linkItem = (subdivLink *)arrayGetItem(model->indexArray, vertexIterator); + linkItem = arrayGetItem(model->indexArray, vertexIterator); v = getVertex(model, linkItem->index); vertexIterator = linkItem->nextLink; v0 = getVertex(model, @@ -454,13 +385,13 @@ int subdivCalculteNorms(subdivModel *model) { vertexIterator = model->vertexLink; while (-1 != vertexIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, vertexIterator); + linkItem = arrayGetItem(model->indexArray, vertexIterator); v = getVertex(model, linkItem->index); nextVertexIterator = linkItem->nextLink; faceIterator = v->faceLink; j = 0; while (-1 != faceIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, faceIterator); + linkItem = arrayGetItem(model->indexArray, faceIterator); f = getFace(model, linkItem->index); faceIterator = linkItem->nextLink; vec3Add(&v->avgNorm, &f->norm, &v->avgNorm); @@ -471,8 +402,6 @@ int subdivCalculteNorms(subdivModel *model) { } vertexIterator = nextVertexIterator; } - - return 0; } void subdivDrawModel(subdivModel *model) { @@ -484,13 +413,13 @@ void subdivDrawModel(subdivModel *model) { faceIterator = model->faceLink; glColor4f(1.0, 1.0, 1.0, 1.0); while (-1 != faceIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, faceIterator); + linkItem = arrayGetItem(model->indexArray, faceIterator); f = getFace(model, linkItem->index); faceIterator = linkItem->nextLink; vertexIterator = f->vertexLink; glBegin(GL_POLYGON); while (-1 != vertexIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, vertexIterator); + linkItem = arrayGetItem(model->indexArray, vertexIterator); v = getVertex(model, linkItem->index); vertexIterator = linkItem->nextLink; glNormal3fv(&(f->norm.x)); @@ -512,48 +441,24 @@ subdivModel *subdivCatmullClark(subdivModel *model) { subdivModel *outputModel; outputModel = subdivCreateModel(); - if (!outputModel) { - fprintf(stderr, "%s:subdivCreateModel failed.\n", __FUNCTION__); - return 0; - } faceIterator = model->faceLink; while (-1 != faceIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, faceIterator); + linkItem = arrayGetItem(model->indexArray, faceIterator); f = linkItem->index; j = 0; nextFaceIterator = linkItem->nextLink; vertexIterator = getFace(model, f)->vertexLink; while (-1 != vertexIterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, vertexIterator); + linkItem = arrayGetItem(model->indexArray, vertexIterator); p = linkItem->index; vertexIterator = linkItem->nextLink; ai = updatedPoint(model, p); - if (-1 == ai) { - fprintf(stderr, "%s:updatedPoint failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } bi = edgePoint(model, subdivLinkElement(model, getFace(model, f)->edgeLink, (j + 1) % getFace(model, f)->edgeNum)); - if (-1 == bi) { - fprintf(stderr, "%s:edgePoint failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } ci = facePoint(model, f); - if (-1 == ci) { - fprintf(stderr, "%s:facePoint failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } di = edgePoint(model, subdivLinkElement(model, getFace(model, f)->edgeLink, j)); - if (-1 == di) { - fprintf(stderr, "%s:edgePoint failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } a = getVertex(model, ai)->indexOnNewModel; if (-1 == a) { a = subdivAddVertex(outputModel, &getVertex(model, ai)->v); @@ -574,36 +479,19 @@ subdivModel *subdivCatmullClark(subdivModel *model) { d = subdivAddVertex(outputModel, &getVertex(model, di)->v); getVertex(model, di)->indexOnNewModel = d; } - if (-1 == a || -1 == b || -1 == c || -1 == d) { - fprintf(stderr, "%s:subdivAddVertex failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } - if (-1 == subdivAddQuadFace(outputModel, a, b, c, d)) { - fprintf(stderr, "%s:subdivAddFace failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } + subdivAddQuadFace(outputModel, a, b, c, d); ++j; } faceIterator = nextFaceIterator; } - if (0 != subdivCalculteNorms(outputModel)) { - fprintf(stderr, "%s:subdivCalculteNorms failed.\n", __FUNCTION__); - subdivDestroyModel(outputModel); - return 0; - } - + subdivCalculteNorms(outputModel); + return outputModel; } int subdivAddVertex(subdivModel *model, vec3 *v) { subdivVertex *newVertex = allocVertex(model); - if (!newVertex) { - fprintf(stderr, "%s:allocVertex failed.\n", __FUNCTION__); - return -1; - } newVertex->v = *v; return newVertex->index; } @@ -612,27 +500,13 @@ static int subdivAddEdge(subdivModel *model, int p1, int p2) { subdivEdge *newEdge = allocEdge(model); subdivVertex *v1; subdivVertex *v2; - if (!newEdge) { - fprintf(stderr, "%s:allocEdge failed.\n", __FUNCTION__); - return -1; - } newEdge->v[0] = p1; newEdge->v[1] = p2; v1 = getVertex(model, p1); v2 = getVertex(model, p2); - if (-1 == pushLink(model, &v1->edgeLink, &v1->edgeNum, newEdge->index)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } - if (-1 == pushLink(model, &v2->edgeLink, &v2->edgeNum, newEdge->index)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } - if (-1 == pushLink(model, &model->edgeLink, &model->edgeNum, - newEdge->index)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } + pushLink(model, &v1->edgeLink, &v1->edgeNum, newEdge->index); + pushLink(model, &v2->edgeLink, &v2->edgeNum, newEdge->index); + pushLink(model, &model->edgeLink, &model->edgeNum, newEdge->index); return newEdge->index; } @@ -643,7 +517,7 @@ static int subdivEdgeByVertexs(subdivModel *model, int p1, int p2) { int newEdgeIndex; int iterator = v1->edgeLink; while (-1 != iterator) { - linkItem = (subdivLink *)arrayGetItem(model->indexArray, iterator); + linkItem = arrayGetItem(model->indexArray, iterator); e = getEdge(model, linkItem->index); iterator = linkItem->nextLink; if (e->v[0] == p2 || e->v[1] == p2) { @@ -660,44 +534,21 @@ static int subdivAddFace(subdivModel *model, int *vertexs, int vertexNum) { int p0, p1; int newFaceIndex; int edgeIndex; - if (!f) { - fprintf(stderr, "%s:allocFace failed.\n", __FUNCTION__); - return -1; - } newFaceIndex = f->index; - if (0 != pushLink(model, &model->faceLink, &model->faceNum, newFaceIndex)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } + pushLink(model, &model->faceLink, &model->faceNum, newFaceIndex); p0 = vertexs[0]; for (i = 1; i <= vertexNum; ++i, p0 = p1) { subdivVertex *v1; subdivEdge *e; p1 = vertexs[i % vertexNum]; v1 = getVertex(model, p1); - if (0 != pushLink(model, &v1->faceLink, &v1->faceNum, newFaceIndex)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } + pushLink(model, &v1->faceLink, &v1->faceNum, newFaceIndex); edgeIndex = subdivEdgeByVertexs(model, p0, p1); - if (-1 == edgeIndex) { - fprintf(stderr, "%s:subdivEdgeByVertexs failed.\n", __FUNCTION__); - return -1; - } e = getEdge(model, edgeIndex); - if (0 != pushLink(model, &e->faceLink, &e->faceNum, newFaceIndex)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } + pushLink(model, &e->faceLink, &e->faceNum, newFaceIndex); f = getFace(model, newFaceIndex); - if (0 != pushLink(model, &f->edgeLink, &f->edgeNum, edgeIndex)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } - if (0 != pushLink(model, &f->vertexLink, &f->vertexNum, p1)) { - fprintf(stderr, "%s:pushLink failed.\n", __FUNCTION__); - return -1; - } + pushLink(model, &f->edgeLink, &f->edgeNum, edgeIndex); + pushLink(model, &f->vertexLink, &f->vertexNum, p1); } return newFaceIndex; } @@ -712,7 +563,7 @@ int subdivAddQuadFace(subdivModel *model, int p1, int p2, int p3, int p4) { return subdivAddFace(model, vertexs, 4); } -int subdivAddCube(subdivModel *model) { +void subdivAddCube(subdivModel *model) { int x, y, z; for (x = -1; x <= 1; x += 2) { for (y = -1; y <= 1; y += 2) { @@ -729,28 +580,17 @@ int subdivAddCube(subdivModel *model) { subdivAddQuadFace(model, 0, 2, 6, 4); subdivAddQuadFace(model, 5, 7, 3, 1); subdivCalculteNorms(model); - return 0; } subdivModel *subdivCatmullClarkWithLoops(subdivModel *model, int loops) { int i; subdivModel *outputModel; outputModel = subdivCatmullClark(model); - if (!outputModel) { - fprintf(stderr, "%s:subdivCatmullClark failed.\n", __FUNCTION__); - return 0; - } for (i = 1; i < loops; ++i) { subdivModel *loopInput = outputModel; outputModel = subdivCatmullClark(loopInput); subdivDestroyModel(loopInput); - if (!outputModel) { - fprintf(stderr, "%s:subdivCatmullClark failed(loops:%d i:%d).\n", - __FUNCTION__, loops, i); - return 0; - } } - drawDebugPrintf("faces: %d", outputModel->faceNum); subdivDrawModel(outputModel); return outputModel; } diff --git a/src/subdivide.h b/src/subdivide.h index 477634e8..b755c494 100644 --- a/src/subdivide.h +++ b/src/subdivide.h @@ -16,8 +16,8 @@ int subdivAddTriangleFace(subdivModel *model, int p1, int p2, int p3); int subdivAddQuadFace(subdivModel *model, int p1, int p2, int p3, int p4); subdivModel *subdivCatmullClark(subdivModel *model); subdivModel *subdivCatmullClarkWithLoops(subdivModel *model, int loops); -int subdivAddCube(subdivModel *model); -int subdivCalculteNorms(subdivModel *model); +void subdivAddCube(subdivModel *model); +void subdivCalculteNorms(subdivModel *model); void subdivDrawModel(subdivModel *model); #ifdef __cplusplus