123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- // 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_COPYLEFT_CGAL_BINARY_WINDING_NUMBER_OPERATIONS_H
- #define IGL_COPYLEFT_CGAL_BINARY_WINDING_NUMBER_OPERATIONS_H
- #include <stdexcept>
- #include "../../igl_inline.h"
- #include "../../MeshBooleanType.h"
- #include <Eigen/Core>
- // TODO: This is not written according to libigl style. These should be
- // function handles.
- //
- // Why is this templated on DerivedW
- //
- // These are all generalized to n-ary operations
- namespace igl
- {
- namespace copyleft
- {
- namespace cgal
- {
- template <igl::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!"));
- }
- };
- // A ∪ B ∪ ... ∪ Z
- template <>
- class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_UNION> {
- public:
- template<typename DerivedW>
- typename DerivedW::Scalar operator()(
- const Eigen::PlainObjectBase<DerivedW>& win_nums) const
- {
- for(int i = 0;i<win_nums.size();i++)
- {
- if(win_nums(i) > 0) return true;
- }
- return false;
- }
- };
- // A ∩ B ∩ ... ∩ Z
- template <>
- class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_INTERSECT> {
- public:
- template<typename DerivedW>
- typename DerivedW::Scalar operator()(
- const Eigen::PlainObjectBase<DerivedW>& win_nums) const
- {
- for(int i = 0;i<win_nums.size();i++)
- {
- if(win_nums(i)<=0) return false;
- }
- return true;
- }
- };
- // A \ B \ ... \ Z = A \ (B ∪ ... ∪ Z)
- template <>
- class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_MINUS> {
- public:
- template<typename DerivedW>
- typename DerivedW::Scalar operator()(
- const Eigen::PlainObjectBase<DerivedW>& win_nums) const
- {
- assert(win_nums.size()>1);
- // Union of objects 1 through n-1
- bool union_rest = false;
- for(int i = 1;i<win_nums.size();i++)
- {
- union_rest = union_rest || win_nums(i) > 0;
- if(union_rest) break;
- }
- // Must be in object 0 and not in union of objects 1 through n-1
- return win_nums(0) > 0 && !union_rest;
- }
- };
- // A ∆ B ∆ ... ∆ Z (equivalent to set inside odd number of objects)
- template <>
- class BinaryWindingNumberOperations<MESH_BOOLEAN_TYPE_XOR> {
- public:
- template<typename DerivedW>
- typename DerivedW::Scalar operator()(
- const Eigen::PlainObjectBase<DerivedW>& win_nums) const
- {
- // If inside an odd number of objects
- int count = 0;
- for(int i = 0;i<win_nums.size();i++)
- {
- if(win_nums(i) > 0) count++;
- }
- return count % 2 == 1;
- }
- };
- template <>
- class BinaryWindingNumberOperations<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
|