00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "StdMeshers_Import_1D.hxx"
00028 #include "StdMeshers_ImportSource.hxx"
00029
00030 #include "SMDS_MeshElement.hxx"
00031 #include "SMDS_MeshNode.hxx"
00032 #include "SMESHDS_Group.hxx"
00033 #include "SMESHDS_Mesh.hxx"
00034 #include "SMESH_Comment.hxx"
00035 #include "SMESH_Gen.hxx"
00036 #include "SMESH_Group.hxx"
00037 #include "SMESH_HypoFilter.hxx"
00038 #include "SMESH_Mesh.hxx"
00039 #include "SMESH_MesherHelper.hxx"
00040 #include "SMESH_subMesh.hxx"
00041 #include "SMESH_subMeshEventListener.hxx"
00042
00043 #include "Utils_SALOME_Exception.hxx"
00044 #include "utilities.h"
00045
00046 #include <BRep_Builder.hxx>
00047 #include <BRep_Tool.hxx>
00048 #include <TopExp.hxx>
00049 #include <TopExp_Explorer.hxx>
00050 #include <TopoDS.hxx>
00051 #include <TopoDS_Compound.hxx>
00052 #include <TopoDS_Edge.hxx>
00053 #include <TopoDS_Vertex.hxx>
00054
00055 using namespace std;
00056
00057
00061
00062
00063 StdMeshers_Import_1D::StdMeshers_Import_1D(int hypId, int studyId, SMESH_Gen * gen)
00064 :SMESH_1D_Algo(hypId, studyId, gen), _sourceHyp(0)
00065 {
00066 MESSAGE("StdMeshers_Import_1D::StdMeshers_Import_1D");
00067 _name = "Import_1D";
00068 _shapeType = (1 << TopAbs_EDGE);
00069
00070 _compatibleHypothesis.push_back("ImportSource1D");
00071 }
00072
00073
00077
00078
00079 bool StdMeshers_Import_1D::CheckHypothesis
00080 (SMESH_Mesh& aMesh,
00081 const TopoDS_Shape& aShape,
00082 SMESH_Hypothesis::Hypothesis_Status& aStatus)
00083 {
00084 _sourceHyp = 0;
00085
00086 const list <const SMESHDS_Hypothesis * >&hyps = GetUsedHypothesis(aMesh, aShape);
00087 if ( hyps.size() == 0 )
00088 {
00089 aStatus = SMESH_Hypothesis::HYP_MISSING;
00090 return false;
00091 }
00092
00093 if ( hyps.size() > 1 )
00094 {
00095 aStatus = SMESH_Hypothesis::HYP_ALREADY_EXIST;
00096 return false;
00097 }
00098
00099 const SMESHDS_Hypothesis *theHyp = hyps.front();
00100
00101 string hypName = theHyp->GetName();
00102
00103 if (hypName == _compatibleHypothesis.front())
00104 {
00105 _sourceHyp = (StdMeshers_ImportSource1D *)theHyp;
00106 aStatus = SMESH_Hypothesis::HYP_OK;
00107 return true;
00108 }
00109
00110 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
00111 return true;
00112 }
00113
00114
00115 namespace
00116
00117 {
00118 int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS, SMESH_Mesh* tgtMesh);
00119
00120 enum _ListenerDataType
00121 {
00122 WAIT_HYP_MODIF=1,
00123 LISTEN_SRC_MESH,
00124 SRC_HYP
00125 };
00126
00131 struct _ListenerData : public SMESH_subMeshEventListenerData
00132 {
00133 const StdMeshers_ImportSource1D* _srcHyp;
00134 _ListenerData(const StdMeshers_ImportSource1D* h, _ListenerDataType type=SRC_HYP):
00135 SMESH_subMeshEventListenerData(true), _srcHyp(h)
00136 {
00137 myType = type;
00138 }
00139 };
00140
00144 struct _SubLess
00145 {
00146 bool operator()(const SMESH_subMesh* sm1, const SMESH_subMesh* sm2 ) const
00147 {
00148 if ( sm1 == sm2 ) return false;
00149 if ( !sm1 || !sm2 ) return sm1 < sm2;
00150 const TopoDS_Shape& s1 = sm1->GetSubShape();
00151 const TopoDS_Shape& s2 = sm2->GetSubShape();
00152 TopAbs_ShapeEnum t1 = s1.IsNull() ? TopAbs_SHAPE : s1.ShapeType();
00153 TopAbs_ShapeEnum t2 = s2.IsNull() ? TopAbs_SHAPE : s2.ShapeType();
00154 if ( t1 == t2)
00155 return (sm1 < sm2);
00156 return t1 < t2;
00157 }
00158 };
00159
00163 struct _ImportData
00164 {
00165 const SMESH_Mesh* _srcMesh;
00166 StdMeshers_Import_1D::TNodeNodeMap _n2n;
00167 StdMeshers_Import_1D::TElemElemMap _e2e;
00168
00169 set< SMESH_subMesh*, _SubLess > _subM;
00170 set< SMESH_subMesh*, _SubLess > _copyMeshSubM;
00171 set< SMESH_subMesh*, _SubLess > _copyGroupSubM;
00172 set< SMESH_subMesh*, _SubLess > _computedSubM;
00173
00174 SMESHDS_SubMesh* _importMeshSubDS;
00175 int _importMeshSubID;
00176
00177 _ImportData(const SMESH_Mesh* srcMesh=0):
00178 _srcMesh(srcMesh), _importMeshSubDS(0),_importMeshSubID(-1) {}
00179
00180 void removeImportedMesh( SMESHDS_Mesh* meshDS )
00181 {
00182 if ( !_importMeshSubDS ) return;
00183 SMDS_ElemIteratorPtr eIt = _importMeshSubDS->GetElements();
00184 while ( eIt->more() )
00185 meshDS->RemoveFreeElement( eIt->next(), _importMeshSubDS, false );
00186 SMDS_NodeIteratorPtr nIt = _importMeshSubDS->GetNodes();
00187 while ( nIt->more() )
00188 meshDS->RemoveFreeNode( nIt->next(), _importMeshSubDS, false );
00189 _n2n.clear();
00190 _e2e.clear();
00191 }
00192 void removeGroups( SMESH_subMesh* subM, const StdMeshers_ImportSource1D* srcHyp )
00193 {
00194 if ( !srcHyp ) return;
00195 SMESH_Mesh* tgtMesh = subM->GetFather();
00196 const SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
00197 const SMESHDS_Mesh* srcMeshDS = _srcMesh->GetMeshDS();
00198 vector<SMESH_Group*>* groups =
00199 const_cast<StdMeshers_ImportSource1D*>(srcHyp)->GetResultGroups(*srcMeshDS,*tgtMeshDS);
00200 if ( groups )
00201 {
00202 for ( unsigned i = 0; i < groups->size(); ++i )
00203 tgtMesh->RemoveGroup( groups->at(i)->GetGroupDS()->GetID() );
00204 groups->clear();
00205 }
00206 }
00207 void trackHypParams( SMESH_subMesh* sm, const StdMeshers_ImportSource1D* srcHyp )
00208 {
00209 if ( !srcHyp ) return;
00210 bool toCopyMesh, toCopyGroups;
00211 srcHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
00212
00213 if ( toCopyMesh )_copyMeshSubM.insert( sm );
00214 else _copyMeshSubM.erase( sm );
00215
00216 if ( toCopyGroups ) _copyGroupSubM.insert( sm );
00217 else _copyGroupSubM.erase( sm );
00218 }
00219 void addComputed( SMESH_subMesh* sm )
00220 {
00221 SMESH_subMeshIteratorPtr smIt = sm->getDependsOnIterator(true,
00222 true);
00223 while ( smIt->more() )
00224 {
00225 sm = smIt->next();
00226 switch ( sm->GetSubShape().ShapeType() )
00227 {
00228 case TopAbs_EDGE:
00229 case TopAbs_FACE:
00230 _subM.insert( sm );
00231 if ( !sm->IsEmpty() )
00232 _computedSubM.insert( sm );
00233 case TopAbs_VERTEX:
00234 break;
00235 default:;
00236 }
00237 }
00238 }
00239 };
00240
00244 class _Listener : public SMESH_subMeshEventListener
00245 {
00246 typedef map< SMESH_Mesh*, list< _ImportData > > TMesh2ImpData;
00247 TMesh2ImpData _tgtMesh2ImportData;
00248
00249 _Listener():SMESH_subMeshEventListener(false){}
00250
00251 public:
00252
00253 static _Listener* get() { static _Listener theListener; return &theListener; }
00254
00255 static _ImportData* getImportData(const SMESH_Mesh* srcMesh, SMESH_Mesh* tgtMesh);
00256
00257 static void storeImportSubmesh(SMESH_subMesh* importSub,
00258 const SMESH_Mesh* srcMesh,
00259 const StdMeshers_ImportSource1D* srcHyp);
00260
00261 virtual void ProcessEvent(const int event,
00262 const int eventType,
00263 SMESH_subMesh* subMesh,
00264 SMESH_subMeshEventListenerData* data,
00265 const SMESH_Hypothesis* hyp);
00266 void removeSubmesh( SMESH_subMesh* sm, _ListenerData* data );
00267 void clearSubmesh ( SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub );
00268
00269
00270 static void waitHypModification(SMESH_subMesh* sm)
00271 {
00272 sm->SetEventListener
00273 (get(), SMESH_subMeshEventListenerData::MakeData( sm, WAIT_HYP_MODIF ), sm);
00274 }
00275 };
00276
00280 _ImportData* _Listener::getImportData(const SMESH_Mesh* srcMesh,
00281 SMESH_Mesh* tgtMesh)
00282 {
00283 list< _ImportData >& dList = get()->_tgtMesh2ImportData[tgtMesh];
00284 list< _ImportData >::iterator d = dList.begin();
00285 for ( ; d != dList.end(); ++d )
00286 if ( d->_srcMesh == srcMesh )
00287 return &*d;
00288 dList.push_back(_ImportData(srcMesh));
00289 return &dList.back();
00290 }
00291
00292
00299 void _Listener::storeImportSubmesh(SMESH_subMesh* importSub,
00300 const SMESH_Mesh* srcMesh,
00301 const StdMeshers_ImportSource1D* srcHyp)
00302 {
00303
00304 importSub->SetEventListener( get(), new _ListenerData(srcHyp), importSub );
00305
00306
00307 SMESH_subMesh* smToNotify = importSub;
00308 SMESH_subMesh* smToListen = srcMesh->GetSubMeshContaining(1);
00309 SMESH_subMeshEventListenerData* data = new _ListenerData(srcHyp, LISTEN_SRC_MESH);
00310 data->mySubMeshes.push_back( smToNotify );
00311 importSub->SetEventListener( get(), data, smToListen );
00312
00313
00314 _ImportData* iData = _Listener::getImportData( srcMesh, importSub->GetFather());
00315 iData->trackHypParams( importSub, srcHyp );
00316 iData->addComputed( importSub );
00317 if ( !iData->_copyMeshSubM.empty() && iData->_importMeshSubID < 1 )
00318 {
00319 SMESH_Mesh* tgtMesh = importSub->GetFather();
00320 iData->_importMeshSubID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(),tgtMesh);
00321 iData->_importMeshSubDS = tgtMesh->GetMeshDS()->NewSubMesh( iData->_importMeshSubID );
00322 }
00323 }
00324
00330 void _Listener::removeSubmesh( SMESH_subMesh* sm, _ListenerData* data )
00331 {
00332 list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
00333 list< _ImportData >::iterator d = dList.begin();
00334 for ( ; d != dList.end(); ++d )
00335 if ( (*d)._subM.erase( sm ))
00336 {
00337 d->_computedSubM.erase( sm );
00338 bool rmMesh = d->_copyMeshSubM.erase( sm ) && d->_copyMeshSubM.empty();
00339 bool rmGroups = (d->_copyGroupSubM.erase( sm ) && d->_copyGroupSubM.empty()) || rmMesh;
00340 if ( rmMesh )
00341 d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
00342 if ( rmGroups && data )
00343 d->removeGroups( sm, data->_srcHyp );
00344 }
00345 }
00346
00352 void _Listener::clearSubmesh(SMESH_subMesh* sm, _ListenerData* data, bool clearAllSub)
00353 {
00354 list< _ImportData > & dList = _tgtMesh2ImportData[ sm->GetFather() ];
00355 list< _ImportData >::iterator d = dList.begin();
00356 for ( ; d != dList.end(); ++d )
00357 {
00358 if ( !d->_subM.count( sm )) continue;
00359 if ( (*d)._computedSubM.erase( sm ) )
00360 {
00361 bool copyMesh = !d->_copyMeshSubM.empty();
00362 if ( copyMesh || clearAllSub )
00363 {
00364
00365 d->removeImportedMesh( sm->GetFather()->GetMeshDS() );
00366
00367 if ( data )
00368 d->removeGroups( sm, data->_srcHyp );
00369
00370
00371 if ( !d->_computedSubM.empty() )
00372 {
00373 set< SMESH_subMesh*, _SubLess> subs;
00374 subs.swap( d->_computedSubM );
00375 while ( !subs.empty() )
00376 {
00377 SMESH_subMesh* subM = *subs.begin(); subs.erase( subs.begin() );
00378 _ListenerData* hypData = (_ListenerData*) subM->GetEventListenerData( get() );
00379 if ( hypData )
00380 d->removeGroups( sm, hypData->_srcHyp );
00381
00382 subM->ComputeStateEngine( SMESH_subMesh::CLEAN );
00383 if ( subM->GetSubShape().ShapeType() == TopAbs_FACE )
00384 subM->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
00385 }
00386 }
00387 }
00388 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
00389 if ( sm->GetSubShape().ShapeType() == TopAbs_FACE )
00390 sm->ComputeSubMeshStateEngine( SMESH_subMesh::CLEAN );
00391 }
00392 if ( data )
00393 d->trackHypParams( sm, data->_srcHyp );
00394 d->_n2n.clear();
00395 d->_e2e.clear();
00396 }
00397 }
00398
00402 void _Listener::ProcessEvent(const int event,
00403 const int eventType,
00404 SMESH_subMesh* subMesh,
00405 SMESH_subMeshEventListenerData* data,
00406 const SMESH_Hypothesis* )
00407 {
00408 if ( data && data->myType == WAIT_HYP_MODIF )
00409 {
00410
00411 if ( SMESH_subMesh::MODIF_HYP == event &&
00412 SMESH_subMesh::ALGO_EVENT == eventType )
00413 {
00414
00415
00416 SMESH_Gen* gen = subMesh->GetFather()->GetGen();
00417 if ( SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(), subMesh->GetSubShape()))
00418 algo->SetEventListener( subMesh );
00419 }
00420 }
00421 else if ( data && data->myType == LISTEN_SRC_MESH )
00422 {
00423
00424 if ( SMESH_subMesh::COMPUTE_EVENT == eventType )
00425 {
00426 switch ( event ) {
00427 case SMESH_subMesh::CLEAN:
00428
00429 clearSubmesh( data->mySubMeshes.front(), (_ListenerData*) data, true );
00430 break;
00431 case SMESH_subMesh::SUBMESH_COMPUTED: {
00432
00433
00434 SMESH_Mesh* srcMesh = subMesh->GetFather();
00435 if ( srcMesh->NbEdges() > 0 || srcMesh->NbFaces() > 0 )
00436 {
00437 SMESH_Mesh* m = data->mySubMeshes.front()->GetFather();
00438 if ( SMESH_subMesh* sm1 = m->GetSubMeshContaining(1))
00439 {
00440 sm1->ComputeStateEngine(SMESH_subMesh::SUBMESH_COMPUTED );
00441 sm1->ComputeSubMeshStateEngine( SMESH_subMesh::SUBMESH_COMPUTED );
00442 }
00443 }
00444 break;
00445 }
00446 default:;
00447 }
00448 }
00449 }
00450 else
00451 {
00452
00453 bool removeImport = false, modifHyp = false;
00454 if ( SMESH_subMesh::ALGO_EVENT == eventType )
00455 modifHyp = true;
00456 if ( subMesh->GetAlgoState() != SMESH_subMesh::HYP_OK )
00457 {
00458 removeImport = true;
00459 }
00460 else if ( SMESH_subMesh::REMOVE_ALGO == event ||
00461 SMESH_subMesh::REMOVE_FATHER_ALGO == event )
00462 {
00463 SMESH_Gen* gen = subMesh->GetFather()->GetGen();
00464 SMESH_Algo* algo = gen->GetAlgo(*subMesh->GetFather(),subMesh->GetSubShape() );
00465 removeImport = ( strncmp( "Import", algo->GetName(), 6 ) != 0 );
00466 }
00467
00468 if ( removeImport )
00469 {
00470
00471 removeSubmesh( subMesh, (_ListenerData*) data );
00472 }
00473 else if ( modifHyp )
00474 {
00475
00476 clearSubmesh( subMesh, (_ListenerData*) data, false );
00477 }
00478 else if ( SMESH_subMesh::CHECK_COMPUTE_STATE == event &&
00479 SMESH_subMesh::COMPUTE_EVENT == eventType )
00480 {
00481
00482
00483
00484 list< _ImportData > & dList = _tgtMesh2ImportData[ subMesh->GetFather() ];
00485 list< _ImportData >::iterator d = dList.begin();
00486 for ( ; d != dList.end(); ++d )
00487 if ( d->_subM.count( subMesh ))
00488 {
00489 set<SMESH_subMesh*>::iterator smIt = d->_subM.begin();
00490 for( ; smIt != d->_subM.end(); ++smIt )
00491 if ( (*smIt)->IsMeshComputed() )
00492 d->_computedSubM.insert( *smIt);
00493 }
00494 }
00495 }
00496 }
00497
00498
00502
00503
00504 int getSubmeshIDForCopiedMesh(const SMESHDS_Mesh* srcMeshDS,
00505 SMESH_Mesh* tgtMesh)
00506 {
00507
00508
00509
00510
00511
00512
00513
00514
00515 TopoDS_Shape shapeForSrcMesh;
00516 TopTools_IndexedMapOfShape pseudoSubShapes;
00517 TopExp::MapShapes( SMESH_Mesh::PseudoShape(), pseudoSubShapes );
00518
00519
00520 int subIndex = srcMeshDS->GetPersistentId() % pseudoSubShapes.Extent();
00521 int nbSubShapes = 1 + srcMeshDS->GetPersistentId() / pseudoSubShapes.Extent();
00522
00523
00524 SMESHDS_Mesh* tgtMeshDS = tgtMesh->GetMeshDS();
00525 for ( int i = tgtMeshDS->MaxShapeIndex(); i > 0 && shapeForSrcMesh.IsNull(); --i )
00526 {
00527 const TopoDS_Shape& s = tgtMeshDS->IndexToShape(i);
00528 if ( s.ShapeType() != TopAbs_COMPOUND ) break;
00529 TopoDS_Iterator sSubIt( s );
00530 for ( int iSub = 0; iSub < nbSubShapes && sSubIt.More(); ++iSub, sSubIt.Next() )
00531 if ( pseudoSubShapes( subIndex+iSub ).IsSame( sSubIt.Value()))
00532 if ( iSub+1 == nbSubShapes )
00533 {
00534 shapeForSrcMesh = s;
00535 break;
00536 }
00537 }
00538 if ( shapeForSrcMesh.IsNull() )
00539 {
00540
00541 BRep_Builder aBuilder;
00542 TopoDS_Compound comp;
00543 aBuilder.MakeCompound( comp );
00544 shapeForSrcMesh = comp;
00545 for ( int iSub = 0; iSub < nbSubShapes; ++iSub )
00546 aBuilder.Add( comp, pseudoSubShapes( subIndex+iSub ));
00547 TopExp_Explorer vExp( tgtMeshDS->ShapeToMesh(), TopAbs_VERTEX );
00548 aBuilder.Add( comp, vExp.Current() );
00549 }
00550 SMESH_subMesh* sm = tgtMesh->GetSubMesh( shapeForSrcMesh );
00551 SMESHDS_SubMesh* smDS = sm->GetSubMeshDS();
00552 if ( !smDS )
00553 smDS = tgtMeshDS->NewSubMesh( sm->GetId() );
00554
00555
00556 if ( smDS->IsComplexSubmesh() )
00557 {
00558 list< const SMESHDS_SubMesh* > subSM;
00559 SMESHDS_SubMeshIteratorPtr smIt = smDS->GetSubMeshIterator();
00560 while ( smIt->more() ) subSM.push_back( smIt->next() );
00561 list< const SMESHDS_SubMesh* >::iterator sub = subSM.begin();
00562 for ( ; sub != subSM.end(); ++sub)
00563 smDS->RemoveSubMesh( *sub );
00564 }
00565 return sm->GetId();
00566 }
00567
00568
00574
00575
00576 SMESHDS_SubMesh* getSubmeshForCopiedMesh(const SMESH_Mesh* srcMesh,
00577 SMESH_Mesh* tgtMesh,
00578 const TopoDS_Shape& tgtShape,
00579 StdMeshers_Import_1D::TNodeNodeMap*& n2n,
00580 StdMeshers_Import_1D::TElemElemMap*& e2e,
00581 bool & toCopyGroups)
00582 {
00583 StdMeshers_Import_1D::getMaps( srcMesh, tgtMesh, n2n,e2e );
00584
00585 _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
00586
00587 SMESH_subMesh* importedSM = tgtMesh->GetSubMesh( tgtShape );
00588 iData->addComputed( importedSM );
00589 if ( iData->_computedSubM.size() != iData->_subM.size() )
00590 return 0;
00591
00592 toCopyGroups = !iData->_copyGroupSubM.empty();
00593
00594 if ( !iData->_copyMeshSubM.empty())
00595 {
00596
00597 int smID = getSubmeshIDForCopiedMesh( srcMesh->GetMeshDS(), tgtMesh );
00598 SMESHDS_SubMesh* subDS = tgtMesh->GetMeshDS()->NewSubMesh( smID );
00599
00600 iData->_importMeshSubID = smID;
00601 iData->_importMeshSubDS = subDS;
00602 return subDS;
00603 }
00604 return 0;
00605 }
00606
00607 }
00608
00609
00610
00614
00615
00616 bool StdMeshers_Import_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & theShape)
00617 {
00618 if ( !_sourceHyp ) return false;
00619
00620 const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
00621 if ( srcGroups.empty() )
00622 return error("Invalid source groups");
00623
00624 SMESH_MesherHelper helper(theMesh);
00625 helper.SetSubShape(theShape);
00626 SMESHDS_Mesh* tgtMesh = theMesh.GetMeshDS();
00627
00628 const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
00629 const double edgeTol = BRep_Tool::Tolerance( geomEdge );
00630 const int shapeID = tgtMesh->ShapeToIndex( geomEdge );
00631
00632 set<int> subShapeIDs;
00633 subShapeIDs.insert( shapeID );
00634
00635
00636 list < SMESH_TNodeXYZ > vertexNodes;
00637 list < SMESH_TNodeXYZ >::iterator vNIt;
00638 TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
00639 for ( ; vExp.More(); vExp.Next() )
00640 {
00641 const TopoDS_Vertex& v = TopoDS::Vertex( vExp.Current() );
00642 if ( !subShapeIDs.insert( tgtMesh->ShapeToIndex( v )).second )
00643 continue;
00644 const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
00645 if ( !n )
00646 {
00647 _gen->Compute(theMesh,v,true);
00648 n = SMESH_Algo::VertexNode( v, tgtMesh );
00649 if ( !n ) return false;
00650 }
00651 vertexNodes.push_back( SMESH_TNodeXYZ( n ));
00652 }
00653
00654
00655 TNodeNodeMap* n2n;
00656 TElemElemMap* e2e;
00657 for ( int iG = 0; iG < srcGroups.size(); ++iG )
00658 {
00659 const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
00660
00661 const int meshID = srcGroup->GetMesh()->GetPersistentId();
00662 const SMESH_Mesh* srcMesh = GetMeshByPersistentID( meshID );
00663 if ( !srcMesh ) continue;
00664 getMaps( srcMesh, &theMesh, n2n, e2e );
00665
00666 SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
00667 vector<const SMDS_MeshNode*> newNodes;
00668 SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
00669 double u;
00670 while ( srcElems->more() )
00671 {
00672 const SMDS_MeshElement* edge = srcElems->next();
00673
00674 newNodes.resize( edge->NbNodes() );
00675 newNodes.back() = 0;
00676 SMDS_MeshElement::iterator node = edge->begin_nodes();
00677 for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
00678 {
00679 TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
00680 if ( n2nIt->second )
00681 {
00682 if ( !subShapeIDs.count( n2nIt->second->getshapeId() ))
00683 break;
00684 }
00685 else
00686 {
00687
00688 for ( vNIt = vertexNodes.begin(); vNIt != vertexNodes.end(); ++vNIt)
00689 if ( vNIt->SquareDistance( *node ) < 10 * edgeTol * edgeTol)
00690 {
00691 (*n2nIt).second = vNIt->_node;
00692 vertexNodes.erase( vNIt );
00693 break;
00694 }
00695 }
00696 if ( !n2nIt->second )
00697 {
00698
00699 tmpNode->setXYZ( (*node)->X(), (*node)->Y(), (*node)->Z());
00700 if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, true ))
00701 {
00702 SMDS_MeshNode* newNode = tgtMesh->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
00703 n2nIt->second = newNode;
00704 tgtMesh->SetNodeOnEdge( newNode, shapeID, u );
00705 }
00706 }
00707 if ( !(newNodes[i] = n2nIt->second ))
00708 break;
00709 }
00710 if ( !newNodes.back() )
00711 continue;
00712
00713
00714 SMDS_MeshElement * newEdge;
00715 if ( newNodes.size() == 3 )
00716 newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1], newNodes[2] );
00717 else
00718 newEdge = tgtMesh->AddEdge( newNodes[0], newNodes[1]);
00719 tgtMesh->SetMeshElementOnShape( newEdge, shapeID );
00720 e2e->insert( make_pair( edge, newEdge ));
00721 }
00722 helper.GetMeshDS()->RemoveNode(tmpNode);
00723 }
00724 if ( n2n->empty())
00725 return error("Empty source groups");
00726
00727
00728
00729 bool isEdgeMeshed = false;
00730 if ( SMESHDS_SubMesh* tgtSM = tgtMesh->MeshElements( theShape ))
00731 {
00732 const TopoDS_Vertex& v = ( vExp.ReInit(), TopoDS::Vertex( vExp.Current() ));
00733 const SMDS_MeshNode* n = SMESH_Algo::VertexNode( v, tgtMesh );
00734 const SMDS_MeshElement* seg = 0;
00735 SMDS_ElemIteratorPtr segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
00736 while ( segIt->more() && !seg )
00737 if ( !tgtSM->Contains( seg = segIt->next()))
00738 seg = 0;
00739 int nbPassedSegs = 0;
00740 while ( seg )
00741 {
00742 ++nbPassedSegs;
00743 const SMDS_MeshNode* n2 = seg->GetNode(0);
00744 n = ( n2 == n ? seg->GetNode(1) : n2 );
00745 if ( n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX )
00746 break;
00747 const SMDS_MeshElement* seg2 = 0;
00748 segIt = n->GetInverseElementIterator(SMDSAbs_Edge);
00749 while ( segIt->more() && !seg2 )
00750 if ( seg == ( seg2 = segIt->next()))
00751 seg2 = 0;
00752 seg = seg2;
00753 }
00754 if (nbPassedSegs > 0 && tgtSM->NbElements() > nbPassedSegs )
00755 return error( "Source elements overlap one another");
00756
00757 isEdgeMeshed = ( tgtSM->NbElements() == nbPassedSegs &&
00758 n->GetPosition()->GetTypeOfPosition() == SMDS_TOP_VERTEX );
00759 }
00760 if ( !isEdgeMeshed )
00761 return error( "Source elements don't cover totally the geometrical edge" );
00762
00763
00764 vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
00765 for ( unsigned i = 0; i < srcMeshes.size(); ++i )
00766 importMesh( srcMeshes[i], theMesh, _sourceHyp, theShape );
00767
00768 return true;
00769 }
00770
00771
00775
00776
00777 void StdMeshers_Import_1D::importMesh(const SMESH_Mesh* srcMesh,
00778 SMESH_Mesh & tgtMesh,
00779 StdMeshers_ImportSource1D* srcHyp,
00780 const TopoDS_Shape& tgtShape)
00781 {
00782
00783 TNodeNodeMap* n2n;
00784 TElemElemMap* e2e;
00785 bool toCopyGroups;
00786 SMESHDS_SubMesh* tgtSubMesh =
00787 getSubmeshForCopiedMesh( srcMesh, &tgtMesh, tgtShape, n2n, e2e, toCopyGroups );
00788 if ( !tgtSubMesh || tgtSubMesh->NbNodes() + tgtSubMesh->NbElements() > 0 )
00789 return;
00790
00791 SMESHDS_Mesh* tgtMeshDS = tgtMesh.GetMeshDS();
00792 SMESH_MeshEditor additor( &tgtMesh );
00793
00794
00795
00796 vector<const SMDS_MeshNode*> newNodes;
00797 const SMESHDS_Mesh* srcMeshDS = srcMesh->GetMeshDS();
00798 SMDS_ElemIteratorPtr eIt = srcMeshDS->elementsIterator();
00799 while ( eIt->more() )
00800 {
00801 const SMDS_MeshElement* elem = eIt->next();
00802 TElemElemMap::iterator e2eIt = e2e->insert( make_pair( elem, (SMDS_MeshElement*)0 )).first;
00803 if ( e2eIt->second ) continue;
00804 newNodes.resize( elem->NbNodes() );
00805 SMDS_MeshElement::iterator node = elem->begin_nodes();
00806 for ( unsigned i = 0; i < newNodes.size(); ++i, ++node )
00807 {
00808 TNodeNodeMap::iterator n2nIt = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )).first;
00809 if ( !n2nIt->second )
00810 {
00811 (*n2nIt).second = tgtMeshDS->AddNode( (*node)->X(), (*node)->Y(), (*node)->Z());
00812 tgtSubMesh->AddNode( n2nIt->second );
00813 }
00814 newNodes[i] = n2nIt->second;
00815 }
00816 const SMDS_MeshElement* newElem =
00817 tgtMeshDS->FindElement( newNodes, elem->GetType(), false );
00818 if ( !newElem )
00819 {
00820 newElem = additor.AddElement( newNodes, elem->GetType(), elem->IsPoly());
00821 tgtSubMesh->AddElement( newElem );
00822 }
00823 if ( toCopyGroups )
00824 (*e2eIt).second = newElem;
00825 }
00826
00827 if ( srcMeshDS->NbNodes() > n2n->size() )
00828 {
00829 SMDS_NodeIteratorPtr nIt = srcMeshDS->nodesIterator();
00830 while( nIt->more() )
00831 {
00832 const SMDS_MeshNode* node = nIt->next();
00833 if ( node->NbInverseElements() == 0 )
00834 {
00835 const SMDS_MeshNode* newNode = tgtMeshDS->AddNode( node->X(), node->Y(), node->Z());
00836 n2n->insert( make_pair( node, newNode ));
00837 tgtSubMesh->AddNode( newNode );
00838 }
00839 }
00840 }
00841
00842
00843
00844 vector<SMESH_Group*> resultGroups;
00845 if ( toCopyGroups )
00846 {
00847
00848 map< SMDSAbs_ElementType, set<string> > namesByType;
00849 SMESH_Mesh::GroupIteratorPtr groupIt = tgtMesh.GetGroups();
00850 while ( groupIt->more() )
00851 {
00852 SMESH_Group* tgtGroup = groupIt->next();
00853 namesByType[ tgtGroup->GetGroupDS()->GetType() ].insert( tgtGroup->GetName() );
00854 }
00855 if (srcMesh)
00856 {
00857 SMESH_Mesh::GroupIteratorPtr groupIt = srcMesh->GetGroups();
00858 while ( groupIt->more() )
00859 {
00860 SMESH_Group* srcGroup = groupIt->next();
00861 SMESHDS_GroupBase* srcGroupDS = srcGroup->GetGroupDS();
00862 string name = srcGroup->GetName();
00863 int nb = 1;
00864 while ( !namesByType[ srcGroupDS->GetType() ].insert( name ).second )
00865 name = SMESH_Comment(srcGroup->GetName()) << "_imported_" << nb++;
00866 SMESH_Group* newGroup = tgtMesh.AddGroup( srcGroupDS->GetType(), name.c_str(), nb );
00867 SMESHDS_Group* newGroupDS = (SMESHDS_Group*)newGroup->GetGroupDS();
00868 resultGroups.push_back( newGroup );
00869
00870 eIt = srcGroupDS->GetElements();
00871 if ( srcGroupDS->GetType() == SMDSAbs_Node )
00872 while (eIt->more())
00873 {
00874 TNodeNodeMap::iterator n2nIt = n2n->find((const SMDS_MeshNode*) eIt->next() );
00875 if ( n2nIt != n2n->end() && n2nIt->second )
00876 newGroupDS->SMDSGroup().Add((*n2nIt).second );
00877 }
00878 else
00879 while (eIt->more())
00880 {
00881 TElemElemMap::iterator e2eIt = e2e->find( eIt->next() );
00882 if ( e2eIt != e2e->end() && e2eIt->second )
00883 newGroupDS->SMDSGroup().Add((*e2eIt).second );
00884 }
00885 }
00886 }
00887 }
00888 n2n->clear();
00889 e2e->clear();
00890
00891
00892
00893
00894 srcHyp->StoreResultGroups( resultGroups, *srcMeshDS, *tgtMeshDS );
00895 }
00896
00897
00903
00904
00905 void StdMeshers_Import_1D::setEventListener(SMESH_subMesh* subMesh,
00906 StdMeshers_ImportSource1D* sourceHyp)
00907 {
00908 if ( sourceHyp )
00909 {
00910 vector<SMESH_Mesh*> srcMeshes = sourceHyp->GetSourceMeshes();
00911 if ( srcMeshes.empty() )
00912 _Listener::waitHypModification( subMesh );
00913 for ( unsigned i = 0; i < srcMeshes.size(); ++i )
00914
00915 _Listener::storeImportSubmesh( subMesh, srcMeshes[i], sourceHyp );
00916 }
00917 }
00918 void StdMeshers_Import_1D::SetEventListener(SMESH_subMesh* subMesh)
00919 {
00920 if ( !_sourceHyp )
00921 {
00922 const TopoDS_Shape& tgtShape = subMesh->GetSubShape();
00923 SMESH_Mesh* tgtMesh = subMesh->GetFather();
00924 Hypothesis_Status aStatus;
00925 CheckHypothesis( *tgtMesh, tgtShape, aStatus );
00926 }
00927 setEventListener( subMesh, _sourceHyp );
00928 }
00929
00930 void StdMeshers_Import_1D::SubmeshRestored(SMESH_subMesh* subMesh)
00931 {
00932 SetEventListener(subMesh);
00933 }
00934
00935
00939
00940
00941 bool StdMeshers_Import_1D::Evaluate(SMESH_Mesh & theMesh,
00942 const TopoDS_Shape & theShape,
00943 MapShapeNbElems& aResMap)
00944 {
00945 if ( !_sourceHyp ) return false;
00946
00947 const vector<SMESH_Group*>& srcGroups = _sourceHyp->GetGroups();
00948 if ( srcGroups.empty() )
00949 return error("Invalid source groups");
00950
00951 vector<int> aVec(SMDSEntity_Last,0);
00952
00953 bool toCopyMesh, toCopyGroups;
00954 _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups);
00955 if ( toCopyMesh )
00956 {
00957 vector<SMESH_Mesh*> srcMeshes = _sourceHyp->GetSourceMeshes();
00958 for ( unsigned i = 0; i < srcMeshes.size(); ++i )
00959 {
00960 SMESH_subMesh* sm = getSubMeshOfCopiedMesh( theMesh, *srcMeshes[i]);
00961 if ( !sm || aResMap.count( sm )) continue;
00962 aVec.assign( SMDSEntity_Last, 0);
00963 const SMDS_MeshInfo& aMeshInfo = srcMeshes[i]->GetMeshDS()->GetMeshInfo();
00964 for (int i = 0; i < SMDSEntity_Last; i++)
00965 aVec[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
00966 }
00967 }
00968 else
00969 {
00970 SMESH_MesherHelper helper(theMesh);
00971
00972 const TopoDS_Edge& geomEdge = TopoDS::Edge( theShape );
00973 const double edgeTol = helper.MaxTolerance( geomEdge );
00974
00975
00976 TopExp_Explorer vExp( theShape, TopAbs_VERTEX );
00977 for ( ; vExp.More(); vExp.Next() )
00978 theMesh.GetSubMesh( vExp.Current())->Evaluate( aResMap );
00979
00980
00981 int nbEdges = 0, nbQuadEdges = 0;
00982 for ( int iG = 0; iG < srcGroups.size(); ++iG )
00983 {
00984 const SMESHDS_GroupBase* srcGroup = srcGroups[iG]->GetGroupDS();
00985 SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
00986 SMDS_MeshNode *tmpNode = helper.AddNode(0,0,0);
00987 while ( srcElems->more() )
00988 {
00989 const SMDS_MeshElement* edge = srcElems->next();
00990
00991
00992 SMESH_TNodeXYZ p1( edge->GetNode(0));
00993 SMESH_TNodeXYZ p2( edge->GetNode(1));
00994 gp_XYZ middle = ( p1 + p2 ) / 2.;
00995 tmpNode->setXYZ( middle.X(), middle.Y(), middle.Z());
00996 double u = 0;
00997 if ( helper.CheckNodeU( geomEdge, tmpNode, u, 10 * edgeTol, true ))
00998 ++( edge->IsQuadratic() ? nbQuadEdges : nbEdges);
00999 }
01000 helper.GetMeshDS()->RemoveNode(tmpNode);
01001 }
01002
01003 int nbNodes = nbEdges + 2 * nbQuadEdges - 1;
01004
01005 aVec[SMDSEntity_Node ] = nbNodes;
01006 aVec[SMDSEntity_Edge ] = nbEdges;
01007 aVec[SMDSEntity_Quad_Edge] = nbQuadEdges;
01008 }
01009
01010 SMESH_subMesh * sm = theMesh.GetSubMesh(theShape);
01011 aResMap.insert(make_pair(sm,aVec));
01012
01013 return true;
01014 }
01015
01016
01020
01021
01022 void StdMeshers_Import_1D::getMaps(const SMESH_Mesh* srcMesh,
01023 SMESH_Mesh* tgtMesh,
01024 TNodeNodeMap*& n2n,
01025 TElemElemMap*& e2e)
01026 {
01027 _ImportData* iData = _Listener::getImportData(srcMesh,tgtMesh);
01028 n2n = &iData->_n2n;
01029 e2e = &iData->_e2e;
01030 if ( iData->_copyMeshSubM.empty() )
01031 {
01032 n2n->clear();
01033 e2e->clear();
01034 }
01035 }
01036
01037
01041
01042
01043 SMESH_subMesh* StdMeshers_Import_1D::getSubMeshOfCopiedMesh( SMESH_Mesh& tgtMesh,
01044 SMESH_Mesh& srcMesh )
01045 {
01046 _ImportData* iData = _Listener::getImportData(&srcMesh,&tgtMesh);
01047 if ( iData->_copyMeshSubM.empty() ) return 0;
01048 SMESH_subMesh* sm = tgtMesh.GetSubMeshContaining( iData->_importMeshSubID );
01049 return sm;
01050 }
01051