PR : merge from V7_2_1p1

memory leaks, bug in import 1D for cracks
M src/SMDS/SMDS_UnstructuredGrid.cxx
M src/SMESH/SMESH_MeshEditor.cxx
M src/SMESH/SMESH_MesherHelper.cxx
M src/SMESHUtils/SMESH_MeshAlgos.cxx
M src/SMESHUtils/SMESH_MeshAlgos.hxx
M src/SMESHUtils/SMESH_Octree.hxx
M src/SMESHUtils/SMESH_Tree.hxx
M src/SMESH_PY/smeshstudytools.py
M src/StdMeshers/StdMeshers_Import_1D.cxx
This commit is contained in:
prascle 2013-08-03 11:11:12 +00:00
parent 7a89c82974
commit ef59152514
9 changed files with 169 additions and 46 deletions

View File

@ -326,7 +326,7 @@ void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes,
int start, int start,
int end) int end)
{ {
MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start); //MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
for (int j = start; j < end; j++) for (int j = start; j < end; j++)
{ {
newTypes->SetValue(alreadyCopied, this->Types->GetValue(j)); newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));

View File

@ -9891,12 +9891,14 @@ namespace {
//================================================================================ //================================================================================
/*! /*!
\brief Identify the elements that will be affected by node duplication (actual duplication is not performed. \brief Identify the elements that will be affected by node duplication (actual duplication is not performed).
This method is the first step of DoubleNodeElemGroupsInRegion. This method is the first step of DoubleNodeElemGroupsInRegion.
\param theElems - list of groups of elements (edges or faces) to be replicated \param theElems - list of groups of elements (edges or faces) to be replicated
\param theNodesNot - list of groups of nodes not to replicated \param theNodesNot - list of groups of nodes not to replicated
\param theShape - shape to detect affected elements (element which geometric center \param theShape - shape to detect affected elements (element which geometric center
located on or inside shape). located on or inside shape). If the shape is null, detection is done on faces orientations
(select elements with a gravity center on the side given by faces normals).
This mode (null shape) is faster, but works only when theElems are faces, with coherents orientations.
The replicated nodes should be associated to affected elements. The replicated nodes should be associated to affected elements.
\return groups of affected elements \return groups of affected elements
\sa DoubleNodeElemGroupsInRegion() \sa DoubleNodeElemGroupsInRegion()
@ -9909,8 +9911,105 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl
TIDSortedElemSet& theAffectedElems) TIDSortedElemSet& theAffectedElems)
{ {
if ( theShape.IsNull() ) if ( theShape.IsNull() )
return false; {
std::set<const SMDS_MeshNode*> alreadyCheckedNodes;
std::set<const SMDS_MeshElement*> alreadyCheckedElems;
std::set<const SMDS_MeshElement*> edgesToCheck;
alreadyCheckedNodes.clear();
alreadyCheckedElems.clear();
edgesToCheck.clear();
// --- iterates on elements to be replicated and get elements by back references from their nodes
TIDSortedElemSet::const_iterator elemItr = theElems.begin();
int ielem = 1;
for ( ; elemItr != theElems.end(); ++elemItr )
{
SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr;
if (!anElem || (anElem->GetType() != SMDSAbs_Face))
continue;
gp_XYZ normal;
SMESH_MeshAlgos::FaceNormal( anElem, normal, /*normalized=*/true );
MESSAGE("element " << ielem++ << " normal " << normal.X() << " " << normal.Y() << " " << normal.Z());
std::set<const SMDS_MeshNode*> nodesElem;
nodesElem.clear();
SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator();
while ( nodeItr->more() )
{
const SMDS_MeshNode* aNode = cast2Node(nodeItr->next());
nodesElem.insert(aNode);
}
std::set<const SMDS_MeshNode*>::iterator nodit = nodesElem.begin();
for (; nodit != nodesElem.end(); nodit++)
{
MESSAGE(" noeud ");
const SMDS_MeshNode* aNode = *nodit;
if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() )
continue;
if (alreadyCheckedNodes.find(aNode) != alreadyCheckedNodes.end())
continue;
alreadyCheckedNodes.insert(aNode);
SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator();
while ( backElemItr->more() )
{
MESSAGE(" backelem ");
const SMDS_MeshElement* curElem = backElemItr->next();
if (alreadyCheckedElems.find(curElem) != alreadyCheckedElems.end())
continue;
if (theElems.find(curElem) != theElems.end())
continue;
alreadyCheckedElems.insert(curElem);
double x=0, y=0, z=0;
int nb = 0;
SMDS_ElemIteratorPtr nodeItr2 = curElem->nodesIterator();
while ( nodeItr2->more() )
{
const SMDS_MeshNode* anotherNode = cast2Node(nodeItr2->next());
x += anotherNode->X();
y += anotherNode->Y();
z += anotherNode->Z();
nb++;
}
gp_XYZ p;
p.SetCoord( x/nb -aNode->X(),
y/nb -aNode->Y(),
z/nb -aNode->Z() );
MESSAGE(" check " << p.X() << " " << p.Y() << " " << p.Z());
if (normal*p > 0)
{
MESSAGE(" --- inserted")
theAffectedElems.insert( curElem );
}
else if (curElem->GetType() == SMDSAbs_Edge)
edgesToCheck.insert(curElem);
}
}
}
// --- add also edges lying on the set of faces (all nodes in alreadyCheckedNodes)
std::set<const SMDS_MeshElement*>::iterator eit = edgesToCheck.begin();
for( ; eit != edgesToCheck.end(); eit++)
{
bool onside = true;
const SMDS_MeshElement* anEdge = *eit;
SMDS_ElemIteratorPtr nodeItr = anEdge->nodesIterator();
while ( nodeItr->more() )
{
const SMDS_MeshNode* aNode = cast2Node(nodeItr->next());
if (alreadyCheckedNodes.find(aNode) == alreadyCheckedNodes.end())
{
onside = false;
break;
}
}
if (onside)
{
MESSAGE(" --- edge onside inserted")
theAffectedElems.insert(anEdge);
}
}
}
else
{
const double aTol = Precision::Confusion(); const double aTol = Precision::Confusion();
auto_ptr< BRepClass3d_SolidClassifier> bsc3d; auto_ptr< BRepClass3d_SolidClassifier> bsc3d;
auto_ptr<_FaceClassifier> aFaceClassifier; auto_ptr<_FaceClassifier> aFaceClassifier;
@ -9926,21 +10025,24 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl
// iterates on indicated elements and get elements by back references from their nodes // iterates on indicated elements and get elements by back references from their nodes
TIDSortedElemSet::const_iterator elemItr = theElems.begin(); TIDSortedElemSet::const_iterator elemItr = theElems.begin();
int ielem = 1;
for ( ; elemItr != theElems.end(); ++elemItr ) for ( ; elemItr != theElems.end(); ++elemItr )
{ {
MESSAGE("element " << ielem++);
SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr; SMDS_MeshElement* anElem = (SMDS_MeshElement*)*elemItr;
if (!anElem) if (!anElem)
continue; continue;
SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator(); SMDS_ElemIteratorPtr nodeItr = anElem->nodesIterator();
while ( nodeItr->more() ) while ( nodeItr->more() )
{ {
MESSAGE(" noeud ");
const SMDS_MeshNode* aNode = cast2Node(nodeItr->next()); const SMDS_MeshNode* aNode = cast2Node(nodeItr->next());
if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() ) if ( !aNode || theNodesNot.find(aNode) != theNodesNot.end() )
continue; continue;
SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator(); SMDS_ElemIteratorPtr backElemItr = aNode->GetInverseElementIterator();
while ( backElemItr->more() ) while ( backElemItr->more() )
{ {
MESSAGE(" backelem ");
const SMDS_MeshElement* curElem = backElemItr->next(); const SMDS_MeshElement* curElem = backElemItr->next();
if ( curElem && theElems.find(curElem) == theElems.end() && if ( curElem && theElems.find(curElem) == theElems.end() &&
( bsc3d.get() ? ( bsc3d.get() ?
@ -9950,6 +10052,7 @@ bool SMESH_MeshEditor::AffectedElemGroupsInRegion( const TIDSortedElemSet& theEl
} }
} }
} }
}
return true; return true;
} }

View File

@ -909,6 +909,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
{ {
double r = Max( 0.5, 1 - tol*n->GetID()); // to get a unique u on edge double r = Max( 0.5, 1 - tol*n->GetID()); // to get a unique u on edge
u = f*r + l*(1-r); u = f*r + l*(1-r);
MESSAGE("curve.IsNull: " << u);
} }
} }
else else
@ -944,6 +945,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
} }
Quantity_Parameter U = projector->LowerDistanceParameter(); Quantity_Parameter U = projector->LowerDistanceParameter();
u = double( U ); u = double( U );
MESSAGE(" f " << f << " l " << l << " u " << u);
curvPnt = curve->Value( u ); curvPnt = curve->Value( u );
dist = nodePnt.Distance( curvPnt ); dist = nodePnt.Distance( curvPnt );
if ( distXYZ ) { if ( distXYZ ) {
@ -964,10 +966,12 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge& E,
} }
else if ( fabs( u ) > numeric_limits<double>::min() ) else if ( fabs( u ) > numeric_limits<double>::min() )
{ {
MESSAGE("fabs( u ) > numeric_limits<double>::min() ; u " << u << " f " << f << " l " << l);
setPosOnShapeValidity( shapeID, true ); setPosOnShapeValidity( shapeID, true );
} }
if (( u < f-tol || u > l+tol ) && force ) if (( u < f-tol || u > l+tol ) && force )
{ {
MESSAGE("u < f-tol || u > l+tol ; u " << u << " f " << f << " l " << l);
// node is on vertex but is set on periodic but trimmed edge (issue 0020890) // node is on vertex but is set on periodic but trimmed edge (issue 0020890)
try try
{ {

View File

@ -210,7 +210,7 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
void getElementsInSphere ( const gp_XYZ& center, void getElementsInSphere ( const gp_XYZ& center,
const double radius, TIDSortedElemSet& foundElems); const double radius, TIDSortedElemSet& foundElems);
size_t getSize() { return std::max( _size, _elements.size() ); } size_t getSize() { return std::max( _size, _elements.size() ); }
~ElementBndBoxTree(); virtual ~ElementBndBoxTree();
protected: protected:
ElementBndBoxTree():_size(0) {} ElementBndBoxTree():_size(0) {}
@ -410,6 +410,10 @@ namespace // Utils used in SMESH_ElementSearcherImpl::FindElementsByPoint()
*/ */
//======================================================================= //=======================================================================
SMESH_ElementSearcher::~SMESH_ElementSearcher()
{
}
struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
{ {
SMDS_Mesh* _mesh; SMDS_Mesh* _mesh;
@ -423,7 +427,7 @@ struct SMESH_ElementSearcherImpl: public SMESH_ElementSearcher
SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr()) SMESH_ElementSearcherImpl( SMDS_Mesh& mesh, SMDS_ElemIteratorPtr elemIt=SMDS_ElemIteratorPtr())
: _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {} : _mesh(&mesh),_meshPartIt(elemIt),_ebbTree(0),_nodeSearcher(0),_tolerance(-1),_outerFacesFound(false) {}
~SMESH_ElementSearcherImpl() virtual ~SMESH_ElementSearcherImpl()
{ {
if ( _ebbTree ) delete _ebbTree; _ebbTree = 0; if ( _ebbTree ) delete _ebbTree; _ebbTree = 0;
if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0; if ( _nodeSearcher ) delete _nodeSearcher; _nodeSearcher = 0;

View File

@ -87,6 +87,7 @@ struct SMESH_ElementSearcher
* \brief Find out if the given point is out of closed 2D mesh. * \brief Find out if the given point is out of closed 2D mesh.
*/ */
virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0; virtual TopAbs_State GetPointState(const gp_Pnt& point) = 0;
virtual ~SMESH_ElementSearcher();
}; };
namespace SMESH_MeshAlgos namespace SMESH_MeshAlgos

View File

@ -49,6 +49,7 @@ public:
// Constructor. limit must be provided at tree root construction. // Constructor. limit must be provided at tree root construction.
// limit will be deleted by SMESH_Octree // limit will be deleted by SMESH_Octree
SMESH_Octree (SMESH_TreeLimit* limit=0); SMESH_Octree (SMESH_TreeLimit* limit=0);
virtual ~SMESH_Octree() {};
// Compute the bigger dimension of my box // Compute the bigger dimension of my box
double maxSize() const; double maxSize() const;

View File

@ -219,6 +219,8 @@ void SMESH_Tree<BND_BOX,NB_CHILDREN>::buildChildren()
myChildren[i] = newChild(); myChildren[i] = newChild();
// and we assign to him its box. // and we assign to him its box.
myChildren[i]->myFather = this; myChildren[i]->myFather = this;
if (myChildren[i]->myLimit)
delete myChildren[i]->myLimit;
myChildren[i]->myLimit = myLimit; myChildren[i]->myLimit = myLimit;
myChildren[i]->myLevel = myLevel + 1; myChildren[i]->myLevel = myLevel + 1;
myChildren[i]->myBox = newChildBox( i ); myChildren[i]->myBox = newChildBox( i );

View File

@ -27,10 +27,9 @@ import salome
SMESH = None # SMESH module is loaded only when needed SMESH = None # SMESH module is loaded only when needed
from salome.kernel.studyedit import getStudyEditor from salome.kernel.studyedit import getStudyEditor
try: from salome.kernel.deprecation import is_called_by_sphinx
if not is_called_by_sphinx():
from salome.gui import helper from salome.gui import helper
except ImportError:
pass
class SMeshStudyTools: class SMeshStudyTools:
""" """

View File

@ -621,6 +621,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
{ {
if ( !_sourceHyp ) return false; if ( !_sourceHyp ) return false;
//MESSAGE("---------> StdMeshers_Import_1D::Compute");
const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups(/*loaded=*/true); const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups(/*loaded=*/true);
if ( srcGroups.empty() ) if ( srcGroups.empty() )
return error("Invalid source groups"); return error("Invalid source groups");
@ -650,9 +651,11 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
{ {
_gen->Compute(theMesh,v,/*anUpward=*/true); _gen->Compute(theMesh,v,/*anUpward=*/true);
n = SMESH_Algo::VertexNode( v, tgtMesh ); n = SMESH_Algo::VertexNode( v, tgtMesh );
//MESSAGE("_gen->Compute " << n);
if ( !n ) return false; // very strange if ( !n ) return false; // very strange
} }
vertexNodes.push_back( SMESH_TNodeXYZ( n )); vertexNodes.push_back( SMESH_TNodeXYZ( n ));
//MESSAGE("SMESH_Algo::VertexNode " << n->GetID() << " " << n->X() << " " << n->Y() << " " << n->Z() );
} }
// import edges from groups // import edges from groups
@ -670,17 +673,19 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
vector<const SMDS_MeshNode*> newNodes; vector<const SMDS_MeshNode*> newNodes;
SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0); SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
double u = 0; double u = 0.314159; // "random" value between 0 and 1, avoid 0 and 1, false detection possible on edge restrictions
while ( srcElems->more() ) // loop on group contents while ( srcElems->more() ) // loop on group contents
{ {
const SMDS_MeshElement* edge = srcElems->next(); const SMDS_MeshElement* edge = srcElems->next();
// find or create nodes of a new edge // find or create nodes of a new edge
newNodes.resize( edge->NbNodes() ); newNodes.resize( edge->NbNodes() );
//MESSAGE("edge->NbNodes " << edge->NbNodes());
newNodes.back() = 0; newNodes.back() = 0;
SMDS_MeshElement::iterator node = edge->begin_nodes(); SMDS_MeshElement::iterator node = edge->begin_nodes();
SMESH_TNodeXYZ a(edge->GetNode(0)); SMESH_TNodeXYZ a(edge->GetNode(0));
// --- define a tolerance relative to the length of an edge // --- define a tolerance relative to the length of an edge
double mytol = a.Distance(edge->GetNode(edge->NbNodes()-1))/25; double mytol = a.Distance(edge->GetNode(edge->NbNodes()-1))/25;
//mytol = max(1.E-5, 10*edgeTol); // too strict and not necessary
//MESSAGE("mytol = " << mytol); //MESSAGE("mytol = " << mytol);
for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
{ {
@ -697,22 +702,26 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
if ( vNIt->SquareDistance( *node ) < checktol) if ( vNIt->SquareDistance( *node ) < checktol)
{ {
//MESSAGE("SquareDistance " << vNIt->SquareDistance( *node ) << " checktol " << checktol); //MESSAGE("SquareDistance " << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<<vNIt->X()<<" "<<vNIt->Y()<<" "<<vNIt->Z());
(*n2nIt).second = vNIt->_node; (*n2nIt).second = vNIt->_node;
vertexNodes.erase( vNIt ); vertexNodes.erase( vNIt );
break; break;
} }
else if ( vNIt->SquareDistance( *node ) < 10*checktol)
MESSAGE("SquareDistance missed" << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<<vNIt->X()<<" "<<vNIt->Y()<<" "<<vNIt->Z());
} }
if ( !n2nIt->second ) if ( !n2nIt->second )
{ {
// find out if node lies on theShape // find out if node lies on theShape
//double dxyz[4];
tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z()); tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
if ( helper.CheckNodeU( geomEdge, tmpNode, u, mytol, /*force=*/true )) if ( helper.CheckNodeU( geomEdge, tmpNode, u, mytol, /*force=*/true)) // , dxyz )) // dxyz used for debug purposes
{ {
SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z()); SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
n2nIt->second = newNode; n2nIt->second = newNode;
tgtMesh->SetNodeOnEdge( newNode, shapeID, u ); tgtMesh->SetNodeOnEdge( newNode, shapeID, u );
//MESSAGE("u=" << u); //MESSAGE("u=" << u << " " << newNode->X()<< " " << newNode->Y()<< " " << newNode->Z());
//MESSAGE("d=" << dxyz[0] << " " << dxyz[1] << " " << dxyz[2] << " " << dxyz[3]);
} }
} }
if ( !(newNodes[i] = n2nIt->second )) if ( !(newNodes[i] = n2nIt->second ))
@ -730,7 +739,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th
newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
else else
newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]); newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
//MESSAGE("add Edge"); //MESSAGE("add Edge " << newNodes[0]->GetID() << " " << newNodes[1]->GetID());
tgtMesh->SetMeshElementOnShape( newEdge, shapeID ); tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
e2e->insert( make_pair( edge, newEdge )); e2e->insert( make_pair( edge, newEdge ));
} }