AbdulElahGwaith's picture
Upload folder using huggingface_hub
985c397 verified
// SPDX-License-Identifier: LGPL-2.1-or-later
/***************************************************************************
* 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_ITERATOR_H
#define MESH_ITERATOR_H
#include <Base/Matrix.h>
#include "MeshKernel.h"
namespace MeshCore
{
class MeshKernel;
class MeshGeomFacet;
class MeshPoint;
class MeshGeomEdge;
class MeshIndexEdge;
class MeshHelpEdge;
/**
* The MeshFacetIterator allows one to iterate over the facets that
* hold the topology of the mesh and provides access to their
* geometric information.
* \note This class is not thread-safe.
*/
class MeshFacetIterator
{
public:
/** @name Construction */
//@{
/// construction
inline explicit MeshFacetIterator(const MeshKernel& rclM);
/// construction
inline MeshFacetIterator(const MeshKernel& rclM, FacetIndex ulPos);
/// construction
inline MeshFacetIterator(const MeshFacetIterator& rclI);
inline MeshFacetIterator(MeshFacetIterator&& rclI);
~MeshFacetIterator() = default;
//@}
/** @name Transformation */
//@{
/// Transforms the returned facet points with the current transformation
inline void Transform(const Base::Matrix4D& rclTrf);
//@}
/** @name Access methods */
//@{
/// Access to the element the iterator points to.
const MeshGeomFacet& operator*()
{
return Dereference();
}
/// Access to the element the iterator points to.
const MeshGeomFacet* operator->()
{
return &Dereference();
}
/// Increments the iterator. It points then to the next element if the
/// end is not reached.
const MeshFacetIterator& operator++()
{
++_clIter;
return *this;
}
/// Decrements the iterator. It points then to the previous element if the beginning
/// is not reached.
const MeshFacetIterator& operator--()
{
--_clIter;
return *this;
}
/// Increments the iterator by \a k positions.
const MeshFacetIterator& operator+=(int k)
{
_clIter += k;
return *this;
}
/// Decrements the iterator by \a k positions.
const MeshFacetIterator& operator-=(int k)
{
_clIter -= k;
return *this;
}
/// Assignment.
inline MeshFacetIterator& operator=(const MeshFacetIterator& rpI);
inline MeshFacetIterator& operator=(MeshFacetIterator&& rpI);
/// Compares if this iterator points to a lower element than the other one.
bool operator<(const MeshFacetIterator& rclI) const
{
return _clIter < rclI._clIter;
}
/// Compares if this iterator points to a higher element than the other one.
bool operator>(const MeshFacetIterator& rclI) const
{
return _clIter > rclI._clIter;
}
/// Checks if the iterators points to the same element.
bool operator==(const MeshFacetIterator& rclI) const
{
return _clIter == rclI._clIter;
}
/// Sets the iterator to the beginning of the array.
void Begin()
{
_clIter = _rclFAry.begin();
}
/// Sets the iterator to the end of the array.
void End()
{
_clIter = _rclFAry.end();
}
/// Returns the current position of the iterator in the array.
FacetIndex Position() const
{
return _clIter - _rclFAry.begin();
}
/// Checks if the end is already reached.
bool EndReached() const
{
return !(_clIter < _rclFAry.end());
}
/// Sets the iterator to the beginning of the array.
void Init()
{
Begin();
}
/// Checks if the end is not yet reached.
bool More() const
{
return !EndReached();
}
/// Increments the iterator.
void Next()
{
operator++();
}
/// Sets the iterator to a given position.
inline bool Set(FacetIndex ulIndex);
/// Returns the topologic facet.
inline MeshFacet GetIndices() const
{
return *_clIter;
}
/// Returns the topologic facet.
inline const MeshFacet& GetReference() const
{
return *_clIter;
}
/// Returns iterators pointing to the current facet's neighbours.
inline void GetNeighbours(
MeshFacetIterator& rclN0,
MeshFacetIterator& rclN1,
MeshFacetIterator& rclN2
) const;
/// Sets the iterator to the current facet's neighbour of the side \a usN.
inline void SetToNeighbour(unsigned short usN);
/// Returns the property information to the current facet.
inline unsigned long GetProperty() const;
/// Checks if the iterator points to a valid element inside the array.
inline bool IsValid() const
{
return (_clIter >= _rclFAry.begin()) && (_clIter < _rclFAry.end());
}
//@}
/** @name Flag state
*/
//@{
void SetFlag(MeshFacet::TFlagType tF) const
{
this->_clIter->SetFlag(tF);
}
void ResetFlag(MeshFacet::TFlagType tF) const
{
this->_clIter->ResetFlag(tF);
}
bool IsFlag(MeshFacet::TFlagType tF) const
{
return this->_clIter->IsFlag(tF);
}
void SetProperty(unsigned long uP) const
{
this->_clIter->SetProperty(uP);
}
//@}
protected:
inline const MeshGeomFacet& Dereference();
private:
const MeshKernel& _rclMesh;
const MeshFacetArray& _rclFAry;
const MeshPointArray& _rclPAry;
MeshFacetArray::_TConstIterator _clIter;
MeshGeomFacet _clFacet;
bool _bApply;
Base::Matrix4D _clTrf;
// friends
friend class MeshKernel;
};
/**
* The MeshPointIterator allows one to iterate over the vertices of the mesh and provides access to
* their geometric information. \note This class is not thread-safe.
*/
class MeshExport MeshPointIterator
{
public:
/** @name Construction */
//@{
inline explicit MeshPointIterator(const MeshKernel& rclM);
inline MeshPointIterator(const MeshKernel& rclM, PointIndex ulPos);
inline MeshPointIterator(const MeshPointIterator& rclI);
inline MeshPointIterator(MeshPointIterator&& rclI);
~MeshPointIterator() = default;
//@}
/** @name Transformation */
//@{
/// Transforms the returned points with the current transformation
inline void Transform(const Base::Matrix4D& rclTrf);
//@}
/** @name Access methods */
//@{
/// Access to the element the iterator points to.
const MeshPoint& operator*() const
{
return Dereference();
}
/// Access to the element the iterator points to.
const MeshPoint* operator->() const
{
return &Dereference();
}
/// Increments the iterator. It points then to the next element if the
/// end is not reached.
const MeshPointIterator& operator++()
{
++_clIter;
return *this;
}
/// Decrements the iterator. It points then to the previous element if the beginning
/// is not reached.
const MeshPointIterator& operator--()
{
--_clIter;
return *this;
}
/// Assignment.
inline MeshPointIterator& operator=(const MeshPointIterator& rpI);
inline MeshPointIterator& operator=(MeshPointIterator&& rpI);
/// Compares if this iterator points to a lower element than the other one.
bool operator<(const MeshPointIterator& rclI) const
{
return _clIter < rclI._clIter;
}
/// Compares if this iterator points to a higher element than the other one.
bool operator>(const MeshPointIterator& rclI) const
{
return _clIter > rclI._clIter;
}
/// Checks if the iterators points to the same element.
bool operator==(const MeshPointIterator& rclI) const
{
return _clIter == rclI._clIter;
}
/// Sets the iterator to the beginning of the array.
void Begin()
{
_clIter = _rclPAry.begin();
}
/// Sets the iterator to the end of the array.
void End()
{
_clIter = _rclPAry.end();
}
/// Returns the current position of the iterator in the array.
PointIndex Position() const
{
return _clIter - _rclPAry.begin();
}
/// Checks if the end is already reached.
bool EndReached() const
{
return !(_clIter < _rclPAry.end());
}
/// Sets the iterator to the beginning of the array.
void Init()
{
Begin();
}
/// Checks if the end is not yet reached.
bool More() const
{
return !EndReached();
}
/// Increments the iterator.
void Next()
{
operator++();
}
/// Sets the iterator to a given position.
inline bool Set(PointIndex ulIndex);
/// Checks if the iterator points to a valid element inside the array.
inline bool IsValid() const
{
return (_clIter >= _rclPAry.begin()) && (_clIter < _rclPAry.end());
}
//@}
/** @name Flag state
*/
//@{
void SetFlag(MeshPoint::TFlagType tF) const
{
this->_clIter->SetFlag(tF);
}
void ResetFlag(MeshPoint::TFlagType tF) const
{
this->_clIter->ResetFlag(tF);
}
bool IsFlag(MeshPoint::TFlagType tF) const
{
return this->_clIter->IsFlag(tF);
}
void SetProperty(unsigned long uP) const
{
this->_clIter->SetProperty(uP);
}
//@}
private:
inline const MeshPoint& Dereference() const;
private:
const MeshKernel& _rclMesh;
const MeshPointArray& _rclPAry;
mutable MeshPoint _clPoint;
MeshPointArray::_TConstIterator _clIter;
bool _bApply;
Base::Matrix4D _clTrf;
// friends
friend class MeshKernel;
};
class MeshFastFacetIterator
{
public:
inline explicit MeshFastFacetIterator(const MeshKernel& rclM);
virtual ~MeshFastFacetIterator() = default;
void Init()
{
_clIter = _rclFAry.begin();
}
inline void Next();
bool More()
{
return _clIter != _rclFAry.end();
}
Base::Vector3f _afPoints[3]; // NOLINT
private:
const MeshFacetArray& _rclFAry;
const MeshPointArray& _rclPAry;
MeshFacetArray::_TConstIterator _clIter;
public:
MeshFastFacetIterator(const MeshFastFacetIterator&) = delete;
MeshFastFacetIterator(MeshFastFacetIterator&&) = delete;
void operator=(const MeshFastFacetIterator&) = delete;
void operator=(MeshFastFacetIterator&&) = delete;
};
inline MeshFastFacetIterator::MeshFastFacetIterator(const MeshKernel& rclM)
: _rclFAry(rclM._aclFacetArray)
, _rclPAry(rclM._aclPointArray)
, _clIter(_rclFAry.begin())
{}
inline void MeshFastFacetIterator::Next()
{
const PointIndex* paulPt = _clIter->_aulPoints;
Base::Vector3f* pfPt = _afPoints;
*(pfPt++) = _rclPAry[*(paulPt++)];
*(pfPt++) = _rclPAry[*(paulPt++)];
*pfPt = _rclPAry[*paulPt];
}
inline MeshFacetIterator::MeshFacetIterator(const MeshKernel& rclM)
: _rclMesh(rclM)
, _rclFAry(rclM._aclFacetArray)
, _rclPAry(rclM._aclPointArray)
, _clIter(rclM._aclFacetArray.begin())
, _bApply(false)
{}
inline MeshFacetIterator::MeshFacetIterator(const MeshKernel& rclM, FacetIndex ulPos)
: _rclMesh(rclM)
, _rclFAry(rclM._aclFacetArray)
, _rclPAry(rclM._aclPointArray)
, _clIter(rclM._aclFacetArray.begin() + ulPos)
, _bApply(false)
{}
inline MeshFacetIterator::MeshFacetIterator(const MeshFacetIterator& rclI)
: _rclMesh(rclI._rclMesh)
, _rclFAry(rclI._rclFAry)
, _rclPAry(rclI._rclPAry)
, _clIter(rclI._clIter)
, _bApply(rclI._bApply)
, _clTrf(rclI._clTrf)
{}
inline MeshFacetIterator::MeshFacetIterator(MeshFacetIterator&& rclI)
: _rclMesh(rclI._rclMesh)
, _rclFAry(rclI._rclFAry)
, _rclPAry(rclI._rclPAry)
, _clIter(rclI._clIter)
, _bApply(rclI._bApply)
, _clTrf(rclI._clTrf)
{}
inline void MeshFacetIterator::Transform(const Base::Matrix4D& rclTrf)
{
_clTrf = rclTrf;
Base::Matrix4D tmp;
// checks for unit matrix
_clTrf != tmp ? _bApply = true : _bApply = false;
}
inline const MeshGeomFacet& MeshFacetIterator::Dereference()
{
MeshFacet rclF = *_clIter;
const PointIndex* paulPt = &(_clIter->_aulPoints[0]);
Base::Vector3f* pclPt = _clFacet._aclPoints;
*(pclPt++) = _rclPAry[*(paulPt++)];
*(pclPt++) = _rclPAry[*(paulPt++)];
*pclPt = _rclPAry[*paulPt];
_clFacet._ulProp = rclF._ulProp;
_clFacet._ucFlag = rclF._ucFlag;
_clFacet.NormalInvalid();
if (_bApply) {
_clFacet._aclPoints[0] = _clTrf * _clFacet._aclPoints[0];
_clFacet._aclPoints[1] = _clTrf * _clFacet._aclPoints[1];
_clFacet._aclPoints[2] = _clTrf * _clFacet._aclPoints[2];
}
return _clFacet;
}
inline bool MeshFacetIterator::Set(FacetIndex ulIndex)
{
if (ulIndex < _rclFAry.size()) {
_clIter = _rclFAry.begin() + ulIndex;
return true;
}
_clIter = _rclFAry.end();
return false;
}
inline MeshFacetIterator& MeshFacetIterator::operator=(const MeshFacetIterator& rpI)
{
_clIter = rpI._clIter;
_bApply = rpI._bApply;
_clTrf = rpI._clTrf;
return *this;
}
inline MeshFacetIterator& MeshFacetIterator::operator=(MeshFacetIterator&& rpI)
{
_clIter = rpI._clIter;
_bApply = rpI._bApply;
_clTrf = rpI._clTrf;
return *this;
}
inline unsigned long MeshFacetIterator::GetProperty() const
{
return _clIter->_ulProp;
}
inline void MeshFacetIterator::GetNeighbours(
MeshFacetIterator& rclN0,
MeshFacetIterator& rclN1,
MeshFacetIterator& rclN2
) const
{
if (_clIter->_aulNeighbours[0] != FACET_INDEX_MAX) {
rclN0.Set(_clIter->_aulNeighbours[0]);
}
else {
rclN0.End();
}
if (_clIter->_aulNeighbours[1] != FACET_INDEX_MAX) {
rclN1.Set(_clIter->_aulNeighbours[1]);
}
else {
rclN1.End();
}
if (_clIter->_aulNeighbours[2] != FACET_INDEX_MAX) {
rclN2.Set(_clIter->_aulNeighbours[2]);
}
else {
rclN2.End();
}
}
inline void MeshFacetIterator::SetToNeighbour(unsigned short usN)
{
if (_clIter->_aulNeighbours[usN] != FACET_INDEX_MAX) {
_clIter = _rclFAry.begin() + _clIter->_aulNeighbours[usN];
}
else {
End();
}
}
inline MeshPointIterator::MeshPointIterator(const MeshKernel& rclM)
: _rclMesh(rclM)
, _rclPAry(_rclMesh._aclPointArray)
, _bApply(false)
{
_clIter = _rclPAry.begin();
}
inline MeshPointIterator::MeshPointIterator(const MeshKernel& rclM, PointIndex ulPos)
: _rclMesh(rclM)
, _rclPAry(_rclMesh._aclPointArray)
, _bApply(false)
{
_clIter = _rclPAry.begin() + ulPos;
}
inline MeshPointIterator::MeshPointIterator(const MeshPointIterator& rclI)
: _rclMesh(rclI._rclMesh)
, _rclPAry(rclI._rclPAry)
, _clIter(rclI._clIter)
, _bApply(rclI._bApply)
, _clTrf(rclI._clTrf)
{}
inline MeshPointIterator::MeshPointIterator(MeshPointIterator&& rclI)
: _rclMesh(rclI._rclMesh)
, _rclPAry(rclI._rclPAry)
, _clIter(rclI._clIter)
, _bApply(rclI._bApply)
, _clTrf(rclI._clTrf)
{}
inline void MeshPointIterator::Transform(const Base::Matrix4D& rclTrf)
{
_clTrf = rclTrf;
Base::Matrix4D tmp;
// checks for unit matrix
_clTrf != tmp ? _bApply = true : _bApply = false;
}
inline const MeshPoint& MeshPointIterator::Dereference() const
{
// We change only the value of the point but not the actual iterator
_clPoint = *_clIter;
if (_bApply) {
_clPoint = _clTrf * _clPoint;
}
return _clPoint;
}
inline bool MeshPointIterator::Set(PointIndex ulIndex)
{
if (ulIndex < _rclPAry.size()) {
_clIter = _rclPAry.begin() + ulIndex;
return true;
}
_clIter = _rclPAry.end();
return false;
}
inline MeshPointIterator& MeshPointIterator::operator=(const MeshPointIterator& rpI)
{
_clIter = rpI._clIter;
_bApply = rpI._bApply;
_clTrf = rpI._clTrf;
return *this;
}
inline MeshPointIterator& MeshPointIterator::operator=(MeshPointIterator&& rpI)
{
_clIter = rpI._clIter;
_bApply = rpI._bApply;
_clTrf = rpI._clTrf;
return *this;
}
} // namespace MeshCore
#endif // MESH_ITERATOR_H