-// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2024 CEA, EDF, OPEN CASCADE
//
// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
//
#include "StdMeshers_Adaptive1D.hxx"
+#include "SMESHDS_Mesh.hxx"
#include "SMESH_Gen.hxx"
+#include "SMESH_HypoFilter.hxx"
#include "SMESH_Mesh.hxx"
#include "SMESH_MesherHelper.hxx"
#include "SMESH_Octree.hxx"
#include "SMESH_subMesh.hxx"
-#include "SMESH_HypoFilter.hxx"
#include <Utils_SALOME_Exception.hxx>
#include <BRepAdaptor_Curve.hxx>
#include <BRepAdaptor_Surface.hxx>
+#include <BRepBndLib.hxx>
#include <BRepMesh_IncrementalMesh.hxx>
#include <BRep_Tool.hxx>
#include <Bnd_B3d.hxx>
+#include <Bnd_Box.hxx>
#include <GCPnts_AbscissaPoint.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <Geom_Curve.hxx>
class AdaptiveAlgo : public StdMeshers_Regular_1D
{
public:
- AdaptiveAlgo(int hypId, int studyId, SMESH_Gen* gen);
+ AdaptiveAlgo(int hypId, SMESH_Gen* gen);
virtual bool Compute(SMESH_Mesh & aMesh, const TopoDS_Shape & aShape );
virtual bool Evaluate(SMESH_Mesh & theMesh,
const TopoDS_Shape & theShape,
BBox myBBox;
BRepAdaptor_Surface mySurface;
ElementBndBoxTree* myTree;
- const Poly_Array1OfTriangle* myPolyTrias;
- const TColgp_Array1OfPnt* myNodes;
- bool myOwnNodes;
+ TColgp_Array1OfPnt myNodes;
typedef vector<int> IntVec;
IntVec myFoundTriaIDs;
TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree );
- ~TriaTreeData() { if ( myOwnNodes ) delete myNodes; myNodes = NULL; }
+ ~TriaTreeData() {
+ }
virtual const Bnd_B3d* GetBox(int elemID) const { return &myTrias[elemID].myBox; }
void PrepareToTriaSearch();
void SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const;
vector< int > _elementIDs;
};
//================================================================================
- /*!
- * \brief BRepMesh_IncrementalMesh with access to its protected Bnd_Box
- */
- struct IncrementalMesh : public BRepMesh_IncrementalMesh
- {
- IncrementalMesh(const TopoDS_Shape& shape,
- const Standard_Real deflection,
- const bool relative):
- BRepMesh_IncrementalMesh( shape, deflection, relative )
- {
- }
- Bnd_B3d GetBox() const
- {
- Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
- myBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
- Bnd_B3d bb;
- bb.Add( gp_XYZ( TXmin, TYmin, TZmin ));
- bb.Add( gp_XYZ( TXmax, TYmax, TZmax ));
- return bb;
- }
- };
- //================================================================================
/*!
* \brief Link of two nodes
*/
TriaTreeData::TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree )
: myTriasDeflection(0), mySurface( face ),
- myTree(NULL), myPolyTrias(NULL), myNodes(NULL), myOwnNodes(false)
+ myTree(NULL)
{
TopLoc_Location loc;
Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( face, loc );
{
myFaceTol = SMESH_MesherHelper::MaxTolerance( face );
myTree = triaTree;
- myNodes = & tr->Nodes();
- myPolyTrias = & tr->Triangles();
+ myNodes = TColgp_Array1OfPnt( 1, tr->NbNodes() );
+ for (int ii = 1; ii <= tr->NbNodes(); ++ii) {
+ myNodes(ii) = tr->Node(ii);
+ }
myTriasDeflection = tr->Deflection();
if ( !loc.IsIdentity() ) // transform nodes if necessary
{
- TColgp_Array1OfPnt* trsfNodes = new TColgp_Array1OfPnt( myNodes->Lower(), myNodes->Upper() );
- trsfNodes->Assign( *myNodes );
- myNodes = trsfNodes;
- myOwnNodes = true;
const gp_Trsf& trsf = loc;
- for ( int i = trsfNodes->Lower(); i <= trsfNodes->Upper(); ++i )
- trsfNodes->ChangeValue(i).Transform( trsf );
+ for ( int i = myNodes.Lower(); i <= myNodes.Upper(); ++i )
+ myNodes(i).Transform( trsf );
}
- for ( int i = myNodes->Lower(); i <= myNodes->Upper(); ++i )
- myBBox.Add( myNodes->Value(i).XYZ() );
+ for ( int i = myNodes.Lower(); i <= myNodes.Upper(); ++i )
+ myBBox.Add( myNodes.Value(i).XYZ() );
}
}
//================================================================================
void TriaTreeData::PrepareToTriaSearch()
{
if ( !myTrias.empty() ) return; // already done
- if ( !myPolyTrias ) return;
+
+ TopLoc_Location loc;
+ Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
+
+ if ( tr.IsNull() || !tr->NbTriangles() ) return;
// get all boundary links and nodes on VERTEXes
map< NLink, Segment* > linkToSegMap;
map< NLink, Segment* >::iterator l2s;
set< int > vertexNodes;
- TopLoc_Location loc;
- Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
if ( !tr.IsNull() )
{
TopTools_IndexedMapOfShape edgeMap;
{
const NLink& link = (*l2s).first;
(*l2s).second = & mySegments[ iS ];
- mySegments[ iS ].Init( myNodes->Value( link.N1() ),
- myNodes->Value( link.N2() ));
+ mySegments[ iS ].Init( myNodes( link.N1() ),
+ myNodes( link.N2() ));
}
}
// initialize myTrias
- myTrias.resize( myPolyTrias->Length() );
+ myTrias.resize( tr->NbTriangles() );
Standard_Integer n1,n2,n3;
- for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
+ for ( int i = 1; i <= tr->NbTriangles(); ++i )
{
Triangle & t = myTrias[ i-1 ];
- myPolyTrias->Value( i ).Get( n1,n2,n3 );
- t.Init( myNodes->Value( n1 ),
- myNodes->Value( n2 ),
- myNodes->Value( n3 ));
+ tr->Triangle( i ).Get( n1,n2,n3 );
+ t.Init( myNodes.Value( n1 ),
+ myNodes.Value( n2 ),
+ myNodes.Value( n3 ));
int nbSeg = 0;
if (( l2s = linkToSegMap.find( NLink( n1, n2 ))) != linkToSegMap.end())
t.mySegments[ nbSeg++ ] = l2s->second;
double a[3];
bool isDone[3];
double size = -1., maxLinkLen;
- int jLongest;
+ int jLongest = 0;
- //int nbLinks = 0;
- for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
+ TopLoc_Location loc;
+ Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
+ for ( int i = 1; i <= tr->NbTriangles(); ++i )
{
// get corners of a triangle
- myPolyTrias->Value( i ).Get( n[0],n[1],n[2] );
+ tr->Triangle( i ).Get( n[0],n[1],n[2] );
n[3] = n[0];
- p[0] = myNodes->Value( n[0] );
- p[1] = myNodes->Value( n[1] );
- p[2] = myNodes->Value( n[2] );
+ p[0] = myNodes.Value( n[0] );
+ p[1] = myNodes.Value( n[1] );
+ p[2] = myNodes.Value( n[2] );
p[3] = p[0];
// get length of links and find the longest one
maxLinkLen = 0;
}
//cout << "SetSizeByTrias, i="<< i << " " << sz * factor << endl;
}
- // cout << "SetSizeByTrias, nn tria="<< myPolyTrias->Upper()
+ // cout << "SetSizeByTrias, nn tria="<< tr->NbTriangles()
// << " nb links" << nbLinks << " isConstSize="<<isConstSize
// << " " << size * factor << endl;
}
if ( myFoundTriaIDs.empty() )
return minDist2;
+ TopLoc_Location loc;
+ Handle(Poly_Triangulation) tr = BRep_Tool::Triangulation( mySurface.Face(), loc );
+
Standard_Integer n[ 3 ];
for ( size_t i = 0; i < myFoundTriaIDs.size(); ++i )
{
t.myIsChecked = true;
double d, minD2 = minDist2;
- myPolyTrias->Value( myFoundTriaIDs[i]+1 ).Get( n[0],n[1],n[2] );
+ tr->Triangle( myFoundTriaIDs[i]+1 ).Get( n[0],n[1],n[2] );
if ( avoidPnt && t.myHasNodeOnVertex )
{
bool avoidTria = false;
for ( int i = 0; i < 3; ++i )
{
- const gp_Pnt& pn = myNodes->Value(n[i]);
- if ( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 ))
+ const gp_Pnt& pn = myNodes.Value(n[i]);
+ if (( avoidTria = ( pn.SquareDistance( *avoidPnt ) <= tol2 )))
break;
if ( !projectedOnly )
minD2 = Min( minD2, pn.SquareDistance( p ));
else
{
for ( int i = 0; i < 3; ++i )
- minD2 = Min( minD2, p.SquareDistance( myNodes->Value(n[i]) ));
+ minD2 = Min( minD2, p.SquareDistance( myNodes.Value(n[i]) ));
if ( minD2 < t.myMaxSize2 && ( t.DistToProjection( p, d ) || t.DistToSegment( p, d )))
minD2 = Min( minD2, d*d );
minDist2 = Min( minDist2, minD2 );
//================================================================================
/*!
- * \brief Consturct ElementBndBoxTree of Poly_Triangulation of a FACE
+ * \brief Construct ElementBndBoxTree of Poly_Triangulation of a FACE
*/
//================================================================================
void ElementBndBoxTree::buildChildrenData()
{
ElemTreeData* data = GetElemData();
- for ( int i = 0; i < _elementIDs.size(); ++i )
+ for ( size_t i = 0; i < _elementIDs.size(); ++i )
{
const Bnd_B3d* elemBox = data->GetBox( _elementIDs[i] );
for (int j = 0; j < 8; j++)
{
ElementBndBoxTree* child = static_cast<ElementBndBoxTree*>( myChildren[j] );
child->_elementIDs = data->myWorkIDs[ j ];
- if ( child->_elementIDs.size() <= theMaxNbElemsInLeaf )
+ if ((int) child->_elementIDs.size() <= theMaxNbElemsInLeaf )
child->myIsLeaf = true;
data->myWorkIDs[ j ].clear();
}
if ( isLeaf() )
{
ElemTreeData* data = GetElemData();
- for ( int i = 0; i < _elementIDs.size(); ++i )
+ for ( size_t i = 0; i < _elementIDs.size(); ++i )
if ( !data->GetBox( _elementIDs[i] )->IsOut( center, radius ))
foundElemIDs.push_back( _elementIDs[i] );
}
//function : StdMeshers_Adaptive1D
//purpose : Constructor
StdMeshers_Adaptive1D::StdMeshers_Adaptive1D(int hypId,
- int studyId,
SMESH_Gen * gen)
- :SMESH_Hypothesis(hypId, studyId, gen)
+ :SMESH_Hypothesis(hypId, gen)
{
myMinSize = 1e-10;
myMaxSize = 1e+10;
//function : SetDeflection
//purpose :
void StdMeshers_Adaptive1D::SetDeflection(double value)
- throw(SALOME_Exception)
{
if (value <= std::numeric_limits<double>::min() )
throw SALOME_Exception("Deflection must be greater that zero");
//function : SetMinSize
//purpose : Sets minimal allowed segment length
void StdMeshers_Adaptive1D::SetMinSize(double minSize)
- throw(SALOME_Exception)
{
if (minSize <= std::numeric_limits<double>::min() )
throw SALOME_Exception("Min size must be greater that zero");
//function : SetMaxSize
//purpose : Sets maximal allowed segment length
void StdMeshers_Adaptive1D::SetMaxSize(double maxSize)
- throw(SALOME_Exception)
{
if (maxSize <= std::numeric_limits<double>::min() )
throw SALOME_Exception("Max size must be greater that zero");
istream & StdMeshers_Adaptive1D::LoadFrom(istream & load)
{
int dummyParam;
- bool isOK = (load >> myMinSize >> myMaxSize >> myDeflection >> dummyParam >> dummyParam);
+ bool isOK = static_cast<bool>(load >> myMinSize >> myMaxSize >> myDeflection >> dummyParam >> dummyParam);
if (!isOK)
load.clear(ios::badbit | load.rdstate());
return load;
if ( !myAlgo )
{
AdaptiveAlgo* newAlgo =
- new AdaptiveAlgo( _gen->GetANewId(), _studyId, _gen );
+ new AdaptiveAlgo( _gen->GetANewId(), _gen );
newAlgo->SetHypothesis( this );
((StdMeshers_Adaptive1D*) this)->myAlgo = newAlgo;
//================================================================================
AdaptiveAlgo::AdaptiveAlgo(int hypId,
- int studyId,
SMESH_Gen* gen)
- : StdMeshers_Regular_1D( hypId, studyId, gen ),
+ : StdMeshers_Regular_1D( hypId, gen ),
myHyp(NULL)
{
_name = "AdaptiveAlgo_1D";
TopExp::MapShapes( theMesh.GetShapeToMesh(), TopAbs_FACE, faceMap );
// Triangulate the shape with the given deflection ?????????
+ {
+ BRepMesh_IncrementalMesh im( theMesh.GetShapeToMesh(), myHyp->GetDeflection(), /*isRelatif=*/0);
+ }
+
+ // get a bnd box
Bnd_B3d box;
{
- IncrementalMesh im( theMesh.GetShapeToMesh(), myHyp->GetDeflection(), /*Relatif=*/false);
- box = im.GetBox();
+ Bnd_Box aBox;
+ BRepBndLib::Add( theMesh.GetShapeToMesh(), aBox);
+ Standard_Real TXmin, TYmin, TZmin, TXmax, TYmax, TZmax;
+ aBox.Get(TXmin, TYmin, TZmin, TXmax, TYmax, TZmax);
+ box.Add( gp_XYZ( TXmin, TYmin, TZmin ));
+ box.Add( gp_XYZ( TXmax, TYmax, TZmax ));
}
// *theProgress = 0.3;
eData.AddPoint( eData.myPoints.end(), eData.myC3d.LastParameter() );
}
}
+ if ( myEdges.empty() ) return true;
if ( _computeCanceled ) return false;
// Take into account size of already existing segments
StdMeshers_Regular_1D::_value[ DEFLECTION_IND ] = myHyp->GetDeflection();
list< double > params;
- for ( int iE = 0; iE < myEdges.size(); ++iE )
+ for ( size_t iE = 0; iE < myEdges.size(); ++iE )
{
EdgeData& eData = myEdges[ iE ];
//cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
triaSearcher->SetSizeByTrias( sizeTree, myHyp->GetDeflection() );
- for ( int iE = 0; iE < myEdges.size(); ++iE )
+ for ( size_t iE = 0; iE < myEdges.size(); ++iE )
{
EdgeData& eData = myEdges[ iE ];
//cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
sizeDecreased = false;
const gp_Pnt* avoidPnt = & eData.First().myP;
+ EdgeData::TPntIter pItLast = --eData.myPoints.end(), pItFirst = eData.myPoints.begin();
for ( pIt1 = eData.myPoints.begin(); pIt1 != eData.myPoints.end(); )
{
double distToFace =
// << "\t SetSize " << allowedSize << " at "
// << pIt1->myP.X() <<", "<< pIt1->myP.Y()<<", "<<pIt1->myP.Z() << endl;
pIt2 = pIt1;
- if ( --pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+ if ( pIt1 != pItFirst && ( --pIt2 )->mySegSize > allowedSize )
sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
pIt2 = pIt1;
- if ( ++pIt2 != eData.myPoints.end() && pIt2->mySegSize > allowedSize )
+ if ( pIt1 != pItLast && ( ++pIt2 )->mySegSize > allowedSize )
sizeTree.SetSize( eData.myC3d.Value( 0.6*pIt2->myU + 0.4*pIt1->myU ), allowedSize );
}
pIt1->mySegSize = allowedSize;
}
++pIt1;
- if ( & (*pIt1) == & eData.Last() )
- avoidPnt = & eData.Last().myP;
- else
- avoidPnt = NULL;
+ avoidPnt = ( pIt1 == pItLast ) ? & eData.Last().myP : NULL;
if ( iLoop > 20 )
{
-#ifdef _DEBUG_
- cout << "Infinite loop in AdaptiveAlgo::Compute()" << endl;
-#endif
+ if(SALOME::VerbosityActivated())
+ cout << "Infinite loop in AdaptiveAlgo::Compute()" << endl;
+
sizeDecreased = false;
break;
}
vector< double > nbSegs, params;
- for ( int iE = 0; iE < myEdges.size(); ++iE )
+ for ( size_t iE = 0; iE < myEdges.size(); ++iE )
{
EdgeData& eData = myEdges[ iE ];
edgeMinSize = Min( edgeMinSize,
Min( pIt1->mySegSize, mySizeTree->GetSize( pIt1->myP )));
- const double f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
+ const double f = eData.myC3d.FirstParameter(), l = eData.myC3d.LastParameter();
const double parLen = l - f;
const int nbDivSeg = 5;
- int nbDiv = Max( 1, int ( eData.myLength / edgeMinSize * nbDivSeg ));
+ size_t nbDiv = Max( 1, int ( eData.myLength / edgeMinSize * nbDivSeg ));
// compute nb of segments
- bool toRecompute = true;
+ bool toRecompute = true;
double maxSegSize = 0;
size_t i = 1, segCount;
//cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
}
// compute parameters of nodes
- int nbSegFinal = Max( 1, int(floor( nbSegs.back() + 0.5 )));
+ size_t nbSegFinal = Max( 1, int(floor( nbSegs.back() + 0.5 )));
double fact = nbSegFinal / nbSegs.back();
if ( maxSegSize / fact > myHyp->GetMaxSize() )
fact = ++nbSegFinal / nbSegs.back();
for ( ; edExp.More(); edExp.Next() )
{
- const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
+ //const TopoDS_Edge & edge = TopoDS::Edge( edExp.Current() );
StdMeshers_Regular_1D::Evaluate( theMesh, theShape, theResMap );
}
return true;