| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | #ifndef MESH_TOOLS_H
|
| | #define MESH_TOOLS_H
|
| |
|
| | #include <functional>
|
| | #include <limits>
|
| |
|
| | #include <Mod/Mesh/App/WildMagic4/Wm4DistVector3Triangle3.h>
|
| | #include <Mod/Mesh/App/WildMagic4/Wm4Sphere3.h>
|
| |
|
| | #include "Algorithm.h"
|
| | #include "Iterator.h"
|
| | #include "MeshKernel.h"
|
| |
|
| |
|
| | namespace MeshCore
|
| | {
|
| |
|
| | |
| | |
| | |
| |
|
| | class MeshSearchNeighbours
|
| | {
|
| | public:
|
| | explicit MeshSearchNeighbours(const MeshKernel& rclM, float fSampleDistance = 1.0F);
|
| | ~MeshSearchNeighbours() = default;
|
| |
|
| | void Reinit(float fSampleDistance);
|
| | |
| | |
| | |
| |
|
| | unsigned long NeighboursFromFacet(
|
| | FacetIndex ulFacetIdx,
|
| | float fDistance,
|
| | unsigned long ulMinPoints,
|
| | std::vector<Base::Vector3f>& raclResultPoints
|
| | );
|
| | |
| |
|
| | unsigned long NeighboursFromSampledFacets(
|
| | FacetIndex ulFacetIdx,
|
| | float fDistance,
|
| | std::vector<Base::Vector3f>& raclResultPoints
|
| | );
|
| |
|
| | unsigned long NeighboursFacetFromFacet(
|
| | FacetIndex ulFacetIdx,
|
| | float fDistance,
|
| | std::vector<Base::Vector3f>& raclResultPoints,
|
| | std::vector<FacetIndex>& raclResultFacets
|
| | );
|
| |
|
| | protected:
|
| |
|
| | void SampleAllFacets();
|
| | inline bool CheckDistToFacet(const MeshFacet& rclF);
|
| |
|
| | bool AccumulateNeighbours(
|
| | const MeshFacet& rclF,
|
| | FacetIndex ulFIdx
|
| | );
|
| | inline bool InnerPoint(const Base::Vector3f& rclPt) const;
|
| | inline bool TriangleCutsSphere(const MeshFacet& rclF) const;
|
| | bool ExpandRadius(unsigned long ulMinPoints);
|
| |
|
| | struct CDistRad
|
| | {
|
| | explicit CDistRad(const Base::Vector3f clCenter)
|
| | : _clCenter(clCenter)
|
| | {}
|
| | bool operator()(const Base::Vector3f& rclPt1, const Base::Vector3f& rclPt2)
|
| | {
|
| | return Base::DistanceP2(_clCenter, rclPt1) < Base::DistanceP2(_clCenter, rclPt2);
|
| | }
|
| | Base::Vector3f _clCenter;
|
| | };
|
| |
|
| | private:
|
| | const MeshKernel& _rclMesh;
|
| | const MeshFacetArray& _rclFAry;
|
| | const MeshPointArray& _rclPAry;
|
| | MeshRefPointToFacets _clPt2Fa;
|
| | float _fMaxDistanceP2 {0};
|
| | Base::Vector3f _clCenter;
|
| | std::set<PointIndex> _aclResult;
|
| | std::set<PointIndex> _aclOuter;
|
| | std::vector<Base::Vector3f> _aclPointsResult;
|
| | std::vector<std::vector<Base::Vector3f>> _aclSampledFacets;
|
| | float _fSampleDistance;
|
| | Wm4::Sphere3<float> _akSphere;
|
| |
|
| | public:
|
| | MeshSearchNeighbours(const MeshSearchNeighbours&) = delete;
|
| | MeshSearchNeighbours(MeshSearchNeighbours&&) = delete;
|
| | void operator=(const MeshSearchNeighbours&) = delete;
|
| | void operator=(MeshSearchNeighbours&&) = delete;
|
| | };
|
| |
|
| | inline bool MeshSearchNeighbours::CheckDistToFacet(const MeshFacet& rclF)
|
| | {
|
| | bool bFound = false;
|
| |
|
| | for (PointIndex ulPIdx : rclF._aulPoints) {
|
| | if (!_rclPAry[ulPIdx].IsFlag(MeshPoint::MARKED)) {
|
| | if (Base::DistanceP2(_clCenter, _rclPAry[ulPIdx]) < _fMaxDistanceP2) {
|
| | bFound = true;
|
| | {
|
| | _aclResult.insert(ulPIdx);
|
| | _rclPAry[ulPIdx].SetFlag(MeshPoint::MARKED);
|
| | }
|
| | }
|
| | _aclOuter.insert(ulPIdx);
|
| | }
|
| | }
|
| |
|
| | return bFound;
|
| | }
|
| |
|
| | inline bool MeshSearchNeighbours::InnerPoint(const Base::Vector3f& rclPt) const
|
| | {
|
| | return Base::DistanceP2(_clCenter, rclPt) < _fMaxDistanceP2;
|
| | }
|
| |
|
| | inline bool MeshSearchNeighbours::TriangleCutsSphere(const MeshFacet& rclF) const
|
| | {
|
| | Base::Vector3f cP0 = _rclPAry[rclF._aulPoints[0]];
|
| | Base::Vector3f cP1 = _rclPAry[rclF._aulPoints[1]];
|
| | Base::Vector3f cP2 = _rclPAry[rclF._aulPoints[2]];
|
| |
|
| | Wm4::Vector3<float> akP0(cP0.x, cP0.y, cP0.z);
|
| | Wm4::Vector3<float> akP1(cP1.x, cP1.y, cP1.z);
|
| | Wm4::Vector3<float> akP2(cP2.x, cP2.y, cP2.z);
|
| |
|
| | Wm4::Triangle3<float> akTri(akP0, akP1, akP2);
|
| | Wm4::DistVector3Triangle3<float> akDistVecTri(_akSphere.Center, akTri);
|
| |
|
| | float fSqrDist = akDistVecTri.GetSquared();
|
| | float fRSqr = _akSphere.Radius * _akSphere.Radius;
|
| | return fSqrDist < fRSqr;
|
| | }
|
| |
|
| | class MeshFaceIterator
|
| | {
|
| | public:
|
| | explicit MeshFaceIterator(const MeshKernel& mesh)
|
| | : it(mesh)
|
| | {}
|
| | Base::Vector3f operator()(FacetIndex index)
|
| | {
|
| | it.Set(index);
|
| | return it->GetGravityPoint();
|
| | }
|
| |
|
| | private:
|
| | MeshFacetIterator it;
|
| | };
|
| |
|
| | class MeshVertexIterator
|
| | {
|
| | public:
|
| | explicit MeshVertexIterator(const MeshKernel& mesh)
|
| | : it(mesh)
|
| | {}
|
| | Base::Vector3f operator()(PointIndex index)
|
| | {
|
| | it.Set(index);
|
| | return Base::Vector3f(it->x, it->y, it->z);
|
| | }
|
| |
|
| | private:
|
| | MeshPointIterator it;
|
| | };
|
| |
|
| | template<class T>
|
| | class MeshNearestIndexToPlane
|
| | {
|
| | public:
|
| | using Index = typename T::Index;
|
| | MeshNearestIndexToPlane(const MeshKernel& mesh, const Base::Vector3f& b, const Base::Vector3f& n)
|
| | : nearest_index(-1)
|
| | , it(mesh)
|
| | , base(b)
|
| | , normal(n)
|
| | {}
|
| | void operator()(Index index)
|
| | {
|
| | float dist = (float)fabs(it(index).DistanceToPlane(base, normal));
|
| | if (dist < nearest_dist) {
|
| | nearest_dist = dist;
|
| | nearest_index = index;
|
| | }
|
| | }
|
| |
|
| |
|
| | Index nearest_index;
|
| | float nearest_dist {std::numeric_limits<float>::max()};
|
| |
|
| |
|
| | private:
|
| | T it;
|
| | Base::Vector3f base, normal;
|
| | };
|
| |
|
| | }
|
| |
|
| |
|
| | #endif
|
| |
|