427 lines
16 KiB
C++
427 lines
16 KiB
C++
/***************************************************************************
|
|
* Copyright (c) Jürgen Riegel <juergen.riegel@web.de> *
|
|
* *
|
|
* 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 <vector>
|
|
#include <list>
|
|
#include <set>
|
|
#include <string>
|
|
#include <map>
|
|
|
|
#include <Base/Matrix.h>
|
|
#include <Base/Vector3D.h>
|
|
|
|
#include <App/PropertyStandard.h>
|
|
#include <App/PropertyGeo.h>
|
|
#include <App/ComplexGeoData.h>
|
|
|
|
#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<MeshObject> mesh;
|
|
std::unique_ptr<Mesh::Segment> 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<Base::Vector3f, Base::Vector3f> TPlane;
|
|
typedef std::list<std::vector<Base::Vector3f> > 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<const char*> 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<Base::Vector3d> &Points,
|
|
std::vector<Base::Vector3d> &PointNormals,
|
|
std::vector<Facet> &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<Base::Vector3d> &Points,
|
|
std::vector<Base::Vector3d> &Normals,
|
|
float Accuracy, uint16_t flags=0) const;
|
|
virtual void getFaces(std::vector<Base::Vector3d> &Points,std::vector<Facet> &Topo,
|
|
float Accuracy, uint16_t flags=0) const;
|
|
std::vector<PointIndex> getPointsFromFacets(const std::vector<FacetIndex>& 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<MeshCore::MeshGeomFacet>& facets);
|
|
void addFacets(const std::vector<MeshCore::MeshFacet> &facets,
|
|
bool checkManifolds);
|
|
void addFacets(const std::vector<MeshCore::MeshFacet> &facets,
|
|
const std::vector<Base::Vector3f>& points,
|
|
bool checkManifolds);
|
|
void addFacets(const std::vector<Data::ComplexGeoData::Facet> &facets,
|
|
const std::vector<Base::Vector3d>& points,
|
|
bool checkManifolds);
|
|
void setFacets(const std::vector<MeshCore::MeshGeomFacet>& facets);
|
|
void setFacets(const std::vector<Data::ComplexGeoData::Facet> &facets,
|
|
const std::vector<Base::Vector3d>& 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<FacetIndex>& removeIndices);
|
|
void deletePoints(const std::vector<PointIndex>& removeIndices);
|
|
std::vector<std::vector<FacetIndex> > 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<FacetIndex>& facets,
|
|
std::vector<PointIndex>& 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<Base::Vector3d> getPointNormals() const;
|
|
void crossSections(const std::vector<TPlane>&, std::vector<TPolylines> §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<FacetIndex>&) const;
|
|
void addPointsToSelection(const std::vector<PointIndex>&) const;
|
|
void removeFacetsFromSelection(const std::vector<FacetIndex>&) const;
|
|
void removePointsFromSelection(const std::vector<PointIndex>&) const;
|
|
unsigned long countSelectedFacets() const;
|
|
bool hasSelectedFacets() const;
|
|
unsigned long countSelectedPoints() const;
|
|
bool hasSelectedPoints() const;
|
|
void getFacetsFromSelection(std::vector<FacetIndex>&) const;
|
|
void getPointsFromSelection(std::vector<PointIndex>&) 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<Base::Vector3f> > 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<FacetIndex>&);
|
|
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<FacetIndex>&);
|
|
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<FacetIndex>&);
|
|
const Segment& getSegment(unsigned long) const;
|
|
Segment& getSegment(unsigned long);
|
|
MeshObject* meshFromSegment(const std::vector<FacetIndex>&) const;
|
|
std::vector<Segment> 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<Segment>::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<FacetIndex>& remFacets);
|
|
void updateMesh(const std::vector<FacetIndex>&);
|
|
void updateMesh();
|
|
void swapKernel(MeshCore::MeshKernel& m, const std::vector<std::string>& g);
|
|
void copySegments(const MeshObject&);
|
|
void swapSegments(MeshObject&);
|
|
|
|
private:
|
|
Base::Matrix4D _Mtrx;
|
|
MeshCore::MeshKernel _kernel;
|
|
std::vector<Segment> _segments;
|
|
static float Epsilon;
|
|
};
|
|
|
|
} // namespace Mesh
|
|
|
|
|
|
#endif // MESH_MESH_H
|