From 38ab9e443cfa0428c6af90ea527d39922b6876c2 Mon Sep 17 00:00:00 2001 From: SarahWeiii <13659185706@163.com> Date: Sat, 20 Jul 2024 16:37:14 +0800 Subject: [PATCH] add ch extrude (#44) --- main.cpp | 8 ++++++ public/coacd.cpp | 9 ++++++- public/coacd.h | 1 + python/package/__init__.py | 6 +++++ python/package/bin/coacd | 15 +++++++++++ setup.py | 2 +- src/config.h | 4 +++ src/io.cpp | 2 ++ src/process.cpp | 55 ++++++++++++++++++++++++++++++++++++++ src/process.h | 6 +++-- 10 files changed, 104 insertions(+), 4 deletions(-) diff --git a/main.cpp b/main.cpp index 521d5f4..5cec255 100644 --- a/main.cpp +++ b/main.cpp @@ -66,6 +66,14 @@ int main(int argc, char *argv[]) { sscanf(argv[i + 1], "%d", ¶ms.max_ch_vertex); } + if (strcmp(argv[i], "-ex") == 0 || strcmp(argv[i], "--extrude") == 0) + { + params.extrude = true; + } + if (strcmp(argv[i], "-em") == 0 || strcmp(argv[i], "--extrude-margin") == 0) + { + sscanf(argv[i + 1], "%le", ¶ms.extrude_margin); + } if (strcmp(argv[i], "--pca") == 0) { params.pca = true; diff --git a/public/coacd.cpp b/public/coacd.cpp index 0c98817..2712612 100644 --- a/public/coacd.cpp +++ b/public/coacd.cpp @@ -17,6 +17,7 @@ std::vector CoACD(Mesh const &input, double threshold, int prep_resolution, int sample_resolution, int mcts_nodes, int mcts_iteration, int mcts_max_depth, bool pca, bool merge, bool decimate, int max_ch_vertex, + bool extrude, double extrude_margin, std::string apx_mode, unsigned int seed) { logger::info("threshold {}", threshold); @@ -30,6 +31,8 @@ std::vector CoACD(Mesh const &input, double threshold, logger::info("merge {}", merge); logger::info("decimate {}", decimate); logger::info("max_ch_vertex {}", max_ch_vertex); + logger::info("extrude {}", extrude); + logger::info("extrude margin {}", extrude_margin); logger::info("approximate mode {}", apx_mode); logger::info("seed {}", seed); @@ -62,6 +65,8 @@ std::vector CoACD(Mesh const &input, double threshold, params.merge = merge; params.decimate = decimate; params.max_ch_vertex = max_ch_vertex; + params.extrude = extrude; + params.extrude_margin = extrude_margin; params.apx_mode = apx_mode; params.seed = seed; @@ -135,6 +140,7 @@ CoACD_MeshArray CoACD_run(CoACD_Mesh const &input, double threshold, int mcts_nodes, int mcts_iteration, int mcts_max_depth, bool pca, bool merge, bool decimate, int max_ch_vertex, + bool extrude, double extrude_margin, int apx_mode, unsigned int seed) { coacd::Mesh mesh; for (uint64_t i = 0; i < input.vertices_count; ++i) { @@ -167,7 +173,8 @@ CoACD_MeshArray CoACD_run(CoACD_Mesh const &input, double threshold, auto meshes = coacd::CoACD(mesh, threshold, max_convex_hull, pm, prep_resolution, sample_resolution, mcts_nodes, - mcts_iteration, mcts_max_depth, pca, merge, decimate, max_ch_vertex, apx, seed); + mcts_iteration, mcts_max_depth, pca, merge, decimate, max_ch_vertex, + extrude, extrude_margin, apx, seed); CoACD_MeshArray arr; arr.meshes_ptr = new CoACD_Mesh[meshes.size()]; diff --git a/public/coacd.h b/public/coacd.h index b70b280..d45455e 100644 --- a/public/coacd.h +++ b/public/coacd.h @@ -56,6 +56,7 @@ CoACD_MeshArray COACD_API CoACD_run(CoACD_Mesh const &input, double threshold, int mcts_nodes, int mcts_iteration, int mcts_max_depth, bool pca, bool merge, bool decimate, int max_ch_vertex, + bool extrude, double extrude_margin, int apx_mode, unsigned int seed); void COACD_API CoACD_setLogLevel(char const *level); diff --git a/python/package/__init__.py b/python/package/__init__.py index eab95bd..56ac82c 100644 --- a/python/package/__init__.py +++ b/python/package/__init__.py @@ -57,6 +57,8 @@ class CoACD_MeshArray(ctypes.Structure): c_bool, c_bool, c_int, + c_bool, + c_double, c_int, c_uint, ] @@ -89,6 +91,8 @@ def run_coacd( merge: bool = True, decimate: bool = False, max_ch_vertex: int = 256, + extrude: bool = False, + extrude_margin: float = 0.01, apx_mode: str = "ch", seed: int = 0, ): @@ -135,6 +139,8 @@ def run_coacd( merge, decimate, max_ch_vertex, + extrude, + extrude_margin, apx, seed, ) diff --git a/python/package/bin/coacd b/python/package/bin/coacd index 1b961ef..03d0250 100644 --- a/python/package/bin/coacd +++ b/python/package/bin/coacd @@ -70,6 +70,19 @@ if __name__ == "__main__": default=256, help="max # vertices per convex hull, works only when decimate is enabled", ) + parser.add_argument( + "-ex", + "--extrude", + action="store_true", + help="If extrude is enabled, extrude the neighboring convex hulls along the overlap face (other faces are unchanged).", + ) + parser.add_argument( + "-em", + "--extrude-margin", + type=float, + default=0.01, + help="extrude margin, works only when extrude is enabled", + ) parser.add_argument( "-c", "--max-convex-hull", @@ -147,6 +160,8 @@ if __name__ == "__main__": merge=not args.no_merge, decimate=args.decimate, max_ch_vertex=args.max_ch_vertex, + extrude=args.extrude, + extrude_margin=args.extrude_margin, apx_mode=args.apx_mode, seed=args.seed, ) diff --git a/setup.py b/setup.py index cf7df48..babfdb9 100644 --- a/setup.py +++ b/setup.py @@ -74,7 +74,7 @@ def build_extension(self, ext): setup( name="coacd", - version="1.0.4", + version="1.0.5", author_email="xiwei@ucsd.edu", keywords="collision convex decomposition", description="Approximate Convex Decomposition for 3D Meshes with Collision-Aware Concavity and Tree Search", diff --git a/src/config.h b/src/config.h index 8fdddc8..faec3c0 100644 --- a/src/config.h +++ b/src/config.h @@ -38,6 +38,8 @@ namespace coacd string apx_mode; bool decimate; int max_ch_vertex; + bool extrude; + double extrude_margin; /////////////// MCTS Config /////////////// int mcts_iteration; @@ -61,6 +63,8 @@ namespace coacd apx_mode = "ch"; decimate = false; max_ch_vertex = 256; + extrude = false; + extrude_margin = 0.01; mcts_iteration = 150; mcts_max_depth = 3; diff --git a/src/io.cpp b/src/io.cpp index 7289985..bbc1a6c 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -19,6 +19,8 @@ namespace coacd logger::info("\tMerge Postprocess (on/off): {}", params.merge); logger::info("\tDecimate Postprocess (on/off): {}", params.decimate); logger::info("\tMax Convex Hull Vertex: {}", params.max_ch_vertex); + logger::info("\tExtrude Postprocess (on/off): {}", params.extrude); + logger::info("\tExtrude Margin: {}", params.extrude_margin); logger::info("\tPCA (ON/OFF): {}", params.pca); logger::info("\tk for Rv: {}", params.rv_k); logger::info("\tHausdorff Sampling Resolution: {}", params.resolution); diff --git a/src/process.cpp b/src/process.cpp index 7e11219..7c0bbc2 100644 --- a/src/process.cpp +++ b/src/process.cpp @@ -359,6 +359,58 @@ namespace coacd return h; } + void ExtrudeCH(Model &ch, Plane overlap_plane, Params ¶ms, double margin) + { + vec3d normal = {overlap_plane.a, overlap_plane.b, overlap_plane.c}; + + // decide the extrude direction by other points of the ch + int side = 0; + for (int i = 0; i < (int)ch.points.size(); i++) + { + vec3d p = ch.points[i]; + side += overlap_plane.Side(p, 1e-4); + } + side = side > 0 ? 1 : -1; + + for (int i = 0; i < (int)ch.points.size(); i++) + { + if (overlap_plane.Side(ch.points[i], 1e-4) == 0) + ch.points[i] = {ch.points[i][0] - side * margin * normal[0], + ch.points[i][1] - side * margin * normal[1], + ch.points[i][2] - side * margin * normal[2]}; + } + + Model tmp; + ch.ComputeAPX(tmp, params.apx_mode, true); + ch = tmp; + } + + void ExtrudeConvexHulls(vector &cvxs, Params ¶ms, double eps) + { + logger::info(" - Extrude Convex Hulls"); + for (int i = 0; i < (int)cvxs.size(); i++) + { + Model cvx = cvxs[i]; + for (int j = 0; j < (int)cvxs.size(); j++) + { + Model convex1 = cvxs[i], convex2 = cvxs[j]; + Plane overlap_plane; + + double dist = MeshDist(convex1, convex2); + bool flag = ComputeOverlapFace(convex1, convex2, overlap_plane); + + // only extrude the convex hulls along the normal of overlap plane + if (dist < eps && flag) + { + ExtrudeCH(convex1, overlap_plane, params, params.extrude_margin); + cvxs[i] = convex1; + ExtrudeCH(convex2, overlap_plane, params, params.extrude_margin); + cvxs[j] = convex2; + } + } + } + } + vector Compute(Model &mesh, Params ¶ms) { vector InputParts = {mesh}; @@ -467,6 +519,9 @@ namespace coacd if (params.decimate) DecimateConvexHulls(parts, params); + if (params.extrude) + ExtrudeConvexHulls(parts, params); + #ifdef _OPENMP end = omp_get_wtime(); logger::info("Compute Time: {}s", double(end - start)); diff --git a/src/process.h b/src/process.h index c91ca88..63e2905 100644 --- a/src/process.h +++ b/src/process.h @@ -26,10 +26,12 @@ namespace coacd extern thread_local std::mt19937 random_engine; void DecimateCH(Model &ch, int tgt_pts, string apx_mode); - void DecimateConvexHulls(vector &cvxs, Params ¶ms); + void DecimateConvexHulls(vector &cvxs, Params ¶ms); void MergeCH(Model &ch1, Model &ch2, Model &ch, Params ¶ms); double MergeConvexHulls(Model &m, vector &meshs, vector &cvxs, Params ¶ms, double epsilon = 0.02, double threshold = 0.01); - vector Compute(Model &mesh, Params ¶ms); + void ExtrudeCH(Model &ch, Plane overlap_plane, Params ¶ms, double margin = 0.01); + void ExtrudeConvexHulls(vector &cvxs, Params ¶ms, double eps = 1e-4); + vector Compute(Model &mesh, Params ¶ms); bool IsManifold(Model &input); inline void addNeighbor(map, pair> &edge_map, pair &edge, vector &neighbors, int idx)