+ implement modifier class to allow limited access to internals of mesh kernel class

This commit is contained in:
wmayer 2016-07-30 15:31:45 +02:00
parent 1e2e24b652
commit 51171fd932
6 changed files with 168 additions and 83 deletions

View File

@ -43,29 +43,26 @@ using Base::BoundBox2D;
using Base::Polygon2D;
bool MeshAlgorithm::IsVertexVisible (const Base::Vector3f &rcVertex, const Base::Vector3f &rcView, const MeshFacetGrid &rclGrid ) const
bool MeshAlgorithm::IsVertexVisible (const Base::Vector3f &rcVertex, const Base::Vector3f &rcView, const MeshFacetGrid &rclGrid) const
{
Base::Vector3f cDirection = rcVertex-rcView;
float fDistance = cDirection.Length();
Base::Vector3f cIntsct; unsigned long uInd;
Base::Vector3f cDirection = rcVertex - rcView;
float fDistance = cDirection.Length();
Base::Vector3f cIntsct; unsigned long uInd;
// search for the nearest facet to rcView in direction to rcVertex
if ( NearestFacetOnRay( rcView, cDirection, /*1.2f*fDistance,*/ rclGrid, cIntsct, uInd) )
{
// now check if the facet overlays the point
float fLen = Base::Distance( rcView, cIntsct );
if ( fLen < fDistance )
{
// is it the same point?
if ( Base::Distance(rcVertex, cIntsct) > 0.001f )
{
// ok facet overlays the vertex
return false;
}
// search for the nearest facet to rcView in direction to rcVertex
if (NearestFacetOnRay(rcView, cDirection, /*1.2f*fDistance,*/ rclGrid, cIntsct, uInd)) {
// now check if the facet overlays the point
float fLen = Base::Distance(rcView, cIntsct);
if (fLen < fDistance) {
// is it the same point?
if (Base::Distance(rcVertex, cIntsct) > 0.001f) {
// ok facet overlays the vertex
return false;
}
}
}
}
return true; // no facet between the two points
return true; // no facet between the two points
}
bool MeshAlgorithm::NearestFacetOnRay (const Base::Vector3f &rclPt, const Base::Vector3f &rclDir, Base::Vector3f &rclRes,
@ -226,10 +223,10 @@ bool MeshAlgorithm::FirstFacetToVertex(const Base::Vector3f &rPt, float fMaxDist
}
else {
// if not then check the distance to the border of the triangle
Base::Vector3f res = rPt;
Base::Vector3f res;
float fDist;
unsigned short uSide;
cFacet.ProjectPointToPlane(res);
cFacet.ProjectPointToPlane(rPt, res);
cFacet.NearestEdgeToPoint(res, fDist, uSide);
if (fDist < fEps) {
found = true;

View File

@ -516,8 +516,8 @@ unsigned long MeshFixDegeneratedFacets::RemoveEdgeTooSmall (float fMinEdgeLength
{
unsigned long ulCtLastLoop, ulCtFacets = _rclMesh.CountFacets();
MeshFacetArray &rclFAry = _rclMesh._aclFacetArray;
MeshPointArray &rclPAry = _rclMesh._aclPointArray;
const MeshFacetArray &rclFAry = _rclMesh.GetFacets();
const MeshPointArray &rclPAry = _rclMesh.GetPoints();
MeshFacetArray::_TConstIterator f_beg = rclFAry.begin();
// repeat until no facet van be removed
@ -891,11 +891,11 @@ bool MeshEvalFoldOversOnSurface::Evaluate()
return this->indices.empty();
}
// ----------------------------------------------------------------
bool MeshEvalBorderFacet::Evaluate()
{
// ----------------------------------------------------------------
bool MeshEvalBorderFacet::Evaluate()
{
const MeshCore::MeshFacetArray& facets = _rclMesh.GetFacets();
MeshCore::MeshFacetArray::_TConstIterator f_it,
f_beg = facets.begin(), f_end = facets.end();
@ -915,87 +915,107 @@ bool MeshEvalBorderFacet::Evaluate()
if (ok)
_facets.push_back(f_it-f_beg);
}
return _facets.empty();
}
return _facets.empty();
}
// ----------------------------------------------------------------------
bool MeshEvalRangeFacet::Evaluate()
{
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtFacets = rFaces.size();
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtFacets = rFaces.size();
for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) {
for ( int i = 0; i < 3; i++ ) {
if ((it->_aulNeighbours[i] >= ulCtFacets) && (it->_aulNeighbours[i] < ULONG_MAX)) {
return false;
}
for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) {
for (int i = 0; i < 3; i++) {
if ((it->_aulNeighbours[i] >= ulCtFacets) && (it->_aulNeighbours[i] < ULONG_MAX)) {
return false;
}
}
}
}
return true;
return true;
}
std::vector<unsigned long> MeshEvalRangeFacet::GetIndices() const
{
std::vector<unsigned long> aInds;
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtFacets = rFaces.size();
std::vector<unsigned long> aInds;
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtFacets = rFaces.size();
unsigned long ind=0;
for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ )
{
for ( int i = 0; i < 3; i++ ) {
if ((it->_aulNeighbours[i] >= ulCtFacets) && (it->_aulNeighbours[i] < ULONG_MAX)) {
aInds.push_back(ind);
break;
}
unsigned long ind=0;
for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++) {
for (int i = 0; i < 3; i++) {
if ((it->_aulNeighbours[i] >= ulCtFacets) && (it->_aulNeighbours[i] < ULONG_MAX)) {
aInds.push_back(ind);
break;
}
}
}
}
return aInds;
return aInds;
}
bool MeshFixRangeFacet::Fixup()
{
return false;
_rclMesh.RebuildNeighbours();
return true;
}
// ----------------------------------------------------------------------
bool MeshEvalRangePoint::Evaluate()
{
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtPoints = _rclMesh.CountPoints();
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtPoints = _rclMesh.CountPoints();
for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it ) {
if (std::find_if(it->_aulPoints, it->_aulPoints + 3, std::bind2nd(std::greater_equal<unsigned long>(), ulCtPoints)) < it->_aulPoints + 3)
return false;
}
for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it) {
if (std::find_if(it->_aulPoints, it->_aulPoints + 3, std::bind2nd(std::greater_equal<unsigned long>(), ulCtPoints)) < it->_aulPoints + 3)
return false;
}
return true;
return true;
}
std::vector<unsigned long> MeshEvalRangePoint::GetIndices() const
{
std::vector<unsigned long> aInds;
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtPoints = _rclMesh.CountPoints();
std::vector<unsigned long> aInds;
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
unsigned long ulCtPoints = _rclMesh.CountPoints();
unsigned long ind=0;
for ( MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++ )
{
if (std::find_if(it->_aulPoints, it->_aulPoints + 3, std::bind2nd(std::greater_equal<unsigned long>(), ulCtPoints)) < it->_aulPoints + 3)
aInds.push_back(ind);
}
unsigned long ind=0;
for (MeshFacetArray::_TConstIterator it = rFaces.begin(); it != rFaces.end(); ++it, ind++) {
if (std::find_if(it->_aulPoints, it->_aulPoints + 3, std::bind2nd(std::greater_equal<unsigned long>(), ulCtPoints)) < it->_aulPoints + 3)
aInds.push_back(ind);
}
return aInds;
return aInds;
}
bool MeshFixRangePoint::Fixup()
{
return false;
MeshEvalRangePoint eval(_rclMesh);
if (_rclMesh.CountPoints() == 0) {
// if no points are there but facets then the whole mesh can be cleared
_rclMesh.Clear();
}
else {
// facets with point indices out of range cannot be directly deleted because
// 'DeleteFacets' will segfault. But setting all point indices to 0 works.
std::vector<unsigned long> invalid = eval.GetIndices();
if (!invalid.empty()) {
const MeshFacetArray& rFaces = _rclMesh.GetFacets();
for (std::vector<unsigned long>::iterator it = invalid.begin(); it != invalid.end(); ++it) {
MeshFacet& face = const_cast<MeshFacet&>(rFaces[*it]);
face._aulPoints[0] = 0;
face._aulPoints[1] = 0;
face._aulPoints[2] = 0;
}
_rclMesh.DeleteFacets(invalid);
}
}
return true;
}
// ----------------------------------------------------------------------

View File

@ -349,9 +349,9 @@ bool MeshGeomFacet::Weights(const Base::Vector3f& rclP, float& w0, float& w1, fl
return fabs(w0+w1+w2-1.0f)<0.001f;
}
void MeshGeomFacet::ProjectPointToPlane (Base::Vector3f &rclPoint) const
void MeshGeomFacet::ProjectPointToPlane (const Base::Vector3f &rclPoint, Base::Vector3f &rclProj) const
{
rclPoint.ProjectToPlane(_aclPoints[0], GetNormal());
rclPoint.ProjectToPlane(_aclPoints[0], GetNormal(), rclProj);
}
void MeshGeomFacet::ProjectFacetToPlane (MeshGeomFacet &rclFacet) const

View File

@ -349,7 +349,7 @@ public:
/**
* Calculates the projection of a point onto the plane defined by the triangle.
*/
void ProjectPointToPlane (Base::Vector3f &rclPoint) const;
void ProjectPointToPlane (const Base::Vector3f &rclPoint, Base::Vector3f &rclProj) const;
/**
* Calculates the projection of a facet onto the plane defined by the triangle.
*/
@ -592,6 +592,58 @@ public:
void DecrementIndices (unsigned long ulIndex);
};
/**
* MeshPointModifier is a helper class that allows to modify the
* point array of a mesh kernel but with limited access.
*/
class MeshExport MeshPointModifier
{
public:
MeshPointModifier(MeshPointArray& points)
: rPoints(points)
{
}
MeshPointModifier(const MeshPointModifier& c)
: rPoints(c.rPoints)
{
}
private:
MeshPointArray& rPoints;
};
/**
* MeshFacetModifier is a helper class that allows to modify the
* facet array of a mesh kernel but with limited access.
*/
class MeshExport MeshFacetModifier
{
public:
MeshFacetModifier(MeshFacetArray& facets)
: rFacets(facets)
{
}
MeshFacetModifier(const MeshFacetModifier& c)
: rFacets(c.rFacets)
{
}
/**
* Replaces the index of the corner point of the facet at position \a pos
* that is equal to \a old by \a now. If the facet does not have a corner
* point with this index nothing happens.
*/
void Transpose(unsigned long pos, unsigned long old, unsigned long now)
{
rFacets[pos].Transpose(old, now);
}
private:
MeshFacetArray& rFacets;
};
inline MeshPoint::MeshPoint (const Base::Vector3f &rclPt)
#ifdef _MSC_VER
: Vector3f(rclPt),

View File

@ -43,6 +43,7 @@
#include "Evaluation.h"
#include "Builder.h"
#include "Smoothing.h"
#include "MeshIO.h"
using namespace MeshCore;
@ -385,6 +386,12 @@ void MeshKernel::Merge(const MeshPointArray& rPoints, const MeshFacetArray& rFac
RebuildNeighbours(countFacets);
}
void MeshKernel::Cleanup()
{
MeshCleanup meshCleanup(_aclPointArray, _aclFacetArray);
meshCleanup.RemoveInvalids();
}
void MeshKernel::Clear (void)
{
_aclPointArray.clear();

View File

@ -141,6 +141,12 @@ public:
/** Returns the array of all data points. */
const MeshPointArray& GetPoints (void) const { return _aclPointArray; }
/** Returns a modifier for the point array */
MeshPointModifier ModifyPoints()
{
return MeshPointModifier(_aclPointArray);
}
/** Returns the array of all facets */
const MeshFacetArray& GetFacets (void) const { return _aclFacetArray; }
/** Returns an array of facets to the given indices. The indices
@ -148,6 +154,12 @@ public:
*/
MeshFacetArray GetFacets(const std::vector<unsigned long>&) const;
/** Returns a modifier for the facet array */
MeshFacetModifier ModifyFacets()
{
return MeshFacetModifier(_aclFacetArray);
}
/** Returns the array of all edges.
* Notice: The Edgelist will be temporary generated. Changes on the mesh
* structure does not affect the Edgelist
@ -351,8 +363,12 @@ public:
* @note This method overwrites the free usable property of each mesh point.
*/
void DeletePoints (const std::vector<unsigned long> &raulPoints);
/** Removes all as INVALID marked points and facets from the structure. */
void RemoveInvalids ();
/** Rebuilds the neighbour indices for all facets. */
void RebuildNeighbours (void);
/** Removes unreferenced points or facets with invalid indices from the mesh. */
void Cleanup();
/** Clears the whole data structure. */
void Clear (void);
/** Replaces the current data structure with the structure built up of the array
@ -385,7 +401,7 @@ public:
inline void SetPoint (unsigned long ulPtIndex, const Base::Vector3f &rPoint);
/** Sets the point at the given index to the new \a rPoint. */
inline void SetPoint (unsigned long ulPtIndex, float x, float y, float z);
/** Smothes the mesh kernel. */
/** Smoothes the mesh kernel. */
void Smooth(int iterations, float d_max);
/**
* CheckFacets() is invoked within this method and all found facets get deleted from the mesh structure.
@ -405,8 +421,6 @@ public:
protected:
/** Rebuilds the neighbour indices for subset of all facets from index \a index on. */
void RebuildNeighbours (unsigned long);
/** Removes all as INVALID marked points and facets from the structure. */
void RemoveInvalids ();
/** Checks if this point is associated to no other facet and deletes if so.
* The point indices of the facets get adjusted.
* \a ulIndex is the index of the point to be deleted. \a ulFacetIndex is the index
@ -433,11 +447,6 @@ protected:
friend class MeshFastFacetIterator;
friend class MeshAlgorithm;
friend class MeshTopoAlgorithm;
friend class MeshFixNeighbourhood;
friend class MeshFixDegenerations;
friend class MeshFixSingleFacet;
friend class MeshFixInvalids;
friend class MeshFixDegeneratedFacets;
friend class MeshFixDuplicatePoints;
friend class MeshBuilder;
friend class MeshTrimming;