|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
|
|
| #ifndef MESH_ELEMENTS_H
|
| #define MESH_ELEMENTS_H
|
|
|
| #include <cstring>
|
| #include <functional>
|
| #include <limits>
|
| #include <vector>
|
|
|
| #include <Base/BoundBox.h>
|
| #include <Base/Matrix.h>
|
|
|
| #include "Definitions.h"
|
|
|
|
|
|
|
| #ifdef _MSC_VER
|
| using Base::Vector3f;
|
| #endif
|
|
|
| namespace MeshCore
|
| {
|
|
|
| class MeshHelpEdge;
|
| class MeshPoint;
|
|
|
| |
| |
| |
| |
|
|
| class MeshExport MeshHelpEdge
|
| {
|
| public:
|
| inline bool operator==(const MeshHelpEdge& rclEdge) const;
|
| PointIndex _ulIndex[2];
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshIndexEdge
|
| {
|
| public:
|
| FacetIndex _ulFacetIndex;
|
| unsigned short _ausCorner[2];
|
| };
|
|
|
|
|
| using MeshEdge = std::pair<PointIndex, PointIndex>;
|
|
|
| struct MeshExport EdgeCollapse
|
| {
|
| PointIndex _fromPoint;
|
| PointIndex _toPoint;
|
| std::vector<PointIndex> _adjacentFrom;
|
| std::vector<PointIndex> _adjacentTo;
|
| std::vector<FacetIndex> _removeFacets;
|
| std::vector<FacetIndex> _changeFacets;
|
| };
|
|
|
| struct MeshExport VertexCollapse
|
| {
|
| PointIndex _point;
|
| std::vector<PointIndex> _circumPoints;
|
| std::vector<FacetIndex> _circumFacets;
|
| };
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| class MeshExport MeshPoint: public Base::Vector3f
|
| {
|
| public:
|
| enum TFlagType
|
| {
|
| INVALID = 1,
|
| VISIT = 2,
|
| SEGMENT = 4,
|
| MARKED = 8,
|
| SELECTED = 16,
|
| REV = 32,
|
| TMP0 = 64,
|
| TMP1 = 128
|
| };
|
|
|
|
|
|
|
| MeshPoint()
|
| : _ucFlag(0)
|
| , _ulProp(0)
|
| {}
|
| inline MeshPoint(float x, float y, float z);
|
| inline MeshPoint(const Base::Vector3f& rclPt);
|
| inline MeshPoint(const MeshPoint& rclPt) = default;
|
| inline MeshPoint(MeshPoint&& rclPt) = default;
|
| ~MeshPoint() = default;
|
|
|
|
|
| public:
|
| |
| |
|
|
|
|
| void SetFlag(TFlagType tF) const
|
| {
|
| _ucFlag |= static_cast<unsigned char>(tF);
|
| }
|
| void ResetFlag(TFlagType tF) const
|
| {
|
| _ucFlag &= ~static_cast<unsigned char>(tF);
|
| }
|
| bool IsFlag(TFlagType tF) const
|
| {
|
| return (_ucFlag & static_cast<unsigned char>(tF)) == static_cast<unsigned char>(tF);
|
| }
|
| void ResetInvalid() const
|
| {
|
| ResetFlag(INVALID);
|
| }
|
| void SetInvalid() const
|
| {
|
| SetFlag(INVALID);
|
| }
|
| bool IsValid() const
|
| {
|
| return !IsFlag(INVALID);
|
| }
|
| void SetProperty(unsigned long uP) const
|
| {
|
| _ulProp = uP;
|
| }
|
|
|
|
|
|
|
| inline MeshPoint& operator=(const MeshPoint& rclPt) = default;
|
| inline MeshPoint& operator=(MeshPoint&& rclPt) = default;
|
|
|
|
|
| inline bool operator==(const MeshPoint& rclPt) const;
|
| inline bool operator==(const Base::Vector3f& rclV) const;
|
| inline bool operator<(const MeshPoint& rclPt) const;
|
|
|
| public:
|
| mutable unsigned char _ucFlag;
|
| mutable unsigned long _ulProp;
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshGeomEdge
|
| {
|
| public:
|
| MeshGeomEdge() = default;
|
|
|
|
|
| bool ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rclBB) const;
|
|
|
| Base::BoundBox3f GetBoundBox() const;
|
|
|
| bool IntersectBoundingBox(const Base::BoundBox3f& rclBB) const;
|
| |
| |
| |
|
|
| bool IntersectWithLine(
|
| const Base::Vector3f& rclPt,
|
| const Base::Vector3f& rclDir,
|
| Base::Vector3f& rclRes
|
| ) const;
|
| |
| |
|
|
| bool IntersectWithEdge(const MeshGeomEdge& edge, Base::Vector3f& res) const;
|
| |
| |
| |
|
|
| bool IntersectWithPlane(
|
| const Base::Vector3f& rclPt,
|
| const Base::Vector3f& rclDir,
|
| Base::Vector3f& rclRes
|
| ) const;
|
| |
| |
| |
|
|
| void ProjectPointToLine(const Base::Vector3f& rclPoint, Base::Vector3f& rclProj) const;
|
| |
| |
| |
| |
|
|
| void ClosestPointsToLine(
|
| const Base::Vector3f& linePt,
|
| const Base::Vector3f& lineDir,
|
| Base::Vector3f& rclPnt1,
|
| Base::Vector3f& rclPnt2
|
| ) const;
|
| |
| |
| |
| |
|
|
| bool IsPointOf(const Base::Vector3f& rclPoint, float fDistance) const;
|
| |
| |
|
|
| bool IsProjectionPointOf(const Base::Vector3f& point) const;
|
| |
| |
| |
|
|
| bool IsParallel(const MeshGeomEdge& edge) const;
|
| |
| |
| |
|
|
| bool IsCollinear(const MeshGeomEdge& edge) const;
|
|
|
| public:
|
| Base::Vector3f _aclPoints[2];
|
| bool _bBorder {false};
|
| };
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| class MeshFacet
|
| {
|
| public:
|
| enum TFlagType
|
| {
|
| INVALID = 1,
|
| VISIT = 2,
|
| SEGMENT = 4,
|
| MARKED = 8,
|
| SELECTED = 16,
|
| REV = 32,
|
| TMP0 = 64,
|
| TMP1 = 128
|
| };
|
|
|
| public:
|
|
|
|
|
| inline MeshFacet();
|
| inline MeshFacet(const MeshFacet& rclF) = default;
|
| inline MeshFacet(MeshFacet&& rclF) = default;
|
| inline MeshFacet(
|
| PointIndex p1,
|
| PointIndex p2,
|
| PointIndex p3,
|
| FacetIndex n1 = FACET_INDEX_MAX,
|
| FacetIndex n2 = FACET_INDEX_MAX,
|
| FacetIndex n3 = FACET_INDEX_MAX
|
| );
|
| ~MeshFacet() = default;
|
|
|
|
|
| |
| |
|
|
|
|
| void SetFlag(TFlagType tF) const
|
| {
|
| _ucFlag |= static_cast<unsigned char>(tF);
|
| }
|
| void ResetFlag(TFlagType tF) const
|
| {
|
| _ucFlag &= ~static_cast<unsigned char>(tF);
|
| }
|
| bool IsFlag(TFlagType tF) const
|
| {
|
| return (_ucFlag & static_cast<unsigned char>(tF)) == static_cast<unsigned char>(tF);
|
| }
|
| void ResetInvalid() const
|
| {
|
| ResetFlag(INVALID);
|
| }
|
| void SetProperty(unsigned long uP) const
|
| {
|
| _ulProp = uP;
|
| }
|
| |
| |
| |
| |
|
|
| void SetInvalid() const
|
| {
|
| SetFlag(INVALID);
|
| }
|
| bool IsValid() const
|
| {
|
| return !IsFlag(INVALID);
|
| }
|
|
|
|
|
|
|
| inline MeshFacet& operator=(const MeshFacet& rclF) = default;
|
| inline MeshFacet& operator=(MeshFacet&& rclF) = default;
|
| inline void SetVertices(PointIndex, PointIndex, PointIndex);
|
| inline void SetNeighbours(FacetIndex, FacetIndex, FacetIndex);
|
|
|
| |
| |
|
|
| inline void GetEdge(unsigned short usSide, MeshHelpEdge& rclEdge) const;
|
| |
| |
|
|
| inline std::pair<PointIndex, PointIndex> GetEdge(unsigned short usSide) const;
|
| |
| |
| |
|
|
| inline unsigned short Side(FacetIndex ulNIndex) const;
|
| |
| |
| |
|
|
| inline unsigned short Side(PointIndex ulP0, PointIndex P1) const;
|
| |
| |
| |
|
|
| inline unsigned short Side(const MeshFacet& rFace) const;
|
| |
| |
| |
|
|
| inline bool IsEqual(const MeshFacet& rcFace) const;
|
| |
| |
| |
| |
|
|
| inline void Transpose(PointIndex ulOrig, PointIndex ulNew);
|
| |
| |
|
|
| inline void Decrement(PointIndex ulIndex);
|
| |
| |
|
|
| inline bool HasPoint(PointIndex) const;
|
| |
| |
| |
| |
|
|
| inline void ReplaceNeighbour(FacetIndex ulOrig, FacetIndex ulNew);
|
| |
| |
|
|
| bool HasNeighbour(unsigned short usSide) const
|
| {
|
| return (_aulNeighbours[usSide] != FACET_INDEX_MAX);
|
| }
|
| |
| |
|
|
| bool IsNeighbour(FacetIndex index) const
|
| {
|
| return Side(index) < 3;
|
| }
|
|
|
| inline unsigned short CountOpenEdges() const;
|
|
|
| inline bool HasOpenEdge() const;
|
| |
| |
|
|
| inline bool HasSameOrientation(const MeshFacet&) const;
|
|
|
| inline bool IsDegenerated() const;
|
|
|
| void FlipNormal()
|
| {
|
| std::swap(_aulPoints[1], _aulPoints[2]);
|
| std::swap(_aulNeighbours[0], _aulNeighbours[2]);
|
| }
|
|
|
| public:
|
| mutable unsigned char _ucFlag;
|
| mutable unsigned long _ulProp;
|
| PointIndex _aulPoints[3];
|
| FacetIndex _aulNeighbours[3];
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshGeomFacet
|
| {
|
| public:
|
|
|
|
|
|
|
| MeshGeomFacet();
|
|
|
| MeshGeomFacet(const Base::Vector3f& v1, const Base::Vector3f& v2, const Base::Vector3f& v3);
|
| MeshGeomFacet(const MeshGeomFacet&) = default;
|
| MeshGeomFacet(MeshGeomFacet&&) = default;
|
|
|
| ~MeshGeomFacet() = default;
|
|
|
|
|
| MeshGeomFacet& operator=(const MeshGeomFacet&) = default;
|
| MeshGeomFacet& operator=(MeshGeomFacet&&) = default;
|
|
|
| public:
|
| |
| |
| |
| |
|
|
| bool IsPointOf(const Base::Vector3f& rclPoint, float fDistance) const;
|
| |
| |
| |
| |
|
|
| bool IsPointOf(const Base::Vector3f& P) const;
|
| |
| |
| |
|
|
| bool IsPointOfFace(const Base::Vector3f& rclP, float fDistance) const;
|
| |
| |
| |
| |
| |
| |
| |
|
|
| bool Weights(const Base::Vector3f& rclP, float& w0, float& w1, float& w2) const;
|
| |
| |
|
|
| inline float DistancePlaneToPoint(const Base::Vector3f& rclPoint) const;
|
| |
| |
|
|
| void ProjectPointToPlane(const Base::Vector3f& rclPoint, Base::Vector3f& rclProj) const;
|
| |
| |
|
|
| void ProjectFacetToPlane(MeshGeomFacet& rclFacet) const;
|
| |
| |
| |
|
|
| bool IsDegenerated(float epsilon) const;
|
| |
| |
| |
| |
|
|
| bool IsDeformed(float fCosOfMinAngle, float fCosOfMaxAngle) const;
|
| |
| |
|
|
| void Enlarge(float fDist);
|
| |
| |
|
|
| inline void CalcNormal() const;
|
| |
| |
|
|
| inline void ArrangeNormal(const Base::Vector3f& rclN);
|
| |
| |
|
|
| inline void AdjustCirculationDirection();
|
|
|
| void NormalInvalid()
|
| {
|
| _bNormalCalculated = false;
|
| }
|
|
|
| bool IsFlag(MeshFacet::TFlagType tF) const
|
| {
|
| return (_ucFlag & static_cast<unsigned char>(tF)) == static_cast<unsigned char>(tF);
|
| }
|
|
|
| void SetFlag(MeshFacet::TFlagType tF)
|
| {
|
| _ucFlag |= static_cast<unsigned char>(tF);
|
| }
|
|
|
| void ResetFlag(MeshFacet::TFlagType tF)
|
| {
|
| _ucFlag &= ~static_cast<unsigned char>(tF);
|
| }
|
|
|
| inline Base::Vector3f GetGravityPoint() const;
|
|
|
| inline Base::Vector3f GetNormal() const;
|
|
|
| inline void SetNormal(const Base::Vector3f& rclNormal);
|
|
|
| inline Base::BoundBox3f GetBoundBox() const;
|
|
|
| inline float Perimeter() const;
|
|
|
| inline float Area() const;
|
|
|
| float MaximumAngle() const;
|
|
|
| float MinimumAngle() const;
|
|
|
| inline bool ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rcBB) const;
|
|
|
| bool IntersectBoundingBox(const Base::BoundBox3f& rclBB) const;
|
| |
|
|
| bool IntersectWithFacet(const MeshGeomFacet& rclFacet) const;
|
| |
| |
| |
| |
| |
|
|
| int IntersectWithFacet(const MeshGeomFacet& facet, Base::Vector3f& rclPt0, Base::Vector3f& rclPt1) const;
|
| |
| |
|
|
| float DistanceToLineSegment(const Base::Vector3f& rcP1, const Base::Vector3f& rcP2) const;
|
|
|
| float DistanceToPoint(const Base::Vector3f& rcPt) const
|
| {
|
| Base::Vector3f res;
|
| return DistanceToPoint(rcPt, res);
|
| }
|
| |
| |
|
|
| float DistanceToPoint(const Base::Vector3f& rclPt, Base::Vector3f& rclNt) const;
|
| |
| |
| |
|
|
| bool IntersectWithLine(
|
| const Base::Vector3f& rclPt,
|
| const Base::Vector3f& rclDir,
|
| Base::Vector3f& rclRes
|
| ) const;
|
| |
| |
| |
| |
| |
|
|
| bool Foraminate(
|
| const Base::Vector3f& P,
|
| const Base::Vector3f& dir,
|
| Base::Vector3f& I,
|
| float fMaxAngle = Mathf::PI
|
| ) const;
|
| |
| |
|
|
| bool IntersectWithPlane(
|
| const Base::Vector3f& rclBase,
|
| const Base::Vector3f& rclNormal,
|
| Base::Vector3f& rclP1,
|
| Base::Vector3f& rclP2
|
| ) const;
|
| |
| |
| |
|
|
| inline bool IntersectWithPlane(const Base::Vector3f& rclBase, const Base::Vector3f& rclNormal) const;
|
| |
| |
| |
|
|
| bool IntersectPlaneWithLine(
|
| const Base::Vector3f& rclPt,
|
| const Base::Vector3f& rclDir,
|
| Base::Vector3f& rclRes
|
| ) const;
|
| |
| |
|
|
| float VolumeOfPrism(const MeshGeomFacet& rclF) const;
|
|
|
| void SubSample(float fStep, std::vector<Base::Vector3f>& rclPoints) const;
|
|
|
| float CenterOfInscribedCircle(Base::Vector3f& rclCenter) const;
|
|
|
| float CenterOfCircumCircle(Base::Vector3f& rclCenter) const;
|
|
|
| unsigned short NearestEdgeToPoint(const Base::Vector3f& rclPt) const;
|
| |
|
|
| void NearestEdgeToPoint(const Base::Vector3f& rclPt, float& fDistance, unsigned short& side) const;
|
|
|
| MeshGeomEdge GetEdge(short side) const;
|
| |
| |
|
|
| bool IsPointOfSphere(const Base::Vector3f& rP) const;
|
| |
| |
| |
|
|
| bool IsPointOfSphere(const MeshGeomFacet& rFacet) const;
|
| |
|
|
| float AspectRatio() const;
|
| |
| |
|
|
| float AspectRatio2() const;
|
| |
|
|
| float Roundness() const;
|
| |
|
|
| void Transform(const Base::Matrix4D&);
|
| |
| |
|
|
| bool IsCoplanar(const MeshGeomFacet& facet) const;
|
|
|
| private:
|
| mutable Base::Vector3f _clNormal;
|
| mutable bool _bNormalCalculated;
|
|
|
| public:
|
|
|
| Base::Vector3f _aclPoints[3];
|
| unsigned char _ucFlag;
|
| unsigned long _ulProp;
|
|
|
| };
|
|
|
| using TMeshPointArray = std::vector<MeshPoint>;
|
| |
| |
|
|
| class MeshExport MeshPointArray: public TMeshPointArray
|
| {
|
| public:
|
|
|
| using _TIterator = std::vector<MeshPoint>::iterator;
|
| using _TConstIterator = std::vector<MeshPoint>::const_iterator;
|
|
|
|
|
|
|
|
|
| MeshPointArray() = default;
|
|
|
| explicit MeshPointArray(PointIndex ulSize)
|
| : TMeshPointArray(ulSize)
|
| {}
|
|
|
| MeshPointArray(const MeshPointArray&);
|
| MeshPointArray(MeshPointArray&&);
|
|
|
| ~MeshPointArray() = default;
|
|
|
|
|
| |
| |
|
|
|
|
|
|
| void SetFlag(MeshPoint::TFlagType tF) const;
|
|
|
| void ResetFlag(MeshPoint::TFlagType tF) const;
|
|
|
| void ResetInvalid() const;
|
|
|
| void SetProperty(unsigned long ulVal) const;
|
|
|
|
|
|
|
| MeshPointArray& operator=(const MeshPointArray& rclPAry);
|
| MeshPointArray& operator=(MeshPointArray&& rclPAry);
|
| void Transform(const Base::Matrix4D&);
|
| |
| |
| |
|
|
| PointIndex Get(const MeshPoint& rclPoint);
|
| |
| |
| |
| |
|
|
| PointIndex GetOrAddIndex(const MeshPoint& rclPoint);
|
| };
|
|
|
| using TMeshFacetArray = std::vector<MeshFacet>;
|
|
|
| |
| |
|
|
| class MeshExport MeshFacetArray: public TMeshFacetArray
|
| {
|
| public:
|
|
|
| using _TIterator = std::vector<MeshFacet>::iterator;
|
| using _TConstIterator = std::vector<MeshFacet>::const_iterator;
|
|
|
|
|
|
|
|
|
| MeshFacetArray() = default;
|
|
|
| explicit MeshFacetArray(FacetIndex ulSize)
|
| : TMeshFacetArray(ulSize)
|
| {}
|
|
|
| MeshFacetArray(const MeshFacetArray&);
|
| MeshFacetArray(MeshFacetArray&&);
|
|
|
| ~MeshFacetArray() = default;
|
|
|
|
|
| |
| |
| |
|
|
|
|
|
|
| void SetFlag(MeshFacet::TFlagType tF) const;
|
|
|
| void ResetFlag(MeshFacet::TFlagType tF) const;
|
|
|
| void ResetInvalid() const;
|
|
|
| void SetProperty(unsigned long ulVal) const;
|
|
|
|
|
|
|
| MeshFacetArray& operator=(const MeshFacetArray& rclFAry);
|
| MeshFacetArray& operator=(MeshFacetArray&& rclFAry);
|
|
|
| |
| |
| |
|
|
| void Erase(_TIterator pIter);
|
| |
| |
|
|
| void TransposeIndices(PointIndex ulOrig, PointIndex ulNew);
|
| |
| |
|
|
| void DecrementIndices(PointIndex ulIndex);
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshPointModifier
|
| {
|
| public:
|
| explicit MeshPointModifier(MeshPointArray& points)
|
| : rPoints(points)
|
| {}
|
| ~MeshPointModifier() = default;
|
|
|
| MeshPointArray& GetPoints() const
|
| {
|
| return rPoints;
|
| }
|
|
|
| MeshPointModifier(const MeshPointModifier& c) = default;
|
| MeshPointModifier(MeshPointModifier&& c) = default;
|
|
|
| MeshPointModifier& operator=(const MeshPointModifier& c) = delete;
|
| MeshPointModifier& operator=(MeshPointModifier&& c) = delete;
|
|
|
| private:
|
| MeshPointArray& rPoints;
|
| };
|
|
|
| |
| |
| |
|
|
| class MeshExport MeshFacetModifier
|
| {
|
| public:
|
| explicit MeshFacetModifier(MeshFacetArray& facets)
|
| : rFacets(facets)
|
| {}
|
| ~MeshFacetModifier() = default;
|
|
|
| MeshFacetModifier(const MeshFacetModifier& c) = default;
|
| MeshFacetModifier(MeshFacetModifier&& c) = default;
|
| MeshFacetModifier& operator=(const MeshFacetModifier& c) = delete;
|
| MeshFacetModifier& operator=(MeshFacetModifier&& c) = delete;
|
|
|
| |
| |
| |
| |
|
|
| void Transpose(PointIndex pos, PointIndex old, PointIndex now)
|
| {
|
| rFacets[pos].Transpose(old, now);
|
| }
|
|
|
| private:
|
| MeshFacetArray& rFacets;
|
| };
|
|
|
| inline MeshPoint::MeshPoint(float x, float y, float z)
|
| : Base::Vector3f(x, y, z)
|
| , _ucFlag(0)
|
| , _ulProp(0)
|
| {}
|
|
|
| inline MeshPoint::MeshPoint(const Base::Vector3f& rclPt)
|
| : Base::Vector3f(rclPt)
|
| , _ucFlag(0)
|
| , _ulProp(0)
|
| {}
|
|
|
| inline bool MeshPoint::operator==(const MeshPoint& rclPt) const
|
| {
|
| return Base::DistanceP2(*this, rclPt) < MeshDefinitions::_fMinPointDistanceP2;
|
| }
|
|
|
| inline bool MeshPoint::operator==(const Base::Vector3f& rclV) const
|
| {
|
| return Base::DistanceP2(*this, rclV) < MeshDefinitions::_fMinPointDistanceP2;
|
| }
|
|
|
| inline bool MeshPoint::operator<(const MeshPoint& rclPt) const
|
| {
|
| if (std::fabs(this->x - rclPt.x) >= MeshDefinitions::_fMinPointDistanceD1) {
|
| return this->x < rclPt.x;
|
| }
|
| if (std::fabs(this->y - rclPt.y) >= MeshDefinitions::_fMinPointDistanceD1) {
|
| return this->y < rclPt.y;
|
| }
|
| if (std::fabs(this->z - rclPt.z) >= MeshDefinitions::_fMinPointDistanceD1) {
|
| return this->z < rclPt.z;
|
| }
|
| return false;
|
| }
|
|
|
| inline float MeshGeomFacet::DistancePlaneToPoint(const Base::Vector3f& rclPoint) const
|
| {
|
|
|
| return float(fabs(rclPoint.DistanceToPlane(_aclPoints[0], GetNormal())));
|
| }
|
|
|
| inline void MeshGeomFacet::CalcNormal() const
|
| {
|
| _clNormal = (_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0]);
|
| _clNormal.Normalize();
|
| _bNormalCalculated = true;
|
| }
|
|
|
| inline Base::Vector3f MeshGeomFacet::GetNormal() const
|
| {
|
| if (!_bNormalCalculated) {
|
| CalcNormal();
|
| }
|
| return _clNormal;
|
| }
|
|
|
| inline void MeshGeomFacet::SetNormal(const Base::Vector3f& rclNormal)
|
| {
|
| if (rclNormal.Sqr() == 0.0F) {
|
| return;
|
| }
|
| _clNormal = rclNormal;
|
| _clNormal.Normalize();
|
| _bNormalCalculated = true;
|
| }
|
|
|
| inline void MeshGeomFacet::ArrangeNormal(const Base::Vector3f& rclN)
|
| {
|
|
|
| if ((rclN * GetNormal()) < 0.0F) {
|
| _clNormal = -_clNormal;
|
| }
|
| }
|
|
|
| inline Base::Vector3f MeshGeomFacet::GetGravityPoint() const
|
| {
|
| return (1.0F / 3.0F) * (_aclPoints[0] + _aclPoints[1] + _aclPoints[2]);
|
| }
|
|
|
| inline void MeshGeomFacet::AdjustCirculationDirection()
|
| {
|
| Base::Vector3f clN = (_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0]);
|
| if ((clN * _clNormal) < 0.0F) {
|
| std::swap(_aclPoints[1], _aclPoints[2]);
|
| }
|
| }
|
|
|
| inline Base::BoundBox3f MeshGeomFacet::GetBoundBox() const
|
| {
|
| return {_aclPoints, 3};
|
| }
|
|
|
| inline float MeshGeomFacet::Perimeter() const
|
| {
|
| float perimeter = 0.0F;
|
| perimeter += Base::Distance(_aclPoints[0], _aclPoints[1]);
|
| perimeter += Base::Distance(_aclPoints[1], _aclPoints[2]);
|
| perimeter += Base::Distance(_aclPoints[2], _aclPoints[0]);
|
| return perimeter;
|
| }
|
|
|
| inline float MeshGeomFacet::Area() const
|
| {
|
| return ((_aclPoints[1] - _aclPoints[0]) % (_aclPoints[2] - _aclPoints[0])).Length() / 2.0F;
|
| }
|
|
|
| inline bool MeshGeomFacet::ContainedByOrIntersectBoundingBox(const Base::BoundBox3f& rclBB) const
|
| {
|
|
|
| if (!(GetBoundBox() && rclBB)) {
|
| return false;
|
| }
|
|
|
|
|
| if (rclBB.IsInBox(GetBoundBox())) {
|
| return true;
|
| }
|
|
|
|
|
| for (auto pnt : _aclPoints) {
|
| if (rclBB.IsInBox(pnt)) {
|
| return true;
|
| }
|
| }
|
|
|
|
|
| return (IntersectBoundingBox(rclBB));
|
| }
|
|
|
| inline bool MeshGeomFacet::IntersectWithPlane(
|
| const Base::Vector3f& rclBase,
|
| const Base::Vector3f& rclNormal
|
| ) const
|
| {
|
| bool bD0 = (_aclPoints[0].DistanceToPlane(rclBase, rclNormal) > 0.0F);
|
| return !(
|
| (bD0 == (_aclPoints[1].DistanceToPlane(rclBase, rclNormal) > 0.0F))
|
| && (bD0 == (_aclPoints[2].DistanceToPlane(rclBase, rclNormal) > 0.0F))
|
| );
|
| }
|
|
|
| inline MeshFacet::MeshFacet()
|
| : _ucFlag(0)
|
| , _ulProp(0)
|
| {
|
| memset(_aulNeighbours, 0xff, sizeof(FacetIndex) * 3);
|
| memset(_aulPoints, 0xff, sizeof(PointIndex) * 3);
|
| }
|
|
|
| inline MeshFacet::MeshFacet(
|
| PointIndex p1,
|
| PointIndex p2,
|
| PointIndex p3,
|
| FacetIndex n1,
|
| FacetIndex n2,
|
| FacetIndex n3
|
| )
|
| : _ucFlag(0)
|
| , _ulProp(0)
|
| , _aulPoints {p1, p2, p3}
|
| , _aulNeighbours {n1, n2, n3}
|
| {}
|
|
|
| void MeshFacet::SetVertices(PointIndex p1, PointIndex p2, PointIndex p3)
|
| {
|
| _aulPoints[0] = p1;
|
| _aulPoints[1] = p2;
|
| _aulPoints[2] = p3;
|
| }
|
|
|
| void MeshFacet::SetNeighbours(FacetIndex n1, FacetIndex n2, FacetIndex n3)
|
| {
|
| _aulNeighbours[0] = n1;
|
| _aulNeighbours[1] = n2;
|
| _aulNeighbours[2] = n3;
|
| }
|
|
|
| inline void MeshFacet::GetEdge(unsigned short usSide, MeshHelpEdge& rclEdge) const
|
| {
|
| rclEdge._ulIndex[0] = _aulPoints[usSide];
|
| rclEdge._ulIndex[1] = _aulPoints[(usSide + 1) % 3];
|
| }
|
|
|
| inline std::pair<PointIndex, PointIndex> MeshFacet::GetEdge(unsigned short usSide) const
|
| {
|
| return {_aulPoints[usSide], _aulPoints[(usSide + 1) % 3]};
|
| }
|
|
|
| inline void MeshFacet::Transpose(PointIndex ulOrig, PointIndex ulNew)
|
| {
|
| if (_aulPoints[0] == ulOrig) {
|
| _aulPoints[0] = ulNew;
|
| }
|
| else if (_aulPoints[1] == ulOrig) {
|
| _aulPoints[1] = ulNew;
|
| }
|
| else if (_aulPoints[2] == ulOrig) {
|
| _aulPoints[2] = ulNew;
|
| }
|
| }
|
|
|
| inline void MeshFacet::Decrement(PointIndex ulIndex)
|
| {
|
| if (_aulPoints[0] > ulIndex) {
|
| _aulPoints[0]--;
|
| }
|
| if (_aulPoints[1] > ulIndex) {
|
| _aulPoints[1]--;
|
| }
|
| if (_aulPoints[2] > ulIndex) {
|
| _aulPoints[2]--;
|
| }
|
| }
|
|
|
| inline bool MeshFacet::HasPoint(PointIndex ulIndex) const
|
| {
|
| if (_aulPoints[0] == ulIndex) {
|
| return true;
|
| }
|
| if (_aulPoints[1] == ulIndex) {
|
| return true;
|
| }
|
| if (_aulPoints[2] == ulIndex) {
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| inline void MeshFacet::ReplaceNeighbour(FacetIndex ulOrig, FacetIndex ulNew)
|
| {
|
| if (_aulNeighbours[0] == ulOrig) {
|
| _aulNeighbours[0] = ulNew;
|
| }
|
| else if (_aulNeighbours[1] == ulOrig) {
|
| _aulNeighbours[1] = ulNew;
|
| }
|
| else if (_aulNeighbours[2] == ulOrig) {
|
| _aulNeighbours[2] = ulNew;
|
| }
|
| }
|
|
|
| inline unsigned short MeshFacet::CountOpenEdges() const
|
| {
|
| unsigned short ct = 0;
|
| for (unsigned short i = 0; i < 3; i++) {
|
| if (!HasNeighbour(i)) {
|
| ct++;
|
| }
|
| }
|
| return ct;
|
| }
|
|
|
| inline bool MeshFacet::HasOpenEdge() const
|
| {
|
| return (CountOpenEdges() != 0);
|
| }
|
|
|
| inline bool MeshFacet::HasSameOrientation(const MeshFacet& f) const
|
| {
|
| for (int i = 0; i < 3; i++) {
|
| for (int j = 0; j < 3; j++) {
|
| if (_aulPoints[i] == f._aulPoints[j]) {
|
| if ((_aulPoints[(i + 1) % 3] == f._aulPoints[(j + 1) % 3])
|
| || (_aulPoints[(i + 2) % 3] == f._aulPoints[(j + 2) % 3])) {
|
| return false;
|
| }
|
| }
|
| }
|
| }
|
|
|
| return true;
|
| }
|
|
|
| inline bool MeshFacet::IsDegenerated() const
|
| {
|
| if (_aulPoints[0] == _aulPoints[1]) {
|
| return true;
|
| }
|
| if (_aulPoints[1] == _aulPoints[2]) {
|
| return true;
|
| }
|
| if (_aulPoints[2] == _aulPoints[0]) {
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| inline unsigned short MeshFacet::Side(FacetIndex ulNIndex) const
|
| {
|
| if (_aulNeighbours[0] == ulNIndex) {
|
| return 0;
|
| }
|
| if (_aulNeighbours[1] == ulNIndex) {
|
| return 1;
|
| }
|
| if (_aulNeighbours[2] == ulNIndex) {
|
| return 2;
|
| }
|
|
|
| return std::numeric_limits<unsigned short>::max();
|
| }
|
|
|
| inline unsigned short MeshFacet::Side(PointIndex ulP0, PointIndex ulP1) const
|
| {
|
| if (_aulPoints[0] == ulP0) {
|
| if (_aulPoints[1] == ulP1) {
|
| return 0;
|
| }
|
| if (_aulPoints[2] == ulP1) {
|
| return 2;
|
| }
|
| }
|
| else if (_aulPoints[1] == ulP0) {
|
| if (_aulPoints[0] == ulP1) {
|
| return 0;
|
| }
|
| if (_aulPoints[2] == ulP1) {
|
| return 1;
|
| }
|
| }
|
| else if (_aulPoints[2] == ulP0) {
|
| if (_aulPoints[0] == ulP1) {
|
| return 2;
|
| }
|
| if (_aulPoints[1] == ulP1) {
|
| return 1;
|
| }
|
| }
|
|
|
| return std::numeric_limits<unsigned short>::max();
|
| }
|
|
|
| inline unsigned short MeshFacet::Side(const MeshFacet& rFace) const
|
| {
|
| unsigned short side {};
|
| for (int i = 0; i < 3; i++) {
|
| side = Side(rFace._aulPoints[i], rFace._aulPoints[(i + 1) % 3]);
|
| if (side != std::numeric_limits<unsigned short>::max()) {
|
| return side;
|
| }
|
| }
|
|
|
| return std::numeric_limits<unsigned short>::max();
|
| }
|
|
|
| inline bool MeshFacet::IsEqual(const MeshFacet& rcFace) const
|
| {
|
| for (int i = 0; i < 3; i++) {
|
| if (this->_aulPoints[0] == rcFace._aulPoints[i]) {
|
| if (this->_aulPoints[1] == rcFace._aulPoints[(i + 1) % 3]
|
| && this->_aulPoints[2] == rcFace._aulPoints[(i + 2) % 3]) {
|
| return true;
|
| }
|
| if (this->_aulPoints[1] == rcFace._aulPoints[(i + 2) % 3]
|
| && this->_aulPoints[2] == rcFace._aulPoints[(i + 1) % 3]) {
|
| return true;
|
| }
|
| }
|
| }
|
|
|
| return false;
|
| }
|
|
|
| |
| |
|
|
| template<class TCLASS>
|
| class MeshIsFlag
|
| {
|
| public:
|
| using first_argument_type = TCLASS;
|
| using second_argument_type = typename TCLASS::TFlagType;
|
| using result_type = bool;
|
| bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
|
| {
|
| return rclElem.IsFlag(tFlag);
|
| }
|
| };
|
|
|
| |
| |
|
|
| template<class TCLASS>
|
| class MeshIsNotFlag
|
| {
|
| public:
|
| using first_argument_type = TCLASS;
|
| using second_argument_type = typename TCLASS::TFlagType;
|
| using result_type = bool;
|
| bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
|
| {
|
| return !rclElem.IsFlag(tFlag);
|
| }
|
| };
|
|
|
| |
| |
|
|
| template<class TCLASS>
|
| class MeshSetFlag
|
| {
|
| public:
|
| using first_argument_type = TCLASS;
|
| using second_argument_type = typename TCLASS::TFlagType;
|
| using result_type = bool;
|
| bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
|
| {
|
| rclElem.SetFlag(tFlag);
|
| return true;
|
| }
|
| };
|
|
|
| |
| |
|
|
| template<class TCLASS>
|
| class MeshResetFlag
|
| {
|
| public:
|
| using first_argument_type = TCLASS;
|
| using second_argument_type = typename TCLASS::TFlagType;
|
| using result_type = bool;
|
| bool operator()(const TCLASS& rclElem, typename TCLASS::TFlagType tFlag) const
|
| {
|
| rclElem.ResetFlag(tFlag);
|
| return true;
|
| }
|
| };
|
|
|
| }
|
|
|
| #endif
|
|
|