Эх сурвалжийг харах

Refactor.

Former-commit-id: e99d3518208d2adf1c958b85f921c9639fcf3663
Qingnan Zhou 9 жил өмнө
parent
commit
816236353b

+ 128 - 0
include/igl/boolean/BinaryWindingNumberOperations.h

@@ -0,0 +1,128 @@
+// This file is part of libigl, a simple c++ geometry processing library.
+// 
+// Copyright (C) 2015 Qingnan Zhou <qnzhou@gmail.com>
+// 
+// This Source Code Form is subject to the terms of the Mozilla Public License 
+// v. 2.0. If a copy of the MPL was not distributed with this file, You can 
+// obtain one at http://mozilla.org/MPL/2.0/.
+//
+#ifndef IGL_BINARY_WINDING_NUMBER_OPERATIONS
+#define IGL_BINARY_WINDING_NUMBER_OPERATIONS
+
+#include <stdexcept>
+#include <igl/igl_inline.h>
+#include "MeshBooleanType.h"
+#include <Eigen/Core>
+
+namespace igl
+{
+    namespace boolean
+    {
+        template <igl::boolean::MeshBooleanType Op>
+        class BinaryWindingNumberOperations {
+            public:
+                template<typename DerivedW>
+                    typename DerivedW::Scalar operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        throw (std::runtime_error("not implemented!"));
+                    }
+        };
+
+        template <>
+        class BinaryWindingNumberOperations<igl::boolean::MESH_BOOLEAN_TYPE_UNION> {
+            public:
+                template<typename DerivedW>
+                    typename DerivedW::Scalar operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        return win_nums(0) > 0 || win_nums(1) > 0;
+                    }
+        };
+
+        template <>
+        class BinaryWindingNumberOperations<igl::boolean::MESH_BOOLEAN_TYPE_INTERSECT> {
+            public:
+                template<typename DerivedW>
+                    typename DerivedW::Scalar operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        return win_nums(0) > 0 && win_nums(1) > 0;
+                    }
+        };
+
+        template <>
+        class BinaryWindingNumberOperations<igl::boolean::MESH_BOOLEAN_TYPE_MINUS> {
+            public:
+                template<typename DerivedW>
+                    typename DerivedW::Scalar operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        return win_nums(0) > 0 && win_nums(1) <= 0;
+                    }
+        };
+
+        template <>
+        class BinaryWindingNumberOperations<igl::boolean::MESH_BOOLEAN_TYPE_XOR> {
+            public:
+                template<typename DerivedW>
+                    typename DerivedW::Scalar operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        return (win_nums(0) > 0 && win_nums(1) <= 0) ||
+                            (win_nums(0) <= 0 && win_nums(1) > 0);
+                    }
+        };
+
+        template <>
+        class BinaryWindingNumberOperations<igl::boolean::MESH_BOOLEAN_TYPE_RESOLVE> {
+            public:
+                template<typename DerivedW>
+                    typename DerivedW::Scalar operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        return true;
+                    }
+        };
+
+        typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> BinaryUnion;
+        typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> BinaryIntersect;
+        typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> BinaryMinus;
+        typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> BinaryXor;
+        typedef BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_RESOLVE> BinaryResolve;
+
+        enum KeeperType {
+            KEEP_INSIDE,
+            KEEP_ALL
+        };
+
+        template<KeeperType T>
+        class WindingNumberFilter {
+            public:
+                template<typename DerivedW>
+                    short operator()(
+                            const Eigen::PlainObjectBase<DerivedW>& win_nums) const {
+                        throw std::runtime_error("Not implemented");
+                    }
+        };
+
+        template<>
+        class WindingNumberFilter<KEEP_INSIDE> {
+            public:
+                template<typename T>
+                    short operator()(T out_w, T in_w) const {
+                        if (in_w > 0 && out_w <= 0) return 1;
+                        else if (in_w <= 0 && out_w > 0) return -1;
+                        else return 0;
+                    }
+        };
+
+        template<>
+        class WindingNumberFilter<KEEP_ALL> {
+            public:
+                template<typename T>
+                    short operator()(T out_w, T in_w) const {
+                        return 1;
+                    }
+        };
+
+        typedef WindingNumberFilter<KEEP_INSIDE> KeepInside;
+        typedef WindingNumberFilter<KEEP_ALL> KeepAll;
+    }
+}
+
+#endif

+ 31 - 77
include/igl/boolean/mesh_boolean.cpp

@@ -16,6 +16,8 @@
 
 #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
 
+#include "BinaryWindingNumberOperations.h"
+
 namespace igl {
     namespace boolean {
         namespace mesh_boolean_helper {
@@ -158,55 +160,6 @@ namespace igl {
                     J2.row(i) = J1.row(kept_faces[i]);
                 }
             }
-
-            typedef Eigen::Matrix<int, 1, Eigen::Dynamic> WindingNumbers;
-            typedef std::function<int(const WindingNumbers&)> WindingNumberOperation;
-
-            WindingNumberOperation binary_union() {
-                return [](const WindingNumbers& win_nums) -> int{
-                    return win_nums[0] > 0 || win_nums[1] > 0;
-                };
-            }
-
-            WindingNumberOperation binary_intersect() {
-                return [](const WindingNumbers& win_nums) -> int{
-                    return win_nums[0] > 0 && win_nums[1] > 0;
-                };
-            }
-
-            WindingNumberOperation binary_difference() {
-                return [](const WindingNumbers& win_nums) -> int{
-                    return win_nums[0] > 0 && win_nums[1] <= 0;
-                };
-            }
-
-            WindingNumberOperation binary_xor() {
-                return [](const WindingNumbers& win_nums) -> int{
-                    return (win_nums[0] > 0 && win_nums[1] <= 0) ||
-                           (win_nums[0] <= 0 && win_nums[1] > 0);
-                };
-            }
-
-            WindingNumberOperation binary_resolve() {
-                return [](const WindingNumbers& win_nums) -> int{
-                    return true;
-                };
-            }
-
-            typedef std::function<short(int, int)> ToKeepFunc;
-            ToKeepFunc keep_inside() {
-                return [](int out_w, int in_w) -> short {
-                    if (in_w > 0 && out_w <= 0) return 1;
-                    else if (in_w <= 0 && out_w > 0) return -1;
-                    else return 0;
-                };
-            }
-
-            ToKeepFunc keep_all() {
-                return [](int out_w, int in_w) -> short {
-                    return true;
-                };
-            }
         }
     }
 }
@@ -346,48 +299,49 @@ IGL_INLINE void igl::boolean::mesh_boolean(
         Eigen::PlainObjectBase<DerivedFC > & FC,
         Eigen::PlainObjectBase<DerivedJ > & J) {
     using namespace igl::boolean::mesh_boolean_helper;
-    WindingNumberOperation op;
-    ToKeepFunc keep;
+    typedef Eigen::Matrix<
+        ExactScalar,
+        Eigen::Dynamic,
+        Eigen::Dynamic,
+        DerivedVC::IsRowMajor> MatrixXES;
+    std::function<void(
+            const Eigen::PlainObjectBase<DerivedVA>&,
+            const Eigen::PlainObjectBase<DerivedFA>&,
+            Eigen::PlainObjectBase<MatrixXES>&,
+            Eigen::PlainObjectBase<DerivedFC>&,
+            Eigen::PlainObjectBase<DerivedJ>&)> resolve_func =
+        igl_resolve<DerivedVA, DerivedFA, MatrixXES, DerivedFC, DerivedJ>;
+
     switch (type) {
         case MESH_BOOLEAN_TYPE_UNION:
-            op = binary_union();
-            keep = keep_inside();
+            igl::boolean::per_face_winding_number_binary_operation(
+                    VA, FA, VB, FB, igl::boolean::BinaryUnion(),
+                    igl::boolean::KeepInside(), resolve_func, VC, FC, J);
             break;
         case MESH_BOOLEAN_TYPE_INTERSECT:
-            op = binary_intersect();
-            keep = keep_inside();
+            igl::boolean::per_face_winding_number_binary_operation(
+                    VA, FA, VB, FB, igl::boolean::BinaryIntersect(),
+                    igl::boolean::KeepInside(), resolve_func, VC, FC, J);
             break;
         case MESH_BOOLEAN_TYPE_MINUS:
-            op = binary_difference();
-            keep = keep_inside();
+            igl::boolean::per_face_winding_number_binary_operation(
+                    VA, FA, VB, FB, igl::boolean::BinaryMinus(),
+                    igl::boolean::KeepInside(), resolve_func, VC, FC, J);
             break;
         case MESH_BOOLEAN_TYPE_XOR:
-            op = binary_xor();
-            keep = keep_inside();
+            igl::boolean::per_face_winding_number_binary_operation(
+                    VA, FA, VB, FB, igl::boolean::BinaryXor(),
+                    igl::boolean::KeepInside(), resolve_func, VC, FC, J);
             break;
         case MESH_BOOLEAN_TYPE_RESOLVE:
-            op = binary_resolve();
-            keep = keep_all();
+            //op = binary_resolve();
+            igl::boolean::per_face_winding_number_binary_operation(
+                    VA, FA, VB, FB, igl::boolean::BinaryResolve(),
+                    igl::boolean::KeepAll(), resolve_func, VC, FC, J);
             break;
         default:
             throw std::runtime_error("Unsupported boolean type.");
     }
-
-    typedef Eigen::Matrix<
-        ExactScalar,
-        Eigen::Dynamic,
-        Eigen::Dynamic,
-        DerivedVC::IsRowMajor> MatrixXES;
-    std::function<void(
-            const Eigen::PlainObjectBase<DerivedVA>&,
-            const Eigen::PlainObjectBase<DerivedFA>&,
-            Eigen::PlainObjectBase<MatrixXES>&,
-            Eigen::PlainObjectBase<DerivedFC>&,
-            Eigen::PlainObjectBase<DerivedJ>&)> resolve_func =
-        igl_resolve<DerivedVA, DerivedFA, MatrixXES, DerivedFC, DerivedJ>;
-
-    igl::boolean::per_face_winding_number_binary_operation(
-            VA, FA, VB, FB, op, keep, resolve_func, VC, FC, J);
 }
 
 template <