X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Import_1D.cxx;h=179dd52e4d616167a0a02553902c51f5ead293ff;hb=951dd4234ec84d147b1756bc04b6464c5332091c;hp=760a14a8ca40c3aee99531e032f4110e0dc07c63;hpb=88b3dbe23b236bd1746405155ae33a76aaf59ecd;p=modules%2Fsmesh.git diff --git a/src/StdMeshers/StdMeshers_Import_1D.cxx b/src/StdMeshers/StdMeshers_Import_1D.cxx index 760a14a8c..179dd52e4 100644 --- a/src/StdMeshers/StdMeshers_Import_1D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2020 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -6,7 +6,7 @@ // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 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 @@ -20,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions +// SMESH SMESH : implementation of SMESH idl descriptions // File : StdMeshers_Import_1D.cxx // Module : SMESH // @@ -36,6 +36,7 @@ #include "SMESH_Group.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_MeshEditor.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" @@ -60,57 +61,15 @@ using namespace std; */ //============================================================================= -StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen) - :SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0) +StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, SMESH_Gen * gen) + :SMESH_1D_Algo(hypId, gen), _sourceHyp(0) { - MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D"); _name = "Import_1D"; _shapeType = (1 << TopAbs_EDGE); _compatibleHypothesis.push_back("ImportSource1D"); } -//============================================================================= -/*! - * Check presence of a hypothesis - */ -//============================================================================= - -bool StdMeshers_Import_1D::CheckHypothesis - (SMESH_Mesh& aMesh, - const TopoDS_Shape& aShape, - SMESH_Hypothesis::Hypothesis_Status& aStatus) -{ - _sourceHyp = 0; - - const list &hyps = GetUsedHypothesis(aMesh, aShape); - if ( hyps.size() == 0 ) - { - aStatus = SMESH_Hypothesis::HYP_MISSING; - return false; // can't work with no hypothesis - } - - if ( hyps.size() > 1 ) - { - aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; - return false; - } - - const SMESHDS_Hypothesis *theHyp = hyps.front(); - - string hypName = theHyp->GetName(); - - if (hypName == _compatibleHypothesis.front()) - { - _sourceHyp = (StdMeshers_ImportSource1D *)theHyp; - aStatus = SMESH_Hypothesis::HYP_OK; - return true; - } - - aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; - return true; -} - //================================================================================ namespace // INTERNAL STUFF //================================================================================ @@ -182,10 +141,11 @@ namespace // INTERNAL STUFF if ( !_importMeshSubDS ) return; SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements(); while ( eIt->more() ) - meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, /*fromGroups=*/false ); + meshDS->RemoveFreeElement( eIt->next(), 0, /*fromGroups=*/false ); SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes(); while ( nIt->more() ) - meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, /*fromGroups=*/false ); + meshDS->RemoveFreeNode( nIt->next(), 0, /*fromGroups=*/false ); + _importMeshSubDS->Clear(); _n2n.clear(); _e2e.clear(); } @@ -226,6 +186,8 @@ namespace // INTERNAL STUFF switch ( sm->GetSubShape().ShapeType() ) { case TopAbs_EDGE: + if ( SMESH_Algo::isDegenerated( TopoDS::Edge( sm->GetSubShape() ))) + continue; case TopAbs_FACE: _subM.insert( sm ); if ( !sm->IsEmpty() ) @@ -250,7 +212,7 @@ namespace // INTERNAL STUFF "StdMeshers_Import_1D::_Listener") {} public: - // return poiter to a static listener + // return pointer to a static listener static _Listener* get() { static _Listener theListener; return &theListener; } static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh); @@ -266,6 +228,7 @@ namespace // INTERNAL STUFF const SMESH_Hypothesis* hyp); void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data ); void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub ); + void clearN2N ( SMESH_Mesh* tgtMesh ); // mark sm as missing src hyp with valid groups static void waitHypModification(SMESH_subMesh* sm) @@ -327,7 +290,7 @@ namespace // INTERNAL STUFF //-------------------------------------------------------------------------------- /*! * \brief Remove imported mesh and/or groups if needed - * \param sm - submesh loosing Import algo + * \param sm - submesh losing Import algo * \param data - data holding imported groups */ void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data ) @@ -342,11 +305,23 @@ namespace // INTERNAL STUFF bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh; if ( rmMesh ) d->removeImportedMesh( sm->GetFather()->GetMeshDS() ); - if ( rmGroups && data ) + if ( rmGroups && data && data->myType == SRC_HYP ) d->removeGroups( sm, data->_srcHyp ); } } //-------------------------------------------------------------------------------- + /*! + * \brief Clear _ImportData::_n2n. + * _n2n is useful within one mesh.Compute() only + */ + void _Listener::clearN2N( SMESH_Mesh* tgtMesh ) + { + list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh]; + list< _ImportData >::iterator d = dList.begin(); + for ( ; d != dList.end(); ++d ) + d->_n2n.clear(); + } + //-------------------------------------------------------------------------------- /*! * \brief Clear submeshes and remove imported mesh and/or groups if necessary * \param sm - cleared submesh @@ -367,7 +342,7 @@ namespace // INTERNAL STUFF // remove imported mesh and groups d->removeImportedMesh( sm->GetFather()->GetMeshDS() ); - if ( data ) + if ( data && data->myType == SRC_HYP ) d->removeGroups( sm, data->_srcHyp ); // clear the rest submeshes @@ -379,7 +354,7 @@ namespace // INTERNAL STUFF { SMESH_subMesh* subM = *sub; _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() ); - if ( hypData ) + if ( hypData && hypData->myType == SRC_HYP ) d->removeGroups( sm, hypData->_srcHyp ); subM->ComputeStateEngine( SMESH_subMesh::CLEAN ); @@ -392,7 +367,7 @@ namespace // INTERNAL STUFF if ( sm->GetSubShape().ShapeType() == TopAbs_FACE ) sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN ); } - if ( data ) + if ( data && data->myType == SRC_HYP ) d->trackHypParams( sm, data->_srcHyp ); d->_n2n.clear(); d->_e2e.clear(); @@ -448,6 +423,8 @@ namespace // INTERNAL STUFF default:; } } + if ( !data->mySubMeshes.empty() ) + clearN2N( data->mySubMeshes.front()->GetFather() ); } else // event of Import submesh { @@ -496,6 +473,10 @@ namespace // INTERNAL STUFF d->_computedSubM.insert( *smIt); } } + // Clear _ImportData::_n2n if it's no more useful, i.e. when + // the event is not within mesh.Compute() + if ( SMESH_subMesh::ALGO_EVENT == eventType ) + clearN2N( subMesh->GetFather() ); } } @@ -547,7 +528,8 @@ namespace // INTERNAL STUFF aBuilder.MakeCompound( comp ); shapeForSrcMesh = comp; for ( int iSub = 0; iSub < nbSubShapes; ++iSub ) - aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub )); + if ( subIndex+iSub <= pseudoSubShapes.Extent() ) + aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub )); TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX ); aBuilder.Add( comp, vExp.Current() ); } @@ -610,6 +592,48 @@ namespace // INTERNAL STUFF } // namespace +//============================================================================= +/*! + * Check presence of a hypothesis + */ +//============================================================================= + +bool StdMeshers_Import_1D::CheckHypothesis + (SMESH_Mesh& aMesh, + const TopoDS_Shape& aShape, + SMESH_Hypothesis::Hypothesis_Status& aStatus) +{ + _sourceHyp = 0; + + const list &hyps = GetUsedHypothesis(aMesh, aShape); + if ( hyps.size() == 0 ) + { + aStatus = SMESH_Hypothesis::HYP_MISSING; + return false; // can't work with no hypothesis + } + + if ( hyps.size() > 1 ) + { + aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST; + return false; + } + + const SMESHDS_Hypothesis *theHyp = hyps.front(); + + string hypName = theHyp->GetName(); + + if (hypName == _compatibleHypothesis.front()) + { + _sourceHyp = (StdMeshers_ImportSource1D *)theHyp; + aStatus = _sourceHyp->GetGroups().empty() ? HYP_BAD_PARAMETER : HYP_OK; + if ( aStatus == HYP_BAD_PARAMETER ) + _Listener::waitHypModification( aMesh.GetSubMesh( aShape )); + return aStatus == HYP_OK; + } + + aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE; + return false; +} //============================================================================= /*! @@ -621,7 +645,8 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th { if ( !_sourceHyp ) return false; - const vector& srcGroups = _sourceHyp->GetGroups(); + //MESSAGE("---------> StdMeshers_Import_1D::Compute"); + const vector& srcGroups = _sourceHyp->GetGroups(/*loaded=*/true); if ( srcGroups.empty() ) return error("Invalid source groups"); @@ -650,15 +675,17 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th { _gen->Compute(theMesh,v,/*anUpward=*/true); n = SMESH_Algo::VertexNode( v, tgtMesh ); + //MESSAGE("_gen->Compute " << n); if ( !n ) return false; // very strange } vertexNodes.push_back( SMESH_TNodeXYZ( n )); + //MESSAGE("SMESH_Algo::VertexNode " << n->GetID() << " " << n->X() << " " << n->Y() << " " << n->Z() ); } // import edges from groups TNodeNodeMap* n2n; TElemElemMap* e2e; - for ( int iG = 0; iG < srcGroups.size(); ++iG ) + for ( size_t iG = 0; iG < srcGroups.size(); ++iG ) { const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); @@ -670,19 +697,21 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); vector newNodes; 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 { const SMDS_MeshElement* edge = srcElems->next(); // find or create nodes of a new edge newNodes.resize( edge->NbNodes() ); + //MESSAGE("edge->NbNodes " << edge->NbNodes()); newNodes.back() = 0; SMDS_MeshElement::iterator node = edge->begin_nodes(); SMESH_TNodeXYZ a(edge->GetNode(0)); // --- define a tolerance relative to the length of an edge 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); - for ( unsigned i = 0; i < newNodes.size(); ++i, ++node ) + for ( size_t i = 0; i < newNodes.size(); ++i, ++node ) { TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first; if ( n2nIt->second ) @@ -693,30 +722,40 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th else { // find an existing vertex node + double checktol = max(1.E-10, 10*edgeTol*edgeTol); for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt) - if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol) + if ( vNIt->SquareDistance( *node ) < checktol) { + //MESSAGE("SquareDistance " << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<X()<<" "<Y()<<" "<Z()); (*n2nIt).second = vNIt->_node; vertexNodes.erase( vNIt ); break; } + else if ( vNIt->SquareDistance( *node ) < 10*checktol) + MESSAGE("SquareDistance missed" << vNIt->SquareDistance( *node ) << " checktol " << checktol <<" "<X()<<" "<Y()<<" "<Z()); } if ( !n2nIt->second ) { // find out if node lies on theShape + //double dxyz[4]; 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()); n2nIt->second = newNode; tgtMesh->SetNodeOnEdge( newNode, shapeID, 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 )) break; } if ( !newNodes.back() ) + { + //MESSAGE("not all nodes of edge lie on theShape"); continue; // not all nodes of edge lie on theShape + } // make a new edge SMDS_MeshElement * newEdge; @@ -724,6 +763,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] ); else newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]); + //MESSAGE("add Edge " << newNodes[0]->GetID() << " " << newNodes[1]->GetID()); tgtMesh->SetMeshElementOnShape( newEdge, shapeID ); e2e->insert( make_pair( edge, newEdge )); } @@ -770,7 +810,7 @@ bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & th // copy meshes vector srcMeshes = _sourceHyp->GetSourceMeshes(); - for ( unsigned i = 0; i < srcMeshes.size(); ++i ) + for ( size_t i = 0; i < srcMeshes.size(); ++i ) importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape ); return true; @@ -801,6 +841,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh, // 1. Copy mesh + SMESH_MeshEditor::ElemFeatures elemType; vector newNodes; const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS(); SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator(); @@ -825,14 +866,14 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh, tgtMeshDS->FindElement( newNodes, elem->GetType(), /*noMedium=*/false ); if ( !newElem ) { - newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly()); + newElem = additor.AddElement( newNodes, elemType.Init( elem, /*basicOnly=*/false )); tgtSubMesh->AddElement( newElem ); } if ( toCopyGroups ) (*e2eIt).second = newElem; } // copy free nodes - if ( srcMeshDS->NbNodes() > n2n->size() ) + if ( srcMeshDS->NbNodes() > (int) n2n->size() ) { SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator(); while( nIt->more() ) @@ -871,7 +912,7 @@ void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh, int nb = 1; while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second ) name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++; - SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb ); + SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str() ); SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS(); resultGroups.push_back( newGroup ); @@ -987,7 +1028,7 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh, // count edges imported from groups int nbEdges = 0, nbQuadEdges = 0; - for ( int iG = 0; iG < srcGroups.size(); ++iG ) + for ( size_t iG = 0; iG < srcGroups.size(); ++iG ) { const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS(); SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); @@ -1016,7 +1057,7 @@ bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh, } SMESH_subMesh * sm = theMesh.GetSubMesh(theShape); - aResMap.insert(make_pair(sm,aVec)); + aResMap.insert( make_pair( sm, aVec )); return true; } @@ -1037,7 +1078,7 @@ void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh, e2e = &iData->_e2e; if ( iData->_copyMeshSubM.empty() ) { - n2n->clear(); + // n2n->clear(); -- for sharing nodes on EDGEs e2e->clear(); } }