/*************************************************************************** * Copyright (c) 2005 Berthold Grupp * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #ifndef MESH_SETOPERATIONS_H #define MESH_SETOPERATIONS_H #include #include #include #include "MeshKernel.h" #include "Elements.h" #include "Iterator.h" #include "Visitor.h" #include // forward declarations namespace MeshCore { class MeshGeomFacet; class MeshGeomEdge; class MeshBuilder; class MeshKernel; class MeshFacetGrid; class MeshFacetArray; class MeshFacetIterator; /** * The MeshAlgorithm class provides algorithms base on meshes. */ class MeshExport SetOperations { public: enum OperationType { Union, Intersect, Difference, Inner, Outer }; /// Construction SetOperations (const MeshKernel &cutMesh1, const MeshKernel &cutMesh2, MeshKernel &result, OperationType opType, float minDistanceToPoint = 1e-5f); /// Destruction virtual ~SetOperations (); public: /** Cut this mesh with another one. The result is a list of polylines * If the distance of the polyline to one of the points is less than minDistanceToPoint the polyline goes direct to the point */ void Do (); protected: const MeshKernel &_cutMesh0; /** Mesh for set operations source 1 */ const MeshKernel &_cutMesh1; /** Mesh for set operations source 2 */ MeshKernel &_resultMesh; /** Result mesh */ OperationType _operationType; /** Set Operation Type */ float _minDistanceToPoint; /** Minimal distance to facet corner points */ private: // Helper class cutting edge to his two attached facets class Edge { public: MeshPoint pt1, pt2; // edge Edge () { } Edge (MeshPoint p1, MeshPoint p2) { if (p1 < p2) { pt1 = p1; pt2 = p2; } else { pt2 = p1; pt1 = p2; } } bool operator == (const Edge &edge) const { return (pt1 == edge.pt1) && (pt2 == edge.pt2); } bool operator < (const Edge &edge) const { return (pt1 == edge.pt1) ? (pt2 < edge.pt2) : (pt1 < edge.pt1); } }; class EdgeInfo { public: int fcounter[2]; // counter of facets attacted to the edge MeshGeomFacet facets[2][2]; // Geom-Facets attached to the edge FacetIndex facet[2]; // underlying Facet-Index EdgeInfo () { fcounter[0] = 0; fcounter[1] = 0; facet[0] = 0; facet[1] = 0; } }; //class CollectFacetVisitor : public MeshFacetVisitor //{ // public: // std::vector &_facets; // MeshKernel &_mesh; // std::map &_edges; // int _side; // float _mult; // int _addFacets; // 0: add facets to the result 1: do not add facets to the result // Base::Builder3D& _builder; // CollectFacetVisitor (MeshKernel& mesh, std::vector& facets, std::map& edges, int side, float mult, Base::Builder3D& builder); // bool Visit (MeshFacet &rclFacet, const MeshFacet &rclFrom, unsigned long ulFInd, unsigned long ulLevel); // bool AllowVisit (MeshFacet& rclFacet, MeshFacet& rclFrom, unsigned long ulFInd, unsigned long ulLevel, unsigned short neighbourIndex); //}; class CollectFacetVisitor : public MeshFacetVisitor { public: std::vector &_facets; const MeshKernel &_mesh; std::map &_edges; int _side; float _mult; int _addFacets; // 0: add facets to the result 1: do not add facets to the result Base::Builder3D& _builder; CollectFacetVisitor (const MeshKernel& mesh, std::vector& facets, std::map& edges, int side, float mult, Base::Builder3D& builder); bool Visit (const MeshFacet &rclFacet, const MeshFacet &rclFrom, FacetIndex ulFInd, unsigned long ulLevel); bool AllowVisit (const MeshFacet& rclFacet, const MeshFacet& rclFrom, FacetIndex ulFInd, unsigned long ulLevel, unsigned short neighbourIndex); }; /** all points from cut */ std::set _cutPoints; /** all edges */ std::map _edges; /** map from facet index to its cut points (mesh 1 and mesh 2) Key: Facet-Index Value: List of iterators of set */ std::map::iterator> > _facet2points[2]; /** Facets collected from region growing */ std::vector _facetsOf[2]; std::vector _newMeshFacets[2]; /** Cut mesh 1 with mesh 2 */ void Cut (std::set& facetsNotCuttingEdge0, std::set& facetsCuttingEdge1); /** Trianglute each facets cut with its cutting points */ void TriangulateMesh (const MeshKernel &cutMesh, int side); /** search facets for adding (with region growing) */ void CollectFacets (int side, float mult); /** close gap in the mesh */ void CloseGaps (MeshBuilder& meshBuilder); /** visual debugger */ Base::Builder3D _builder; }; /*! Determine the intersections between two meshes. */ class MeshExport MeshIntersection { public: struct Tuple { Base::Vector3f p1, p2; FacetIndex f1, f2; }; struct Triple { Base::Vector3f p; FacetIndex f1, f2; }; struct Pair { Base::Vector3f p; FacetIndex f; }; MeshIntersection(const MeshKernel& m1, const MeshKernel& m2, float dist) : kernel1(m1) , kernel2(m2) , minDistance(dist) { } ~MeshIntersection() { } bool hasIntersection() const; void getIntersection(std::list&) const; /*! From an unsorted list of intersection points make a list of sorted intersection points. If parameter \a onlyclosed is set to true then only closed intersection curves are taken and all other curves are filtered out. */ void connectLines(bool onlyclosed, const std::list&, std::list< std::list >&); private: static bool testIntersection(const MeshKernel& k1, const MeshKernel& k2); private: const MeshKernel& kernel1; const MeshKernel& kernel2; float minDistance; }; } // namespace MeshCore #endif // MESH_SETOPERATIONS_H