Skip to content

Commit

Permalink
add 3rd option
Browse files Browse the repository at this point in the history
  • Loading branch information
SarahWeiii committed Apr 1, 2024
1 parent 80bf99e commit 72d1f9c
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 111 deletions.
44 changes: 36 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

option(WITH_3RD_PARTY_LIBS "Include 3rd party libraries" ON)

if(WITH_3RD_PARTY_LIBS)
add_compile_definitions(WITH_3RD_PARTY_LIBS=1)
else()
set(DISABLE_SPDLOG ON)
add_compile_definitions(WITH_3RD_PARTY_LIBS=0)
endif()

if (MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W0 -fpermissive -D_USE_MATH_DEFINES")
set(CMAKE_SHARED_LIBRARY_PREFIX "lib")
Expand All @@ -23,17 +32,26 @@ if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fsanitize=address")
endif()

include(zlib)
include(boost)
include(openvdb)
include(eigen)
include(spdlog)
if(WITH_3RD_PARTY_LIBS)
include(zlib)
include(boost)
include(openvdb)
include(spdlog)
endif()

file(GLOB_RECURSE COACD_SRC "src/*.cc" "src/*.cpp")
if(NOT WITH_3RD_PARTY_LIBS)
# Exclude files that match the pattern "preprocess*"
list(FILTER COACD_SRC EXCLUDE REGEX ".*preprocess.*")
endif()

add_library(coacd STATIC ${COACD_SRC})
target_include_directories(coacd PUBLIC public)
target_include_directories(coacd PRIVATE 3rd/cdt/CDT)
target_link_libraries(coacd PRIVATE openvdb_static spdlog::spdlog)

if(WITH_3RD_PARTY_LIBS)
target_link_libraries(coacd PRIVATE openvdb_static spdlog::spdlog)
endif()

find_package(OpenMP)
if (OpenMP_CXX_FOUND)
Expand All @@ -45,7 +63,17 @@ target_link_libraries(coacd PRIVATE Threads::Threads)
set_target_properties(coacd PROPERTIES POSITION_INDEPENDENT_CODE TRUE)

add_library(_coacd SHARED "public/coacd.cpp")
target_link_libraries(_coacd PRIVATE coacd spdlog::spdlog openvdb_static)

if(WITH_3RD_PARTY_LIBS)
target_link_libraries(_coacd PRIVATE coacd spdlog::spdlog openvdb_static)
else()
target_link_libraries(_coacd PRIVATE coacd)
endif()

add_executable(main main.cpp)
target_link_libraries(main coacd spdlog::spdlog openvdb_static)

if(WITH_3RD_PARTY_LIBS)
target_link_libraries(main coacd spdlog::spdlog openvdb_static)
else()
target_link_libraries(main coacd)
endif()
27 changes: 20 additions & 7 deletions main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include <string>
#include <time.h>

#include "src/preprocess.h"
#if WITH_3RD_PARTY_LIBS
#include "src/preprocess.h"
#endif
#include "src/process.h"
#include "src/logger.h"

Expand Down Expand Up @@ -135,15 +137,26 @@ int main(int argc, char *argv[])
vector<double> bbox = m.Normalize();
// m.SaveOBJ("normalized.obj");

if (params.preprocess_mode == "auto")
{
#if WITH_3RD_PARTY_LIBS
if (params.preprocess_mode == "auto")
{
bool is_manifold = IsManifold(m);
logger::info("Mesh Manifoldness: {}", is_manifold);
if (!is_manifold)
ManifoldPreprocess(params, m);
}
else if (params.preprocess_mode == "on")
ManifoldPreprocess(params, m);
#else
bool is_manifold = IsManifold(m);
logger::info("Mesh Manifoldness: {}", is_manifold);
if (!is_manifold)
ManifoldPreprocess(params, m);
}
else if (params.preprocess_mode == "on")
ManifoldPreprocess(params, m);
{
logger::critical("The mesh is not a 2-manifold! Please enable WITH_3RD_PARTY_LIBS during compilation, or use third-party libraries to preprocess the mesh.");
exit(0);
}

#endif

m.SaveOBJ(params.remesh_output_name);

Expand Down
91 changes: 4 additions & 87 deletions src/preprocess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,94 +55,11 @@ namespace coacd
logger::info("Preprocess Time: {}s", double(end - start) / CLOCKS_PER_SEC);
}

bool IsManifold(Model &input)
void ManifoldPreprocess(Params &params, Model &m)
{
logger::info(" - Manifold Check");
clock_t start, end;
start = clock();
// Check all edges are shared by exactly two triangles (watertight manifold)
vector<pair<int, int>> edges;
map<pair<int, int>, int> edge_num;
for (int i = 0; i < (int)input.triangles.size(); i++)
{
int idx0 = input.triangles[i][0];
int idx1 = input.triangles[i][1];
int idx2 = input.triangles[i][2];
edges.push_back({idx0, idx1});
edges.push_back({idx1, idx2});
edges.push_back({idx2, idx0});

if (!edge_num.contains({idx0, idx1}))
edge_num[{idx0, idx1}] = 1;
else
{
logger::info("\tWrong triangle orientation");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
if (!edge_num.contains({idx1, idx2}))
edge_num[{idx1, idx2}] = 1;
else
{
logger::info("\tWrong triangle orientation");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
if (!edge_num.contains({idx2, idx0}))
edge_num[{idx2, idx0}] = 1;
else
{
logger::info("\tWrong triangle orientation");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
}

for (int i = 0; i < (int)edges.size(); i++)
{
pair<int, int> oppo_edge = {edges[i].second, edges[i].first};
if (!edge_num.contains(oppo_edge))
{
logger::info("\tUnclosed mesh");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
}
logger::info("[1/3] Edge check finish");

// Check self-intersection
BVH bvhTree(input);
for (int i = 0; i < (int)input.triangles.size(); i++)
{
bool is_intersect = bvhTree.IntersectBVH(input.triangles[i], 0);
if (is_intersect)
{
logger::info("\tTriangle self-intersection");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
}
logger::info("[2/3] Self-intersection check finish");

// Check triange orientation
double mesh_vol = MeshVolume(input);
if (mesh_vol < 0)
{
// Reverse all the triangles
for (int i = 0; i < (int)input.triangles.size(); i++)
std::swap(input.triangles[i][0], input.triangles[i][1]);
}
end = clock();

logger::info("[3/3] Triangle orientation check finish. Reversed: {}", mesh_vol < 0);
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);

return true;
Model tmp = m;
m.Clear();
SDFManifold(tmp, m, params.prep_resolution, params.dmc_thres);
}

}
4 changes: 1 addition & 3 deletions src/preprocess.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,11 @@

#include "model_obj.h"
#include "logger.h"
#include "bvh.h"

using namespace openvdb;

namespace coacd
{

void SDFManifold(Model &input, Model &output, double scale = 50.0f, double level_set = 0.55f);
bool IsManifold(Model &input);
void ManifoldPreprocess(Params &params, Model &m);
}
93 changes: 88 additions & 5 deletions src/process.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#include "./process.h"
#include "mcts.h"
#include "config.h"
#include "./preprocess.h"
#include "bvh.h"

#include <iostream>
#include <cmath>
Expand All @@ -10,11 +10,94 @@ namespace coacd
{
thread_local std::mt19937 random_engine;

void ManifoldPreprocess(Params &params, Model &m)
bool IsManifold(Model &input)
{
Model tmp = m;
m.Clear();
SDFManifold(tmp, m, params.prep_resolution, params.dmc_thres);
logger::info(" - Manifold Check");
clock_t start, end;
start = clock();
// Check all edges are shared by exactly two triangles (watertight manifold)
vector<pair<int, int>> edges;
map<pair<int, int>, int> edge_num;
for (int i = 0; i < (int)input.triangles.size(); i++)
{
int idx0 = input.triangles[i][0];
int idx1 = input.triangles[i][1];
int idx2 = input.triangles[i][2];
edges.push_back({idx0, idx1});
edges.push_back({idx1, idx2});
edges.push_back({idx2, idx0});

if (!edge_num.contains({idx0, idx1}))
edge_num[{idx0, idx1}] = 1;
else
{
logger::info("\tWrong triangle orientation");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
if (!edge_num.contains({idx1, idx2}))
edge_num[{idx1, idx2}] = 1;
else
{
logger::info("\tWrong triangle orientation");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
if (!edge_num.contains({idx2, idx0}))
edge_num[{idx2, idx0}] = 1;
else
{
logger::info("\tWrong triangle orientation");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
}

for (int i = 0; i < (int)edges.size(); i++)
{
pair<int, int> oppo_edge = {edges[i].second, edges[i].first};
if (!edge_num.contains(oppo_edge))
{
logger::info("\tUnclosed mesh");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
}
logger::info("[1/3] Edge check finish");

// Check self-intersection
BVH bvhTree(input);
for (int i = 0; i < (int)input.triangles.size(); i++)
{
bool is_intersect = bvhTree.IntersectBVH(input.triangles[i], 0);
if (is_intersect)
{
logger::info("\tTriangle self-intersection");
end = clock();
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);
return false;
}
}
logger::info("[2/3] Self-intersection check finish");

// Check triange orientation
double mesh_vol = MeshVolume(input);
if (mesh_vol < 0)
{
// Reverse all the triangles
for (int i = 0; i < (int)input.triangles.size(); i++)
std::swap(input.triangles[i][0], input.triangles[i][1]);
}
end = clock();

logger::info("[3/3] Triangle orientation check finish. Reversed: {}", mesh_vol < 0);
logger::info("Manifold Check Time: {}s", double(end - start) / CLOCKS_PER_SEC);

return true;
}

void MergeCH(Model &ch1, Model &ch2, Model &ch)
Expand Down
5 changes: 4 additions & 1 deletion src/process.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include <algorithm>
#include <assert.h>
#include <regex>
#ifdef _OPENMP
#include <omp.h>
#endif

#include "./io.h"
#include "clip.h"
Expand All @@ -22,10 +25,10 @@ namespace coacd
{
extern thread_local std::mt19937 random_engine;

void ManifoldPreprocess(Params &params, Model &m);
void MergeCH(Model &ch1, Model &ch2, Model &ch);
double MergeConvexHulls(Model &m, vector<Model> &meshs, vector<Model> &cvxs, Params &params, double epsilon = 0.02, double threshold = 0.01);
vector<Model> Compute(Model &mesh, Params &params);
bool IsManifold(Model &input);

inline void addNeighbor(map<pair<int, int>, pair<int, int>> &edge_map, pair<int, int> &edge, vector<int> &neighbors, int idx)
{
Expand Down

0 comments on commit 72d1f9c

Please sign in to comment.