From 6740f4456864f42face1c86e484aa2f30a1aea4a Mon Sep 17 00:00:00 2001 From: "YX.E.Z" Date: Tue, 10 Dec 2024 22:31:21 +0800 Subject: [PATCH 1/2] fix: 1. special format of obj file(with only 1 F term) 2. Grid sample under too small area --- src/API/MSGrid.cpp | 6 +++--- src/Surface/OBJLoader.cpp | 6 ++++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/API/MSGrid.cpp b/src/API/MSGrid.cpp index da1d70a..2143b5b 100644 --- a/src/API/MSGrid.cpp +++ b/src/API/MSGrid.cpp @@ -85,8 +85,8 @@ void MSGrid::generateSamplesInternal(Array *pts, int numSamples, // get normal Vector3D n; sur.getTriangleNormal(&n, i); - - if (num > 1) { + float tArea = areaTriangle(p[0], p[1], p[2]); + if (num > 1 && tArea >= 1e-6) { // generate random samples on the triangle Array points; sampleTriangleGrid(&points, num, p); @@ -98,7 +98,7 @@ void MSGrid::generateSamplesInternal(Array *pts, int numSamples, p->p = points.index(j); p->n = n; } - } else /*if (num == 1)*/ { + } else /*if (num == 1 || tArea < 1e-6)*/ { // should we use incenter ?? Surface::Point *s = &pts->addItem(); s->n = n; diff --git a/src/Surface/OBJLoader.cpp b/src/Surface/OBJLoader.cpp index 2e8d759..1384de2 100644 --- a/src/Surface/OBJLoader.cpp +++ b/src/Surface/OBJLoader.cpp @@ -88,8 +88,10 @@ bool loadOBJ(Surface *sur, const char *fileName, float boxSize) { // decode token int a = 0, b = 0, c = 0; - if (token == NULL || (sscanf(token, "%d/%d/%d", &a, &b, &c) != 3 && - sscanf(token, "%d//%d", &a, &c) != 2)) { + if (token == NULL || + (sscanf(token, "%d/%d/%d", &a, &b, &c) != 3 && + sscanf(token, "%d//%d", &a, &c) != 2 && + sscanf(token, "%d", &a) != 1)){ fclose(f); return false; } From 685a99587d5ca25756c35a5d7785726a6776b533 Mon Sep 17 00:00:00 2001 From: "YX.E.Z" Date: Thu, 12 Dec 2024 16:18:34 +0800 Subject: [PATCH 2/2] fix some bugs in sphere_tree; make a conversion function for eigen to surface --- CMakeLists.txt | 43 +++++------ src/API/CMakeLists.txt | 2 + src/API/SRVoronoi.cpp | 4 + src/BBox/CMakeLists.txt | 2 + src/Geometry/CMakeLists.txt | 2 + src/MedialAxis/Voronoi3D.cpp | 141 ++++++++++++++++++++++++++++++----- 6 files changed, 151 insertions(+), 43 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d479e5e..28493b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,10 @@ add_subdirectory(src/Surface) add_subdirectory(src/Export) # Create STG library -add_library(STG STATIC src/null.c) +add_library(STG STATIC + "src/DecodeParam.cpp" + "src/VerifyModel.cpp" + "src/EvalTree.cpp") # Include compiler warnings module include(CompilerWarnings) @@ -44,22 +47,22 @@ endif() # Link dependent libraries to STG set(LIBS_TO_LINK - API - Base - BBox - Exceptions - Geometry - Matrix - MedialAxis - MinMax - SphereTree - Storage - Surface - Export + ${API_LIBS_OUT} + Base + ${BBox_LIBS_OUT} + Exceptions + ${Geometry_LIBS_OUT} + Matrix + MedialAxis + MinMax + SphereTree + Storage + Surface + Export ) +set(LIBS_TO_LINK_OUT STG ${LIBS_TO_LINK} PARENT_SCOPE) target_link_libraries(STG PUBLIC ${LIBS_TO_LINK}) - # Enable sanitizers if(ENABLE_SANITIZER) include(Sanitizers) @@ -85,34 +88,22 @@ endfunction() # Add executables add_custom_executable(makeTreeMedial "src/makeTreeMedial.cpp" - "src/DecodeParam.cpp" - "src/EvalTree.cpp" - "src/VerifyModel.cpp" ) add_custom_executable(makeTreeHubbard "src/makeTreeHubbard.cpp" - "src/DecodeParam.cpp" - "src/VerifyModel.cpp" ) add_custom_executable(makeTreeOctree "src/makeTreeOctree.cpp" - "src/DecodeParam.cpp" ) add_custom_executable(makeTreeGrid "src/makeTreeGrid.cpp" - "src/DecodeParam.cpp" - "src/VerifyModel.cpp" - "src/EvalTree.cpp" ) add_custom_executable(makeTreeSpawn "src/makeTreeSpawn.cpp" - "src/DecodeParam.cpp" - "src/VerifyModel.cpp" - "src/EvalTree.cpp" ) # Include project-specific and external dependencies diff --git a/src/API/CMakeLists.txt b/src/API/CMakeLists.txt index 196436e..dceeb32 100644 --- a/src/API/CMakeLists.txt +++ b/src/API/CMakeLists.txt @@ -6,3 +6,5 @@ add_library(${BOT_LIB_NAME} STATIC ) target_link_libraries(${BOT_LIB_NAME} SFWhite) + +SET(API_LIBS_OUT SFWhite ${BOT_LIB_NAME} PARENT_SCOPE) \ No newline at end of file diff --git a/src/API/SRVoronoi.cpp b/src/API/SRVoronoi.cpp index 14eaea4..dbfd2ab 100644 --- a/src/API/SRVoronoi.cpp +++ b/src/API/SRVoronoi.cpp @@ -164,6 +164,10 @@ void SRVoronoi::constructSphereSet(Array *medialSpheres, // add to neighbours list for (int j = 0; j < 4; j++) { int neighVert = vert->n[j]; + if (neighVert < 0 || neighVert >= vertexToSphereMap.getSize()) { + OUTPUTINFO("Invalid vertex neighbour index %d in vertex %d's \n ", neighVert, i); + continue; // Skip invalid forming point indices + } CHECK_DEBUG0(neighVert != i); int neighMapsTo = vertexToSphereMap.index(neighVert); if (neighMapsTo > mapsTo) { diff --git a/src/BBox/CMakeLists.txt b/src/BBox/CMakeLists.txt index 0aba147..8b942ea 100644 --- a/src/BBox/CMakeLists.txt +++ b/src/BBox/CMakeLists.txt @@ -13,3 +13,5 @@ add_library(${BOT_LIB_NAME} STATIC target_link_libraries(${BOT_LIB_NAME} qHull MVBB) + +SET(BBox_LIBS_OUT MVBB qHull ${BOT_LIB_NAME} PARENT_SCOPE) \ No newline at end of file diff --git a/src/Geometry/CMakeLists.txt b/src/Geometry/CMakeLists.txt index c247951..834a2fe 100644 --- a/src/Geometry/CMakeLists.txt +++ b/src/Geometry/CMakeLists.txt @@ -7,3 +7,5 @@ add_subdirectory(pcube) target_link_libraries(${BOT_LIB_NAME} pcube Matrix) + +SET(Geometry_LIBS_OUT pcube ${BOT_LIB_NAME} PARENT_SCOPE) \ No newline at end of file diff --git a/src/MedialAxis/Voronoi3D.cpp b/src/MedialAxis/Voronoi3D.cpp index ee63bdf..1b0a239 100644 --- a/src/MedialAxis/Voronoi3D.cpp +++ b/src/MedialAxis/Voronoi3D.cpp @@ -291,7 +291,10 @@ bool Voronoi3D::insertPoint(const Point3D &p, const Vector3D &n, for (int j = 0; j < MAGICK_NUM; j++) { int u = v->n[j]; - + if (u < 0 || u >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex neighbour index %d in vertex %d's \n", u, d); + continue; // Skip invalid forming point indices + } // CHECK_DEBUG0(flags.index(u) == deletable.inList(u)); if (flags.index(u)) continue; @@ -364,6 +367,10 @@ bool Voronoi3D::validNewVertices(const Array &deletable, for (int j = 0; j < MAGICK_NUM; j++) { int u = v->n[j]; + if (u < 0 || u >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex neighbour index %d in vertex %d's \n", u, d); + continue; // Skip invalid forming point indices + } if (deletable.inList(u)) continue; @@ -500,6 +507,10 @@ bool Voronoi3D::constructVertexSphere(Sphere *s, int f0, int f1, int f2, int f3, bool Voronoi3D::constructVertex(int s, int f0, int f1, int f2, int f3, int bV, bool sF) { + if (s < 0 || s >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex index in constructVertex: %d", s); + return false; + } Vertex *newVert = &vertices.index(s); newVert->flag = VOR_FLAG_UNKNOWN; newVert->closestPt.x = newVert->closestPt.y = newVert->closestPt.z = acos(10); @@ -530,7 +541,12 @@ bool Voronoi3D::constructVertex(int s, int f0, int f1, int f2, int f3, int bV, if (sF) { // add to forming points lists for (int i = 0; i < MAGICK_NUM; i++) { - FormingPoint *f = &formingPoints.index(newVert->f[i]); + int formingIndex = newVert->f[i]; + if (formingIndex < 0 || formingIndex >= formingPoints.getSize()) { + OUTPUTINFO("Invalid forming point index %d in constructVertex\n", formingIndex); + continue; // Skip invalid forming points + } + FormingPoint *f = &formingPoints.index(formingIndex); // CHECK_DEBUG0(!f->vertices.inList(s)); f->vertices.addItem() = s; } @@ -556,7 +572,14 @@ void Voronoi3D::addNeighbour(Vertex *vert, int n) { void Voronoi3D::addNeighbour(int dest, int n) { CHECK_DEBUG0(dest != n); CHECK_DEBUG0(n < vertices.getSize()); - + if (dest == n) { + OUTPUTINFO("Attempted to add self as neighbour: %d \n", dest); + return; // Prevent self-neighboring + } + if (n != -1 && (n < 0 || n >= vertices.getSize())) { + OUTPUTINFO("Attempted to add invalid neighbour index: %d \n", n); + return; // Early exit or handle the error as appropriate + } // find the first unused neighbour Vertex *vert = &vertices.index(dest); int i; @@ -564,19 +587,37 @@ void Voronoi3D::addNeighbour(int dest, int n) { if (vert->n[i] < 0) break; - CHECK_DEBUG2(i < MAGICK_NUM, "Not able to add %d as neighbour to %d", n, - dest); - vert->n[i] = n; - // resetFlag(vert); + if (i < MAGICK_NUM) { + vert->n[i] = n; + } else { + OUTPUTINFO("Unable to add neighbour %d: No available slot in Vertex.n \n", n); + + } + // resetFlag(vert); // Uncomment if necessary } bool Voronoi3D::isNeighbour(int v, int n) const { - const Vertex *vert = &vertices.index(v); + if (v < 0 || v >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex index in isNeighbour: %d \n", v); + return false; + } + + if (n != -1 && (n < 0 || n >= vertices.getSize())) { + OUTPUTINFO("Invalid neighbour index in isNeighbour: %d \n", n); + return false; + } + + const Vertex *vert = &vertices.index(v); return isNeighbour(vert, n); } bool Voronoi3D::isNeighbour(const Vertex *vert, int n) const { - for (int i = 0; i < MAGICK_NUM; i++) + if (n != -1 && (n < 0 || n >= vertices.getSize())) { + OUTPUTINFO("Invalid neighbour index in isNeighbour: %d \n", n); + return false; + } + + for (int i = 0; i < MAGICK_NUM; i++) if (vert->n[i] == n) return true; @@ -606,16 +647,25 @@ int Voronoi3D::findClosestVertex(const Point3D &p) const { } void Voronoi3D::replaceNeighbour(Vertex *v, int oldN, int newN) { - CHECK_DEBUG0(newN < vertices.getSize()); + // Allow only valid indices or -1 + if (newN != -1 && (newN < 0 || newN >= vertices.getSize())) { + OUTPUTINFO("Attempted to replace with invalid neighbour index: %d \n", newN); + return; // Early exit or handle the error as appropriate + } - for (int i = 0; i < MAGICK_NUM; i++) { - if (v->n[i] == oldN) { - v->n[i] = newN; - break; + bool replaced = false; + for (int i = 0; i < MAGICK_NUM; i++) { + if (v->n[i] == oldN) { + v->n[i] = newN; + replaced = true; + break; + } } - } - CHECK_DEBUG0(i != MAGICK_NUM); + if (!replaced) { + OUTPUTINFO("Old neighbour %d not found when attempting to replace with %d \n", oldN, newN); + // Optionally, handle the situation (e.g., log an error or add the new neighbor) + } // resetFlag(v); } @@ -667,8 +717,16 @@ void Voronoi3D::remap(Array &list, int oldV, int newV, int sI) const { } void Voronoi3D::deleteVertex(int dI, Array &deletable) { + if (dI < 0 || dI >= deletable.getSize()) { + OUTPUTINFO("Invalid deletable index in deleteVertex: %d \n", dI); + return; + } // remove vertex from forming point's list int n = deletable.index(dI); + if (n < 0 || n >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex index to delete in deleteVertex: %d \n", n); + return; + } CHECK_DEBUG0(n < vertices.getSize()); Vertex *v = &vertices.index(n); @@ -690,7 +748,10 @@ void Voronoi3D::deleteVertex(int dI, Array &deletable) { break; } CHECK_DEBUG0(j != numForm); - + if (j == numForm) { + OUTPUTINFO("Vertex %d not found in forming point %d's list during deletion \n", n, v->f[i]); + continue; + } // remove n f->vertices.index(j) = f->vertices.index(numForm - 1); f->vertices.setSize(numForm - 1); @@ -737,6 +798,18 @@ void Voronoi3D::deleteVertex(int dI, Array &deletable) { // (GRB) CHECK_DEBUG0(nI <= lastV); + if (nI == lastV) { + // Prevent a vertex from being its own neighbor + OUTPUTINFO("Vertex %d cannot be a neighbor to itself after deletion \n", nI); + rV->n[i] = -1; + continue; + } + + if (nI >= vertices.getSize()) { + OUTPUTINFO("Neighbor index out of bounds after deletion: %d \n", nI); + rV->n[i] = -1; + continue; + } Vertex *vN = &vertices.index(nI); replaceNeighbour(vN, lastV, n); @@ -767,6 +840,20 @@ void Voronoi3D::deleteVertex(int dI, Array &deletable) { OUTPUTINFO("AAAAAARRRRGGGGHHHHHH : someone still has lastV as a neighbour\n"); }*/ + for (int i = 0; i < vertices.getSize(); i++) { + Vertex *vert = &vertices.index(i); + for (int j = 0; j < MAGICK_NUM; j++) { + if (vert->n[j] == lastV) { + // Replace with the new index or set to -1 if invalid + vert->n[j] = (n < vertices.getSize()) ? n : -1; + } + // Additionally, validate the neighbor index + if (vert->n[j] >= vertices.getSize()) { + OUTPUTINFO("Invalid neighbor index %d found in vertex %d's neighbor list. Setting to -1.\n", vert->n[j], i); + vert->n[j] = -1; + } + } + } } /* @@ -990,6 +1077,10 @@ void Voronoi3D::deletableSearch(Array &deletable, Array &flags, const Vertex *v = &vertices.index(pqI.i); for (int i = 0; i < MAGICK_NUM; i++) { int vN = v->n[i]; + if (vN < 0 || vN >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex neighbour index %d in vertex %d's ", vN, pqI.i); + continue; // Skip invalid forming point indices + } if (!used.index(vN)) { float v = getValue(vN, p); if (v >= 0) { @@ -1063,6 +1154,10 @@ bool Voronoi3D::validDeletionSetNew(Array &deletable, Array &flags, for (int j = 0; j < MAGICK_NUM && ok; j++) { int u = v->n[j]; + if (u < 0 || u >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex neighbour index %d in vertex %d's \n", u, d); + continue; // Skip invalid forming point indices + } if (flags.index(u)) continue; @@ -1217,6 +1312,10 @@ void Voronoi3D::resetFlag(Vertex *v) { bool Voronoi3D::getCloserForming(int *newForming, float *newDistance, const Point3D &pTest, int currentForming, float currentDistance) const { + if (currentForming < 0 || currentForming >= formingPoints.getSize()) { + OUTPUTINFO("Invalid currentForming index in getCloserForming: %d \n", currentForming); + return false; + } // current forming point const Voronoi3D::FormingPoint *form = &formingPoints.index(currentForming); @@ -1225,11 +1324,19 @@ bool Voronoi3D::getCloserForming(int *newForming, float *newDistance, for (int i = 0; i < numVerts; i++) { // get vertex int vI = form->vertices.index(i); + if (vI < 0 || vI >= vertices.getSize()) { + OUTPUTINFO("Invalid vertex index %d in getCloserForming\n", vI); + continue; // Skip invalid vertex indices + } const Voronoi3D::Vertex *vert = &vertices.index(vI); // forming points for vertex for (int j = 0; j < 4; j++) { int fI = vert->f[j]; + if (fI < 0 || fI >= formingPoints.getSize()) { + OUTPUTINFO("Invalid forming point index %d in vertex %d's forming points\n", fI, vI); + continue; // Skip invalid forming point indices + } const Voronoi3D::FormingPoint *form = &formingPoints.index(fI); float d = form->p.distanceSQR(pTest);