git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5000 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d
357 lines
12 KiB
C++
357 lines
12 KiB
C++
/***************************************************************************
|
|
* Copyright (c) 2005 Imetric 3D GmbH *
|
|
* *
|
|
* 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_EVALUATION_H
|
|
#define MESH_EVALUATION_H
|
|
|
|
#include <list>
|
|
#include <math.h>
|
|
|
|
#include "MeshKernel.h"
|
|
#include "Visitor.h"
|
|
|
|
namespace MeshCore {
|
|
|
|
/**
|
|
* The MeshEvaluation class checks the mesh kernel for correctness with respect to a
|
|
* certain criterion, such as manifoldness, self-intersections, etc.
|
|
* The passed mesh kernel is read-only and cannot be modified.
|
|
* @see MeshEvalTopology
|
|
* @see MeshEvalGeometry
|
|
* The class itself is abstract, hence the method Evaluate() must be implemented
|
|
* by subclasses.
|
|
*/
|
|
class MeshExport MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEvaluation (const MeshKernel &rclB) : _rclMesh(rclB) {}
|
|
virtual ~MeshEvaluation () {}
|
|
|
|
/**
|
|
* Evaluates the mesh kernel with respect to certain criteria. Must be reimplemented by every
|
|
* subclass. This pure virtual function returns false if the mesh kernel is invalid according
|
|
* to this criterion and true if the mesh kernel is correct.
|
|
*/
|
|
virtual bool Evaluate () = 0;
|
|
|
|
protected:
|
|
const MeshKernel& _rclMesh; /**< Mesh kernel */
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshValidation class tries to make a mesh kernel valid with respect to a
|
|
* certain criterion, such as manifoldness, self-intersections, etc.
|
|
* The passed mesh kernel can be modified to fix the errors.
|
|
* The class itself is abstract, hence the method Fixup() must be implemented
|
|
* by subclasses.
|
|
*/
|
|
class MeshExport MeshValidation
|
|
{
|
|
public:
|
|
MeshValidation (MeshKernel &rclB) : _rclMesh(rclB) {}
|
|
virtual ~MeshValidation () {}
|
|
|
|
/**
|
|
* This function attempts to change the mesh kernel to be valid according to the checked
|
|
* criterion: True is returned if the errors could be fixed, false otherwise.
|
|
*/
|
|
virtual bool Fixup() = 0;
|
|
|
|
protected:
|
|
MeshKernel& _rclMesh; /**< Mesh kernel */
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* This class searches for nonuniform orientation of neighboured facets.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshOrientationVisitor : public MeshFacetVisitor
|
|
{
|
|
public:
|
|
MeshOrientationVisitor();
|
|
|
|
/** Returns false after the first inconsistence is found, true otherwise. */
|
|
bool Visit (const MeshFacet &, const MeshFacet &, unsigned long , unsigned long );
|
|
bool HasNonUnifomOrientedFacets() const;
|
|
|
|
private:
|
|
bool _nonuniformOrientation;
|
|
};
|
|
|
|
/**
|
|
* This class searches for inconsistent orientation of neighboured facets.
|
|
* Note: The 'TMP0' flag for facets must be resetted before using this class.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshOrientationCollector : public MeshOrientationVisitor
|
|
{
|
|
public:
|
|
MeshOrientationCollector(std::vector<unsigned long>& aulIndices,
|
|
std::vector<unsigned long>& aulComplement);
|
|
|
|
/** Returns always true and collects the indices with wrong orientation. */
|
|
bool Visit (const MeshFacet &, const MeshFacet &, unsigned long , unsigned long);
|
|
|
|
private:
|
|
std::vector<unsigned long>& _aulIndices;
|
|
std::vector<unsigned long>& _aulComplement;
|
|
};
|
|
|
|
/**
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshSameOrientationCollector : public MeshOrientationVisitor
|
|
{
|
|
public:
|
|
MeshSameOrientationCollector(std::vector<unsigned long>& aulIndices);
|
|
/** Returns always true and collects the indices with wrong orientation. */
|
|
bool Visit (const MeshFacet &, const MeshFacet &, unsigned long , unsigned long);
|
|
|
|
private:
|
|
std::vector<unsigned long>& _aulIndices;
|
|
};
|
|
|
|
/**
|
|
* The MeshEvalOrientation class checks the mesh kernel for consistent facet normals.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshEvalOrientation : public MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEvalOrientation (const MeshKernel& rclM);
|
|
~MeshEvalOrientation();
|
|
bool Evaluate ();
|
|
std::vector<unsigned long> GetIndices() const;
|
|
|
|
private:
|
|
unsigned long HasFalsePositives(const std::vector<unsigned long>&) const;
|
|
};
|
|
|
|
/**
|
|
* The MeshFixOrientation class harmonizes the facet normals of the passed mesh kernel.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshFixOrientation : public MeshValidation
|
|
{
|
|
public:
|
|
MeshFixOrientation (MeshKernel& rclM);
|
|
~MeshFixOrientation();
|
|
bool Fixup();
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshEvalSolid class checks if the mesh represents a solid.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshEvalSolid : public MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEvalSolid (const MeshKernel& rclM);
|
|
~MeshEvalSolid();
|
|
bool Evaluate ();
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshEvalTopology class checks for topologic correctness, i.e
|
|
* that the mesh must not contain non-manifolds. E.g. an edge is regarded as
|
|
* non-manifold if it is shared by more than two facets.
|
|
* @note This check does not necessarily cover any degenerations.
|
|
*/
|
|
class MeshExport MeshEvalTopology : public MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEvalTopology (const MeshKernel &rclB) : MeshEvaluation(rclB) {}
|
|
virtual ~MeshEvalTopology () {}
|
|
virtual bool Evaluate ();
|
|
|
|
void GetFacetManifolds (std::vector<unsigned long> &raclFacetIndList) const;
|
|
unsigned long CountManifolds() const;
|
|
const std::vector<std::pair<unsigned long, unsigned long> >& GetIndices() const { return nonManifoldList; }
|
|
const std::list<std::vector<unsigned long> >& GetFacets() const { return nonManifoldFacets; }
|
|
|
|
protected:
|
|
std::vector<std::pair<unsigned long, unsigned long> > nonManifoldList;
|
|
std::list<std::vector<unsigned long> > nonManifoldFacets;
|
|
};
|
|
|
|
/**
|
|
* The MeshFixTopology class tries to fix a few cases of non-manifolds.
|
|
* @see MeshEvalTopology
|
|
*/
|
|
class MeshExport MeshFixTopology : public MeshValidation
|
|
{
|
|
public:
|
|
MeshFixTopology (MeshKernel &rclB, const std::list<std::vector<unsigned long> >& mf)
|
|
: MeshValidation(rclB), nonManifoldList(mf) {}
|
|
virtual ~MeshFixTopology () {}
|
|
bool Fixup();
|
|
|
|
protected:
|
|
const std::list<std::vector<unsigned long> >& nonManifoldList;
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshEvalSingleFacet class checks a special case of non-manifold edges as follows.
|
|
* If an edge is shared by more than two facets and if all further facets causing this non-
|
|
* manifold have only their neighbour facets set at this edge, i.e. they have no neighbours
|
|
* at their other edges.
|
|
* Such facets can just be removed from the mesh.
|
|
*/
|
|
class MeshExport MeshEvalSingleFacet : public MeshEvalTopology
|
|
{
|
|
public:
|
|
MeshEvalSingleFacet (const MeshKernel &rclB) : MeshEvalTopology(rclB) {}
|
|
virtual ~MeshEvalSingleFacet () {}
|
|
bool Evaluate ();
|
|
};
|
|
|
|
/**
|
|
* The MeshFixSingleFacet class tries to fix a special case of non-manifolds.
|
|
* @see MeshEvalSingleFacet
|
|
*/
|
|
class MeshExport MeshFixSingleFacet : public MeshValidation
|
|
{
|
|
public:
|
|
MeshFixSingleFacet (MeshKernel &rclB, const std::vector<std::list<unsigned long> >& mf)
|
|
: MeshValidation(rclB), _raclManifoldList(mf) {}
|
|
virtual ~MeshFixSingleFacet () {}
|
|
bool Fixup();
|
|
|
|
protected:
|
|
const std::vector<std::list<unsigned long> >& _raclManifoldList;
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshEvalSelfIntersection class checks the mesh for self intersection.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshEvalSelfIntersection : public MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEvalSelfIntersection (const MeshKernel &rclB) : MeshEvaluation(rclB) {}
|
|
virtual ~MeshEvalSelfIntersection () {}
|
|
/// Evaluate the mesh and return if true if there are self intersections
|
|
bool Evaluate ();
|
|
/// collect all intersection lines
|
|
void GetIntersections(const std::vector<std::pair<unsigned long, unsigned long> >&,
|
|
std::vector<std::pair<Base::Vector3f, Base::Vector3f> >&) const;
|
|
/// collect the index of all facets with self intersections
|
|
void GetIntersections(std::vector<std::pair<unsigned long, unsigned long> >&) const;
|
|
};
|
|
|
|
/**
|
|
* The MeshFixSelfIntersection class tries to fix self-intersections.
|
|
* @see MeshEvalSingleFacet
|
|
*/
|
|
class MeshExport MeshFixSelfIntersection : public MeshValidation
|
|
{
|
|
public:
|
|
MeshFixSelfIntersection (MeshKernel &rclB, const std::vector<std::pair<unsigned long, unsigned long> >& si)
|
|
: MeshValidation(rclB), selfIntersectons(si) {}
|
|
virtual ~MeshFixSelfIntersection () {}
|
|
bool Fixup();
|
|
|
|
private:
|
|
const std::vector<std::pair<unsigned long, unsigned long> >& selfIntersectons;
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshEvalNeighbourhood class checks if the neighbourhood among the facets is
|
|
* set correctly.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshEvalNeighbourhood : public MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEvalNeighbourhood (const MeshKernel &rclB) : MeshEvaluation(rclB) {}
|
|
~MeshEvalNeighbourhood () {}
|
|
bool Evaluate ();
|
|
std::vector<unsigned long> GetIndices() const;
|
|
};
|
|
|
|
/**
|
|
* The MeshFixNeighbourhood class fixes the neighbourhood of the facets.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshFixNeighbourhood : public MeshValidation
|
|
{
|
|
public:
|
|
MeshFixNeighbourhood (MeshKernel &rclB) : MeshValidation(rclB) {}
|
|
~MeshFixNeighbourhood () {}
|
|
bool Fixup();
|
|
};
|
|
|
|
// ----------------------------------------------------
|
|
|
|
/**
|
|
* The MeshEigensystem class actually does not try to check for or fix errors but
|
|
* it provides methods to calculate the mesh's local coordinate system with the center
|
|
* of gravity as origin.
|
|
* The local coordinate system is computed this way that u has minimum and w has maximum
|
|
* expansion. The local coordinate system is right-handed.
|
|
* @author Werner Mayer
|
|
*/
|
|
class MeshExport MeshEigensystem : public MeshEvaluation
|
|
{
|
|
public:
|
|
MeshEigensystem (const MeshKernel &rclB);
|
|
virtual ~MeshEigensystem () {}
|
|
|
|
/** Returns the transformation matrix. */
|
|
Base::Matrix4D Transform() const;
|
|
/**
|
|
* Returns the expansions in \a u, \a v and \a w of the bounding box.
|
|
*/
|
|
Base::Vector3f GetBoundings() const;
|
|
|
|
bool Evaluate();
|
|
/**
|
|
* Calculates the local coordinate system defined by \a u, \a v, \a w
|
|
* and \a c.
|
|
*/
|
|
protected:
|
|
void CalculateLocalSystem();
|
|
|
|
private:
|
|
Base::Vector3f _cU, _cV, _cW, _cC; /**< Vectors that define the local coordinate system. */
|
|
float _fU, _fV, _fW; /**< Expansion in \a u, \a v, and \a w direction of the transformed mesh. */
|
|
};
|
|
|
|
} // namespace MeshCore
|
|
|
|
#endif // MESH_EVALUATION_H
|