mirror of
https://git.salome-platform.org/gitpub/modules/smesh.git
synced 2025-01-27 13:20:34 +05:00
2355: EDF SMESH: New 1D hypothesis "Adaptive"
More performance optimization
This commit is contained in:
parent
813092187c
commit
862dfb92f3
@ -100,10 +100,10 @@ namespace // internal utils
|
|||||||
const ProbePnt& First() const { return myPoints.front(); }
|
const ProbePnt& First() const { return myPoints.front(); }
|
||||||
const ProbePnt& Last() const { return myPoints.back(); }
|
const ProbePnt& Last() const { return myPoints.back(); }
|
||||||
const TopoDS_Edge& Edge() const { return myC3d.Edge(); }
|
const TopoDS_Edge& Edge() const { return myC3d.Edge(); }
|
||||||
bool IsTooDistant( const SMESH_Octree::box_type* faceBox, double maxSegSize ) const
|
bool IsTooDistant( const BBox& faceBox, double maxSegSize ) const
|
||||||
{
|
{
|
||||||
gp_XYZ hsize = myBBox.HSize() + gp_XYZ( maxSegSize, maxSegSize, maxSegSize );
|
gp_XYZ hsize = myBBox.HSize() + gp_XYZ( maxSegSize, maxSegSize, maxSegSize );
|
||||||
return faceBox->IsOut ( SMESH_Octree::box_type( myBBox.Center(), hsize ));
|
return faceBox.IsOut ( Bnd_B3d( myBBox.Center(), hsize ));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//================================================================================
|
//================================================================================
|
||||||
@ -191,7 +191,7 @@ namespace // internal utils
|
|||||||
class ElementBndBoxTree;
|
class ElementBndBoxTree;
|
||||||
struct ElemTreeData : public SMESH_TreeLimit
|
struct ElemTreeData : public SMESH_TreeLimit
|
||||||
{
|
{
|
||||||
vector< int > myWorkIDs[8];
|
vector< int > myWorkIDs[8];// to speed up filling ElementBndBoxTree::_elementIDs
|
||||||
virtual const Bnd_B3d* GetBox(int elemID) const = 0;
|
virtual const Bnd_B3d* GetBox(int elemID) const = 0;
|
||||||
};
|
};
|
||||||
struct TriaTreeData : public ElemTreeData
|
struct TriaTreeData : public ElemTreeData
|
||||||
@ -199,17 +199,20 @@ namespace // internal utils
|
|||||||
vector< Triangle > myTrias;
|
vector< Triangle > myTrias;
|
||||||
double myFaceTol;
|
double myFaceTol;
|
||||||
double myTriasDeflection;
|
double myTriasDeflection;
|
||||||
|
BBox myBBox;
|
||||||
BRepAdaptor_Surface mySurface;
|
BRepAdaptor_Surface mySurface;
|
||||||
const ElementBndBoxTree* myTree;
|
ElementBndBoxTree* myTree;
|
||||||
const Poly_Array1OfTriangle* myPolyTrias;
|
const Poly_Array1OfTriangle* myPolyTrias;
|
||||||
const TColgp_Array1OfPnt* myNodes;
|
const TColgp_Array1OfPnt* myNodes;
|
||||||
bool myOwnNodes;
|
bool myOwnNodes;
|
||||||
|
|
||||||
vector< int > myFoundTriaIDs;
|
typedef vector<int> IntVec;
|
||||||
|
IntVec myFoundTriaIDs;
|
||||||
|
|
||||||
TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree );
|
TriaTreeData( const TopoDS_Face& face, ElementBndBoxTree* triaTree );
|
||||||
~TriaTreeData() { if ( myOwnNodes ) delete myNodes; myNodes = NULL; }
|
~TriaTreeData() { if ( myOwnNodes ) delete myNodes; myNodes = NULL; }
|
||||||
virtual const Bnd_B3d* GetBox(int elemID) const { return &myTrias[elemID].myBox; }
|
virtual const Bnd_B3d* GetBox(int elemID) const { return &myTrias[elemID].myBox; }
|
||||||
|
void PrepareToTriaSearch();
|
||||||
void SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const;
|
void SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const;
|
||||||
double GetMinDistInSphere(const gp_Pnt& p,
|
double GetMinDistInSphere(const gp_Pnt& p,
|
||||||
const double radius,
|
const double radius,
|
||||||
@ -226,6 +229,7 @@ namespace // internal utils
|
|||||||
ElementBndBoxTree(const TopoDS_Face& face);
|
ElementBndBoxTree(const TopoDS_Face& face);
|
||||||
void GetElementsInSphere( const gp_XYZ& center,
|
void GetElementsInSphere( const gp_XYZ& center,
|
||||||
const double radius, vector<int> & foundElemIDs) const;
|
const double radius, vector<int> & foundElemIDs) const;
|
||||||
|
void FillIn();
|
||||||
ElemTreeData* GetElemData() const { return (ElemTreeData*) myLimit; }
|
ElemTreeData* GetElemData() const { return (ElemTreeData*) myLimit; }
|
||||||
TriaTreeData* GetTriaData() const { return (TriaTreeData*) myLimit; }
|
TriaTreeData* GetTriaData() const { return (TriaTreeData*) myLimit; }
|
||||||
|
|
||||||
@ -289,37 +293,49 @@ namespace // internal utils
|
|||||||
for ( int i = trsfNodes->Lower(); i <= trsfNodes->Upper(); ++i )
|
for ( int i = trsfNodes->Lower(); i <= trsfNodes->Upper(); ++i )
|
||||||
trsfNodes->ChangeValue(i).Transform( trsf );
|
trsfNodes->ChangeValue(i).Transform( trsf );
|
||||||
}
|
}
|
||||||
myTrias.resize( myPolyTrias->Length() );
|
for ( int i = myNodes->Lower(); i <= myNodes->Upper(); ++i )
|
||||||
Standard_Integer n1,n2,n3;
|
myBBox.Add( myNodes->Value(i).XYZ() );
|
||||||
for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
|
|
||||||
{
|
|
||||||
myPolyTrias->Value( i ).Get( n1,n2,n3 );
|
|
||||||
myTrias[ i-1 ].Init( myNodes->Value( n1 ),
|
|
||||||
myNodes->Value( n2 ),
|
|
||||||
myNodes->Value( n3 ));
|
|
||||||
}
|
|
||||||
// TODO: mark triangles with nodes on VERTEXes to
|
|
||||||
// less frequently compare with avoidPnt in GetMinDistInSphere()
|
|
||||||
//
|
|
||||||
// Handle(Poly_PolygonOnTriangulation) polygon =
|
|
||||||
// BRep_Tool::PolygonOnTriangulation( edge, tr, loc );
|
|
||||||
// if ( polygon.IsNull() /*|| !pologon.HasParameters()*/ )
|
|
||||||
// continue;
|
|
||||||
// Handle(TColStd_Array1OfInteger) nodeIDs = polygon->Nodes();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void TriaTreeData::PrepareToTriaSearch()
|
||||||
|
{
|
||||||
|
if ( !myTrias.empty() ) return; // already done
|
||||||
|
if ( !myPolyTrias ) return;
|
||||||
|
|
||||||
|
myTrias.resize( myPolyTrias->Length() );
|
||||||
|
Standard_Integer n1,n2,n3;
|
||||||
|
for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
|
||||||
|
{
|
||||||
|
myPolyTrias->Value( i ).Get( n1,n2,n3 );
|
||||||
|
myTrias[ i-1 ].Init( myNodes->Value( n1 ),
|
||||||
|
myNodes->Value( n2 ),
|
||||||
|
myNodes->Value( n3 ));
|
||||||
|
}
|
||||||
|
myTree->FillIn();
|
||||||
|
|
||||||
|
// TODO: mark triangles with nodes on VERTEXes to
|
||||||
|
// less frequently compare with avoidPnt in GetMinDistInSphere()
|
||||||
|
//
|
||||||
|
// Handle(Poly_PolygonOnTriangulation) polygon =
|
||||||
|
// BRep_Tool::PolygonOnTriangulation( edge, tr, loc );
|
||||||
|
// if ( polygon.IsNull() || !pologon.HasParameters() )
|
||||||
|
// continue;
|
||||||
|
// Handle(TColStd_Array1OfInteger) nodeIDs = polygon->Nodes();
|
||||||
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Set size of segments by size of triangles
|
* \brief Set size of segments by size of triangles
|
||||||
*/
|
*/
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
|
||||||
void TriaTreeData::SetSizeByTrias( SegSizeTree& sizeTree, double deflection ) const
|
void TriaTreeData::SetSizeByTrias( SegSizeTree& sizeTree, double hypDeflection ) const
|
||||||
{
|
{
|
||||||
if ( mySurface.GetType() == GeomAbs_Plane ||
|
if ( mySurface.GetType() == GeomAbs_Plane ||
|
||||||
myTriasDeflection <= std::numeric_limits<double>::min() )
|
myTriasDeflection <= 1e-100 )
|
||||||
return;
|
return;
|
||||||
const double factor = deflection / myTriasDeflection;
|
const double factor = hypDeflection / myTriasDeflection;
|
||||||
|
|
||||||
bool isConstSize;
|
bool isConstSize;
|
||||||
switch( mySurface.GetType() ) {
|
switch( mySurface.GetType() ) {
|
||||||
@ -343,7 +359,7 @@ namespace // internal utils
|
|||||||
double size = -1., maxLinkLen;
|
double size = -1., maxLinkLen;
|
||||||
int jLongest;
|
int jLongest;
|
||||||
|
|
||||||
int nbLinks = 0;
|
//int nbLinks = 0;
|
||||||
for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
|
for ( int i = 1; i <= myPolyTrias->Upper(); ++i )
|
||||||
{
|
{
|
||||||
// get corners of a triangle
|
// get corners of a triangle
|
||||||
@ -375,16 +391,15 @@ namespace // internal utils
|
|||||||
// compute minimal altitude of a triangle
|
// compute minimal altitude of a triangle
|
||||||
if ( !isConstSize || size < 0. )
|
if ( !isConstSize || size < 0. )
|
||||||
{
|
{
|
||||||
double maxSide = Max( a[0], Max( a[1], a[2] ));
|
double s = 0.5 * ( a[0] + a[1] + a[2] );
|
||||||
double s = 0.5 * ( a[0] + a[1] + a[2] );
|
double area = sqrt( s * (s - a[0]) * (s - a[1]) * (s - a[2]));
|
||||||
double area = sqrt( s * (s - a[0]) * (s - a[1]) * (s - a[2]));
|
size = 2 * area / maxLinkLen; // minimal altitude
|
||||||
size = 2 * area / maxSide; // minimal altitude
|
|
||||||
}
|
}
|
||||||
// set size to the size tree
|
// set size to the size tree
|
||||||
if ( !isDone[ jLongest ] || !isConstSize )
|
if ( !isDone[ jLongest ] || !isConstSize )
|
||||||
{
|
{
|
||||||
++nbLinks;
|
//++nbLinks;
|
||||||
int nb = Max( 1, int( a[jLongest] / size / 2 ));
|
int nb = Max( 1, int( maxLinkLen / size / 2 ));
|
||||||
for ( int k = 0; k <= nb; ++k )
|
for ( int k = 0; k <= nb; ++k )
|
||||||
{
|
{
|
||||||
double r = double( k ) / nb;
|
double r = double( k ) / nb;
|
||||||
@ -521,7 +536,17 @@ namespace // internal utils
|
|||||||
TriaTreeData* data = new TriaTreeData( face, this );
|
TriaTreeData* data = new TriaTreeData( face, this );
|
||||||
data->myMaxLevel = 5;
|
data->myMaxLevel = 5;
|
||||||
myLimit = data;
|
myLimit = data;
|
||||||
|
}
|
||||||
|
//================================================================================
|
||||||
|
/*!
|
||||||
|
* \brief Fill all levels of octree of Poly_Triangulation of a FACE
|
||||||
|
*/
|
||||||
|
//================================================================================
|
||||||
|
|
||||||
|
void ElementBndBoxTree::FillIn()
|
||||||
|
{
|
||||||
|
if ( myChildren ) return;
|
||||||
|
TriaTreeData* data = GetTriaData();
|
||||||
if ( !data->myTrias.empty() )
|
if ( !data->myTrias.empty() )
|
||||||
{
|
{
|
||||||
for ( size_t i = 0; i < data->myTrias.size(); ++i )
|
for ( size_t i = 0; i < data->myTrias.size(); ++i )
|
||||||
@ -538,13 +563,10 @@ namespace // internal utils
|
|||||||
|
|
||||||
Bnd_B3d* ElementBndBoxTree::buildRootBox()
|
Bnd_B3d* ElementBndBoxTree::buildRootBox()
|
||||||
{
|
{
|
||||||
Bnd_B3d* box = new Bnd_B3d;
|
TriaTreeData* data = GetTriaData();
|
||||||
ElemTreeData* data = GetElemData();
|
Bnd_B3d* box = new Bnd_B3d( data->myBBox );
|
||||||
for ( int i = 0; i < _elementIDs.size(); ++i )
|
|
||||||
box->Add( *data->GetBox( _elementIDs[i] ));
|
|
||||||
return box;
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
/*!
|
/*!
|
||||||
* \brief Redistrubute element boxes among children
|
* \brief Redistrubute element boxes among children
|
||||||
@ -1059,7 +1081,12 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
|||||||
|
|
||||||
EdgeData::TPntIter pIt2 = eData.myPoints.begin(), pIt1 = pIt2++;
|
EdgeData::TPntIter pIt2 = eData.myPoints.begin(), pIt1 = pIt2++;
|
||||||
for ( ; pIt2 != eData.myPoints.end(); ++pIt1, ++pIt2 )
|
for ( ; pIt2 != eData.myPoints.end(); ++pIt1, ++pIt2 )
|
||||||
sizeTree.SetSize( (*pIt1).myP, (*pIt2).myP );
|
{
|
||||||
|
double sz = sizeTree.SetSize( (*pIt1).myP, (*pIt2).myP );
|
||||||
|
sz = Min( sz, myHyp->GetMaxSize() );
|
||||||
|
pIt1->mySegSize = Min( sz, pIt1->mySegSize );
|
||||||
|
pIt2->mySegSize = Min( sz, pIt2->mySegSize );
|
||||||
|
}
|
||||||
|
|
||||||
if ( _computeCanceled ) return false;
|
if ( _computeCanceled ) return false;
|
||||||
}
|
}
|
||||||
@ -1097,10 +1124,10 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
|||||||
|
|
||||||
// get points to check distance to the face
|
// get points to check distance to the face
|
||||||
EdgeData::TPntIter pIt2 = eData.myPoints.begin(), pIt1 = pIt2++;
|
EdgeData::TPntIter pIt2 = eData.myPoints.begin(), pIt1 = pIt2++;
|
||||||
maxSegSize = pIt1->mySegSize = sizeTree.GetSize( pIt1->myP );
|
maxSegSize = pIt1->mySegSize = Min( pIt1->mySegSize, sizeTree.GetSize( pIt1->myP ));
|
||||||
for ( ; pIt2 != eData.myPoints.end(); )
|
for ( ; pIt2 != eData.myPoints.end(); )
|
||||||
{
|
{
|
||||||
pIt2->mySegSize = sizeTree.GetSize( pIt2->myP );
|
pIt2->mySegSize = Min( pIt2->mySegSize, sizeTree.GetSize( pIt2->myP ));
|
||||||
double curSize = Min( pIt1->mySegSize, pIt2->mySegSize );
|
double curSize = Min( pIt1->mySegSize, pIt2->mySegSize );
|
||||||
maxSegSize = Max( pIt2->mySegSize, maxSegSize );
|
maxSegSize = Max( pIt2->mySegSize, maxSegSize );
|
||||||
if ( pIt1->myP.Distance( pIt2->myP ) > curSize )
|
if ( pIt1->myP.Distance( pIt2->myP ) > curSize )
|
||||||
@ -1118,8 +1145,11 @@ bool AdaptiveAlgo::Compute(SMESH_Mesh & theMesh,
|
|||||||
}
|
}
|
||||||
// check if the face is more distant than a half of the current segment size,
|
// check if the face is more distant than a half of the current segment size,
|
||||||
// if not, segment size is decreased
|
// if not, segment size is decreased
|
||||||
if ( iLoop == 0 && eData.IsTooDistant( triaTree.getBox(), maxSegSize ))
|
|
||||||
|
if ( iLoop == 0 && eData.IsTooDistant( triaSearcher->myBBox, maxSegSize ))
|
||||||
break;
|
break;
|
||||||
|
triaSearcher->PrepareToTriaSearch();
|
||||||
|
|
||||||
//cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
|
//cout << "E " << theMesh.GetMeshDS()->ShapeToIndex( eData.Edge() ) << endl;
|
||||||
sizeDecreased = false;
|
sizeDecreased = false;
|
||||||
const gp_Pnt* avoidPnt = & eData.First().myP;
|
const gp_Pnt* avoidPnt = & eData.First().myP;
|
||||||
@ -1247,7 +1277,11 @@ bool AdaptiveAlgo::makeSegments()
|
|||||||
while ( nbSegs[i] * fact < segCount )
|
while ( nbSegs[i] * fact < segCount )
|
||||||
++i;
|
++i;
|
||||||
if ( i < nbDiv )
|
if ( i < nbDiv )
|
||||||
params.push_back( f + parLen * i / nbDiv );
|
{
|
||||||
|
double d = i - ( nbSegs[i] - segCount/fact ) / ( nbSegs[i] - nbSegs[i-1] );
|
||||||
|
params.push_back( f + parLen * d / nbDiv );
|
||||||
|
//params.push_back( f + parLen * i / nbDiv );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1282,7 +1316,9 @@ bool AdaptiveAlgo::makeSegments()
|
|||||||
|
|
||||||
} // loop on EDGEs
|
} // loop on EDGEs
|
||||||
|
|
||||||
myEdges.clear();
|
SMESHUtils::FreeVector( myEdges );
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
//================================================================================
|
//================================================================================
|
||||||
|
Loading…
Reference in New Issue
Block a user