/*************************************************************************** * Copyright (c) Jürgen Riegel * * * * 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_MESH_H #define MESH_MESH_H #include #include #include #include #include #include #include #include #include #include #include "Core/MeshKernel.h" #include "Core/MeshIO.h" #include "Core/Iterator.h" #include "MeshPoint.h" #include "Facet.h" #include "MeshPoint.h" #include "Segment.h" namespace Py { class List; } namespace Base { class Polygon2d; class ViewProjMethod; } namespace MeshCore { class AbstractPolygonTriangulator; } namespace Mesh { class MeshObject; class MeshExport MeshSegment : public Data::Segment { TYPESYSTEM_HEADER(); public: virtual std::string getName() const { return "MeshSegment"; } Base::Reference mesh; std::unique_ptr segment; }; /** * The MeshObject class provides an interface for the underlying MeshKernel class and * most of its algorithm on it. * @note Each instance of MeshObject has its own instance of a MeshKernel so it's not possible * that several instances of MeshObject manage one instance of MeshKernel. */ class MeshExport MeshObject : public Data::ComplexGeoData { TYPESYSTEM_HEADER(); public: enum GeometryType {PLANE, CYLINDER, SPHERE}; enum CutType {INNER, OUTER}; // typedef needed for cross-section typedef std::pair TPlane; typedef std::list > TPolylines; MeshObject(); explicit MeshObject(const MeshCore::MeshKernel& Kernel); explicit MeshObject(const MeshCore::MeshKernel& Kernel, const Base::Matrix4D &Mtrx); MeshObject(const MeshObject&); virtual ~MeshObject(); void operator = (const MeshObject&); /** @name Subelement management */ //@{ /** Sub type list * List of different subelement types * its NOT a list of the subelements itself */ virtual std::vector getElementTypes() const; virtual unsigned long countSubElements(const char* Type) const; /// get the subelement by type and number virtual Data::Segment* getSubElement(const char* Type, unsigned long) const; /** Get faces from segment */ virtual void getFacesFromSubElement( const Data::Segment*, std::vector &Points, std::vector &PointNormals, std::vector &faces) const; //@} void setTransform(const Base::Matrix4D& rclTrf); Base::Matrix4D getTransform() const; void transformGeometry(const Base::Matrix4D &rclMat); /** * Swaps the content of \a Kernel and the internal mesh kernel. */ void swap(MeshCore::MeshKernel& Kernel); void swap(MeshObject& mesh); /** @name Querying */ //@{ std::string representation() const; std::string topologyInfo() const; unsigned long countPoints() const; unsigned long countFacets() const; unsigned long countEdges () const; unsigned long countSegments() const; bool isSolid() const; MeshPoint getPoint(PointIndex) const; Mesh::Facet getFacet(FacetIndex) const; double getSurface() const; double getVolume() const; /** Get points from object with given accuracy */ virtual void getPoints(std::vector &Points, std::vector &Normals, float Accuracy, uint16_t flags=0) const; virtual void getFaces(std::vector &Points,std::vector &Topo, float Accuracy, uint16_t flags=0) const; std::vector getPointsFromFacets(const std::vector& facets) const; //@} void setKernel(const MeshCore::MeshKernel& m); MeshCore::MeshKernel& getKernel() { return _kernel; } const MeshCore::MeshKernel& getKernel() const { return _kernel; } virtual Base::BoundBox3d getBoundBox() const; virtual bool getCenterOfGravity(Base::Vector3d& center) const; /** @name I/O */ //@{ // Implemented from Persistence unsigned int getMemSize () const; void Save (Base::Writer &writer) const; void SaveDocFile (Base::Writer &writer) const; void Restore(Base::XMLReader &reader); void RestoreDocFile(Base::Reader &reader); void save(const char* file,MeshCore::MeshIO::Format f=MeshCore::MeshIO::Undefined, const MeshCore::Material* mat = nullptr, const char* objectname = nullptr) const; void save(std::ostream&,MeshCore::MeshIO::Format f, const MeshCore::Material* mat = nullptr, const char* objectname = nullptr) const; bool load(const char* file, MeshCore::Material* mat = nullptr); bool load(std::istream&, MeshCore::MeshIO::Format f, MeshCore::Material* mat = nullptr); // Save and load in internal format void save(std::ostream&) const; void load(std::istream&); //@} /** @name Manipulation */ //@{ void addFacet(const MeshCore::MeshGeomFacet& facet); void addFacets(const std::vector& facets); void addFacets(const std::vector &facets, bool checkManifolds); void addFacets(const std::vector &facets, const std::vector& points, bool checkManifolds); void addFacets(const std::vector &facets, const std::vector& points, bool checkManifolds); void setFacets(const std::vector& facets); void setFacets(const std::vector &facets, const std::vector& points); /** * Combines two independent mesh objects. * @note The mesh object we want to add must not overlap or intersect with * this mesh object. */ void addMesh(const MeshObject&); /** * Combines two independent mesh objects. * @note The mesh object we want to add must not overlap or intersect with * this mesh object. */ void addMesh(const MeshCore::MeshKernel&); void deleteFacets(const std::vector& removeIndices); void deletePoints(const std::vector& removeIndices); std::vector > getComponents() const; unsigned long countComponents() const; void removeComponents(unsigned long); /** * Checks for the given facet indices what will be the degree for each point * when these facets are removed from the mesh kernel. * The point degree information is stored in \a point_degree. The return value * gives the number of points which will have a degree of zero. */ unsigned long getPointDegree(const std::vector& facets, std::vector& point_degree) const; void fillupHoles(unsigned long, int, MeshCore::AbstractPolygonTriangulator&); void offset(float fSize); void offsetSpecial2(float fSize); void offsetSpecial(float fSize, float zmax, float zmin); /// clears the Mesh void clear(); void transformToEigenSystem(); Base::Matrix4D getEigenSystem(Base::Vector3d& v) const; void movePoint(PointIndex, const Base::Vector3d& v); void setPoint(PointIndex, const Base::Vector3d& v); void smooth(int iterations, float d_max); void decimate(float fTolerance, float fReduction); void decimate(int targetSize); Base::Vector3d getPointNormal(PointIndex) const; std::vector getPointNormals() const; void crossSections(const std::vector&, std::vector §ions, float fMinEps = 1.0e-2f, bool bConnectPolygons = false) const; void cut(const Base::Polygon2d& polygon, const Base::ViewProjMethod& proj, CutType); void trim(const Base::Polygon2d& polygon, const Base::ViewProjMethod& proj, CutType); void trim(const Base::Vector3f& base, const Base::Vector3f& normal); //@} /** @name Selection */ //@{ void deleteSelectedFacets(); void deleteSelectedPoints(); void addFacetsToSelection(const std::vector&) const; void addPointsToSelection(const std::vector&) const; void removeFacetsFromSelection(const std::vector&) const; void removePointsFromSelection(const std::vector&) const; unsigned long countSelectedFacets() const; bool hasSelectedFacets() const; unsigned long countSelectedPoints() const; bool hasSelectedPoints() const; void getFacetsFromSelection(std::vector&) const; void getPointsFromSelection(std::vector&) const; void clearFacetSelection() const; void clearPointSelection() const; //@} /** @name Boolean operations */ //@{ MeshObject* unite(const MeshObject&) const; MeshObject* intersect(const MeshObject&) const; MeshObject* subtract(const MeshObject&) const; MeshObject* inner(const MeshObject&) const; MeshObject* outer(const MeshObject&) const; std::vector< std::vector > section(const MeshObject&, bool connectLines, float fMinDist) const; //@} /** @name Topological operations */ //@{ void refine(); void removeNeedles(float); void optimizeTopology(float); void optimizeEdges(); void splitEdges(); void splitEdge(FacetIndex, FacetIndex, const Base::Vector3f&); void splitFacet(FacetIndex, const Base::Vector3f&, const Base::Vector3f&); void swapEdge(FacetIndex, FacetIndex); void collapseEdge(FacetIndex, FacetIndex); void collapseFacet(FacetIndex); void collapseFacets(const std::vector&); void insertVertex(FacetIndex, const Base::Vector3f& v); void snapVertex(FacetIndex, const Base::Vector3f& v); //@} /** @name Mesh validation */ //@{ unsigned long countNonUniformOrientedFacets() const; void flipNormals(); void harmonizeNormals(); void validateIndices(); void validateCaps(float fMaxAngle, float fSplitFactor); void validateDeformations(float fMaxAngle, float fEps); void validateDegenerations(float fEps); void removeDuplicatedPoints(); void removeDuplicatedFacets(); bool hasNonManifolds() const; bool hasInvalidNeighbourhood() const; bool hasPointsOutOfRange() const; bool hasFacetsOutOfRange() const; bool hasCorruptedFacets() const; void removeNonManifolds(); void removeNonManifoldPoints(); bool hasSelfIntersections() const; void removeSelfIntersections(); void removeSelfIntersections(const std::vector&); void removeFoldsOnSurface(); void removeFullBoundaryFacets(); bool hasInvalidPoints() const; void removeInvalidPoints(); void mergeFacets(); bool hasPointsOnEdge() const; void removePointsOnEdge(bool fillBoundary); //@} /** @name Mesh segments */ //@{ void addSegment(const Segment&); void addSegment(const std::vector&); const Segment& getSegment(unsigned long) const; Segment& getSegment(unsigned long); MeshObject* meshFromSegment(const std::vector&) const; std::vector getSegmentsOfType(GeometryType, float dev, unsigned long minFacets) const; //@} /** @name Primitives */ //@{ static MeshObject* createMeshFromList(Py::List& list); static MeshObject* createSphere(float, int); static MeshObject* createEllipsoid(float, float, int); static MeshObject* createCylinder(float, float, int, float, int); static MeshObject* createCone(float, float, float, int, float, int); static MeshObject* createTorus(float, float, int); static MeshObject* createCube(float, float, float); static MeshObject* createCube(float, float, float, float); //@} public: class MeshExport const_point_iterator { public: const_point_iterator(const MeshObject*, PointIndex index); const_point_iterator(const const_point_iterator& pi); ~const_point_iterator(); const_point_iterator& operator=(const const_point_iterator& fi); const MeshPoint& operator*(); const MeshPoint* operator->(); bool operator==(const const_point_iterator& fi) const; bool operator!=(const const_point_iterator& fi) const; const_point_iterator& operator++(); const_point_iterator& operator--(); private: void dereference(); const MeshObject* _mesh; MeshPoint _point; MeshCore::MeshPointIterator _p_it; }; class MeshExport const_facet_iterator { public: const_facet_iterator(const MeshObject*, FacetIndex index); const_facet_iterator(const const_facet_iterator& fi); ~const_facet_iterator(); const_facet_iterator& operator=(const const_facet_iterator& fi); Mesh::Facet& operator*(); Mesh::Facet* operator->(); bool operator==(const const_facet_iterator& fi) const; bool operator!=(const const_facet_iterator& fi) const; const_facet_iterator& operator++(); const_facet_iterator& operator--(); private: void dereference(); const MeshObject* _mesh; Mesh::Facet _facet; MeshCore::MeshFacetIterator _f_it; }; /** @name Iterator */ //@{ const_point_iterator points_begin() const { return const_point_iterator(this, 0); } const_point_iterator points_end() const { return const_point_iterator(this, countPoints()); } const_facet_iterator facets_begin() const { return const_facet_iterator(this, 0); } const_facet_iterator facets_end() const { return const_facet_iterator(this, countFacets()); } typedef std::vector::const_iterator const_segment_iterator; const_segment_iterator segments_begin() const { return _segments.begin(); } const_segment_iterator segments_end() const { return _segments.end(); } //@} // friends friend class Segment; private: void deletedFacets(const std::vector& remFacets); void updateMesh(const std::vector&); void updateMesh(); void swapKernel(MeshCore::MeshKernel& m, const std::vector& g); void copySegments(const MeshObject&); void swapSegments(MeshObject&); private: Base::Matrix4D _Mtrx; MeshCore::MeshKernel _kernel; std::vector _segments; static float Epsilon; }; } // namespace Mesh #endif // MESH_MESH_H