1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_SMESHDS_Mesh.h"
30 #include "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_SetIterator.hxx"
35 #include "SMDS_VolumeTool.hxx"
36 #include "SMESHDS_Command.hxx"
37 #include "SMESHDS_CommandType.hxx"
38 #include "SMESHDS_GroupOnGeom.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_Gen_i.hxx"
41 #include "SMESH_Group.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_MEDMesh_i.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_MeshPartDS.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMESH_PreMeshInfo.hxx"
49 #include "SMESH_PythonDump.hxx"
50 #include "SMESH_subMesh_i.hxx"
53 #include <SALOME_NamingService.hxx>
54 #include <Utils_CorbaException.hxx>
55 #include <Utils_ExceptHandlers.hxx>
56 #include <Utils_SINGLETON.hxx>
57 #include <utilities.h>
58 #include <GEOMImpl_Types.hxx>
61 #include <BRep_Builder.hxx>
62 #include <OSD_Directory.hxx>
63 #include <OSD_File.hxx>
64 #include <OSD_Path.hxx>
65 #include <OSD_Protection.hxx>
66 #include <Standard_OutOfMemory.hxx>
67 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
68 #include <TColStd_MapOfInteger.hxx>
69 #include <TColStd_SequenceOfInteger.hxx>
70 #include <TCollection_AsciiString.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
85 static int MYDEBUG = 0;
87 static int MYDEBUG = 0;
91 using SMESH::TPythonDump;
93 int SMESH_Mesh_i::_idGenerator = 0;
95 //To disable automatic genericobj management, the following line should be commented.
96 //Otherwise, it should be uncommented. Refer to KERNEL_SRC/src/SALOMEDSImpl/SALOMEDSImpl_AttributeIOR.cxx
97 #define WITHGENERICOBJ
99 //=============================================================================
103 //=============================================================================
105 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
107 CORBA::Long studyId )
108 : SALOME::GenericObj_i( thePOA )
110 MESSAGE("SMESH_Mesh_i");
113 _id = _idGenerator++;
118 //=============================================================================
122 //=============================================================================
124 SMESH_Mesh_i::~SMESH_Mesh_i()
126 MESSAGE("~SMESH_Mesh_i");
128 #ifdef WITHGENERICOBJ
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++) {
132 if ( CORBA::is_nil( itGr->second ))
134 SMESH_GroupBase_i* aGroup = dynamic_cast<SMESH_GroupBase_i*>(SMESH_Gen_i::GetServant(itGr->second).in());
136 // this method is called from destructor of group (PAL6331)
137 //_impl->RemoveGroup( aGroup->GetLocalID() );
138 aGroup->myMeshServant = 0;
139 aGroup->UnRegister();
145 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
146 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ ) {
147 if ( CORBA::is_nil( itSM->second ))
149 SMESH_subMesh_i* aSubMesh = dynamic_cast<SMESH_subMesh_i*>(SMESH_Gen_i::GetServant(itSM->second).in());
151 aSubMesh->UnRegister();
154 _mapSubMeshIor.clear();
156 // destroy hypotheses
157 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
158 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
159 if ( CORBA::is_nil( itH->second ))
161 SMESH_Hypothesis_i* aHypo = dynamic_cast<SMESH_Hypothesis_i*>(SMESH_Gen_i::GetServant(itH->second).in());
169 delete _impl; _impl = NULL;
171 if ( _preMeshInfo ) delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 addGeomGroupData( theShapeObject, _this() );
198 //================================================================================
200 * \brief return true if mesh has a shape to build a shape on
202 //================================================================================
204 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
205 throw (SALOME::SALOME_Exception)
207 Unexpect aCatch(SALOME_SalomeException);
210 res = _impl->HasShapeToMesh();
212 catch(SALOME_Exception & S_ex) {
213 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
218 //=======================================================================
219 //function : GetShapeToMesh
221 //=======================================================================
223 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
224 throw (SALOME::SALOME_Exception)
226 Unexpect aCatch(SALOME_SalomeException);
227 GEOM::GEOM_Object_var aShapeObj;
229 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
231 aShapeObj = _gen_i->ShapeToGeomObject( S );
233 catch(SALOME_Exception & S_ex) {
234 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
236 return aShapeObj._retn();
239 //================================================================================
241 * \brief Return false if the mesh is not yet fully loaded from the study file
243 //================================================================================
245 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
247 Unexpect aCatch(SALOME_SalomeException);
248 return !_preMeshInfo;
251 //================================================================================
253 * \brief Load full mesh data from the study file
255 //================================================================================
257 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
259 Unexpect aCatch(SALOME_SalomeException);
261 _preMeshInfo->FullLoadFromFile();
264 //================================================================================
266 * \brief Remove all nodes and elements
268 //================================================================================
270 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
272 Unexpect aCatch(SALOME_SalomeException);
274 _preMeshInfo->ForgetAllData();
278 CheckGeomGroupModif(); // issue 20145
280 catch(SALOME_Exception & S_ex) {
281 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
283 TPythonDump() << _this() << ".Clear()";
286 //================================================================================
288 * \brief Remove all nodes and elements for indicated shape
290 //================================================================================
292 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
293 throw (SALOME::SALOME_Exception)
295 Unexpect aCatch(SALOME_SalomeException);
297 _preMeshInfo->FullLoadFromFile();
300 _impl->ClearSubMesh( ShapeID );
302 catch(SALOME_Exception & S_ex) {
303 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
307 //=============================================================================
309 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
311 //=============================================================================
313 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
315 SMESH::DriverMED_ReadStatus res;
318 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
319 res = SMESH::DRS_OK; break;
320 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
321 res = SMESH::DRS_EMPTY; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
323 res = SMESH::DRS_WARN_RENUMBER; break;
324 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
325 res = SMESH::DRS_WARN_SKIP_ELEM; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
328 res = SMESH::DRS_FAIL; break;
333 //=============================================================================
335 * Convert ::SMESH_ComputeError to SMESH::ComputeError
337 //=============================================================================
339 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
341 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
342 errVar->subShapeID = -1;
343 errVar->hasBadMesh = false;
345 if ( !errorPtr || errorPtr->IsOK() )
347 errVar->code = SMESH::COMPERR_OK;
351 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
352 errVar->comment = errorPtr->myComment.c_str();
354 return errVar._retn();
357 //=============================================================================
361 * Imports mesh data from MED file
363 //=============================================================================
365 SMESH::DriverMED_ReadStatus
366 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
367 throw ( SALOME::SALOME_Exception )
369 Unexpect aCatch(SALOME_SalomeException);
372 status = _impl->MEDToMesh( theFileName, theMeshName );
374 catch( SALOME_Exception& S_ex ) {
375 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
378 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
381 CreateGroupServants();
383 int major, minor, release;
384 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
385 major = minor = release = -1;
386 _medFileInfo = new SALOME_MED::MedFileInfo();
387 _medFileInfo->fileName = theFileName;
388 _medFileInfo->fileSize = 0;
391 if ( ::_stati64( theFileName, &d ) != -1 )
394 if ( ::stat64( theFileName, &d ) != -1 )
396 _medFileInfo->fileSize = d.st_size;
397 _medFileInfo->major = major;
398 _medFileInfo->minor = minor;
399 _medFileInfo->release = release;
401 return ConvertDriverMEDReadStatus(status);
404 //================================================================================
406 * \brief Imports mesh data from the CGNS file
408 //================================================================================
410 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
411 const int theMeshIndex,
412 std::string& theMeshName )
413 throw ( SALOME::SALOME_Exception )
415 Unexpect aCatch(SALOME_SalomeException);
418 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
420 catch( SALOME_Exception& S_ex ) {
421 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
424 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
427 CreateGroupServants();
429 return ConvertDriverMEDReadStatus(status);
432 //================================================================================
434 * \brief Return string representation of a MED file version comprising nbDigits
436 //================================================================================
438 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
440 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
442 return CORBA::string_dup( ver.c_str() );
445 //=============================================================================
449 * Imports mesh data from MED file
451 //=============================================================================
453 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
454 throw ( SALOME::SALOME_Exception )
456 // Read mesh with name = <theMeshName> into SMESH_Mesh
457 _impl->UNVToMesh( theFileName );
459 CreateGroupServants();
464 //=============================================================================
468 * Imports mesh data from STL file
470 //=============================================================================
471 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
472 throw ( SALOME::SALOME_Exception )
474 // Read mesh with name = <theMeshName> into SMESH_Mesh
475 _impl->STLToMesh( theFileName );
480 //================================================================================
482 * \brief Imports data from a GMF file and returns an error description
484 //================================================================================
486 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName )
487 throw (SALOME::SALOME_Exception)
489 SMESH_ComputeErrorPtr error;
491 error = _impl->GMFToMesh( theFileName );
493 catch ( std::bad_alloc& exc ) {
494 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "std::bad_alloc raised" );
496 catch ( Standard_OutOfMemory& exc ) {
497 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Standard_OutOfMemory raised" );
499 catch (Standard_Failure& ex) {
500 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, ex.DynamicType()->Name() );
501 if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
502 error->myComment += string(": ") + ex.GetMessageString();
504 catch ( SALOME_Exception& S_ex ) {
505 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, S_ex.what() );
507 catch ( std::exception& exc ) {
508 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, exc.what() );
511 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Unknown exception" );
514 CreateGroupServants();
516 return ConvertComputeError( error );
519 //=============================================================================
523 //=============================================================================
525 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
527 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
528 (SMESH_Hypothesis::Hypothesis_Status theStatus)
531 RETURNCASE( HYP_OK );
532 RETURNCASE( HYP_MISSING );
533 RETURNCASE( HYP_CONCURENT );
534 RETURNCASE( HYP_BAD_PARAMETER );
535 RETURNCASE( HYP_HIDDEN_ALGO );
536 RETURNCASE( HYP_HIDING_ALGO );
537 RETURNCASE( HYP_UNKNOWN_FATAL );
538 RETURNCASE( HYP_INCOMPATIBLE );
539 RETURNCASE( HYP_NOTCONFORM );
540 RETURNCASE( HYP_ALREADY_EXIST );
541 RETURNCASE( HYP_BAD_DIM );
542 RETURNCASE( HYP_BAD_SUBSHAPE );
543 RETURNCASE( HYP_BAD_GEOMETRY );
544 RETURNCASE( HYP_NEED_SHAPE );
547 return SMESH::HYP_UNKNOWN_FATAL;
550 //=============================================================================
554 * calls internal addHypothesis() and then adds a reference to <anHyp> under
555 * the SObject actually having a reference to <aSubShape>.
556 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
558 //=============================================================================
560 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
561 SMESH::SMESH_Hypothesis_ptr anHyp)
562 throw(SALOME::SALOME_Exception)
564 Unexpect aCatch(SALOME_SalomeException);
566 _preMeshInfo->ForgetOrLoad();
568 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
570 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
571 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
572 aSubShapeObject, anHyp );
574 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
576 // Update Python script
577 if(_impl->HasShapeToMesh()) {
578 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
579 << aSubShapeObject << ", " << anHyp << " )";
582 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
585 return ConvertHypothesisStatus(status);
588 //=============================================================================
592 //=============================================================================
594 SMESH_Hypothesis::Hypothesis_Status
595 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
596 SMESH::SMESH_Hypothesis_ptr anHyp)
598 if(MYDEBUG) MESSAGE("addHypothesis");
600 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
601 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
604 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
605 if (CORBA::is_nil(myHyp))
606 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
609 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
612 TopoDS_Shape myLocSubShape;
613 //use PseudoShape in case if mesh has no shape
615 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
617 myLocSubShape = _impl->GetShapeToMesh();
619 int hypId = myHyp->GetId();
620 status = _impl->AddHypothesis(myLocSubShape, hypId);
621 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
622 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
623 #ifdef WITHGENERICOBJ
624 _mapHypo[hypId]->Register();
626 // assure there is a corresponding submesh
627 if ( !_impl->IsMainShape( myLocSubShape )) {
628 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
629 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
630 createSubMesh( aSubShapeObject );
634 catch(SALOME_Exception & S_ex)
636 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
641 //=============================================================================
645 //=============================================================================
647 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
648 SMESH::SMESH_Hypothesis_ptr anHyp)
649 throw(SALOME::SALOME_Exception)
651 Unexpect aCatch(SALOME_SalomeException);
653 _preMeshInfo->ForgetOrLoad();
655 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
657 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
658 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
659 aSubShapeObject, anHyp );
661 // Update Python script
662 // Update Python script
663 if(_impl->HasShapeToMesh()) {
664 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
665 << aSubShapeObject << ", " << anHyp << " )";
668 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
672 return ConvertHypothesisStatus(status);
675 //=============================================================================
679 //=============================================================================
681 SMESH_Hypothesis::Hypothesis_Status
682 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
683 SMESH::SMESH_Hypothesis_ptr anHyp)
685 if(MYDEBUG) MESSAGE("removeHypothesis()");
686 // **** proposer liste de sub-shape (selection multiple)
688 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
689 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
691 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
692 if (CORBA::is_nil(myHyp))
693 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
695 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
698 TopoDS_Shape myLocSubShape;
699 //use PseudoShape in case if mesh has no shape
701 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
703 myLocSubShape = _impl->GetShapeToMesh();
705 int hypId = myHyp->GetId();
706 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
707 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
708 // _mapHypo.erase( hypId );
710 catch(SALOME_Exception & S_ex)
712 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
717 //=============================================================================
721 //=============================================================================
723 SMESH::ListOfHypothesis *
724 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
725 throw(SALOME::SALOME_Exception)
727 Unexpect aCatch(SALOME_SalomeException);
728 if (MYDEBUG) MESSAGE("GetHypothesisList");
729 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
730 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
732 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
735 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
736 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
737 myLocSubShape = _impl->GetShapeToMesh();
738 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
739 int i = 0, n = aLocalList.size();
742 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
743 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
744 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
745 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
750 catch(SALOME_Exception & S_ex) {
751 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
754 return aList._retn();
757 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
759 Unexpect aCatch(SALOME_SalomeException);
760 if (MYDEBUG) MESSAGE("GetSubMeshes");
762 SMESH::submesh_array_var aList = new SMESH::submesh_array();
765 TPythonDump aPythonDump;
766 if ( !_mapSubMeshIor.empty() )
770 aList->length( _mapSubMeshIor.size() );
772 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
773 for ( ; it != _mapSubMeshIor.end(); it++ ) {
774 if ( CORBA::is_nil( it->second )) continue;
775 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
777 if (i > 1) aPythonDump << ", ";
778 aPythonDump << it->second;
782 catch(SALOME_Exception & S_ex) {
783 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
786 // Update Python script
787 if ( !_mapSubMeshIor.empty() )
788 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
790 return aList._retn();
793 //=============================================================================
797 //=============================================================================
798 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
799 const char* theName )
800 throw(SALOME::SALOME_Exception)
802 Unexpect aCatch(SALOME_SalomeException);
803 MESSAGE("SMESH_Mesh_i::GetSubMesh");
804 if (CORBA::is_nil(aSubShapeObject))
805 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
808 SMESH::SMESH_subMesh_var subMesh;
809 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
811 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
813 //Get or Create the SMESH_subMesh object implementation
815 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
817 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
819 TopoDS_Iterator it( myLocSubShape );
821 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
823 subMesh = getSubMesh( subMeshId );
825 // create a new subMesh object servant if there is none for the shape
826 if ( subMesh->_is_nil() )
827 subMesh = createSubMesh( aSubShapeObject );
828 if ( _gen_i->CanPublishInStudy( subMesh )) {
829 SALOMEDS::SObject_var aSO =
830 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
831 subMesh, aSubShapeObject, theName );
832 if ( !aSO->_is_nil()) {
833 // Update Python script
834 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
835 << aSubShapeObject << ", '" << theName << "' )";
839 catch(SALOME_Exception & S_ex) {
840 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
842 return subMesh._retn();
845 //=============================================================================
849 //=============================================================================
851 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
852 throw (SALOME::SALOME_Exception)
854 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
855 if ( theSubMesh->_is_nil() )
858 GEOM::GEOM_Object_var aSubShapeObject;
859 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
860 if ( !aStudy->_is_nil() ) {
861 // Remove submesh's SObject
862 SALOMEDS::SObject_var anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
863 if ( !anSO->_is_nil() ) {
864 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
865 SALOMEDS::SObject_var anObj, aRef;
866 if ( anSO->FindSubObject( aTag, anObj ) && anObj->ReferencedObject( aRef ) )
867 aSubShapeObject = GEOM::GEOM_Object::_narrow( aRef->GetObject() );
869 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
870 // aSubShapeObject = theSubMesh->GetSubShape();
872 aStudy->NewBuilder()->RemoveObjectWithChildren( anSO );
874 // Update Python script
875 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
879 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
881 _preMeshInfo->ForgetOrLoad();
884 //=============================================================================
888 //=============================================================================
890 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
891 const char* theName )
892 throw(SALOME::SALOME_Exception)
894 Unexpect aCatch(SALOME_SalomeException);
896 _preMeshInfo->FullLoadFromFile();
898 SMESH::SMESH_Group_var aNewGroup =
899 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
901 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
902 SALOMEDS::SObject_var aSO =
903 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
904 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
905 if ( !aSO->_is_nil()) {
906 // Update Python script
907 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
908 << theElemType << ", '" << theName << "' )";
911 return aNewGroup._retn();
915 //=============================================================================
919 //=============================================================================
920 SMESH::SMESH_GroupOnGeom_ptr
921 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
923 GEOM::GEOM_Object_ptr theGeomObj)
924 throw(SALOME::SALOME_Exception)
926 Unexpect aCatch(SALOME_SalomeException);
928 _preMeshInfo->FullLoadFromFile();
930 SMESH::SMESH_GroupOnGeom_var aNewGroup;
932 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
933 if ( !aShape.IsNull() )
935 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
936 ( createGroup( theElemType, theName, aShape ));
938 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
939 SALOMEDS::SObject_var aSO =
940 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
941 aNewGroup, theGeomObj, theName);
942 if ( !aSO->_is_nil()) {
943 // Update Python script
944 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
945 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
950 return aNewGroup._retn();
953 //================================================================================
955 * \brief Creates a group whose contents is defined by filter
956 * \param theElemType - group type
957 * \param theName - group name
958 * \param theFilter - the filter
959 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
961 //================================================================================
963 SMESH::SMESH_GroupOnFilter_ptr
964 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
966 SMESH::Filter_ptr theFilter )
967 throw (SALOME::SALOME_Exception)
969 Unexpect aCatch(SALOME_SalomeException);
971 _preMeshInfo->FullLoadFromFile();
973 if ( CORBA::is_nil( theFilter ))
974 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
976 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
978 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
980 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
981 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
984 if ( !aNewGroup->_is_nil() )
985 aNewGroup->SetFilter( theFilter );
987 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
989 SALOMEDS::SObject_var aSO =
990 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
991 GEOM::GEOM_Object::_nil(), theName);
992 if ( !aSO->_is_nil()) {
993 // Update Python script
994 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
995 << theElemType << ", '" << theName << "', " << theFilter << " )";
999 return aNewGroup._retn();
1002 //=============================================================================
1006 //=============================================================================
1008 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1009 throw (SALOME::SALOME_Exception)
1011 if ( theGroup->_is_nil() )
1014 SMESH_GroupBase_i* aGroup =
1015 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1019 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1020 if ( !aStudy->_is_nil() ) {
1021 SALOMEDS::SObject_var aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1023 if ( !aGroupSO->_is_nil() ) {
1024 // Update Python script
1025 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1027 // Remove group's SObject
1028 aStudy->NewBuilder()->RemoveObjectWithChildren( aGroupSO );
1032 // Remove the group from SMESH data structures
1033 removeGroup( aGroup->GetLocalID() );
1036 //=============================================================================
1038 * Remove group with its contents
1040 //=============================================================================
1042 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1043 throw (SALOME::SALOME_Exception)
1046 _preMeshInfo->FullLoadFromFile();
1048 if ( theGroup->_is_nil() )
1051 SMESH_GroupBase_i* aGroup =
1052 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1056 SMESH::long_array_var anIds = aGroup->GetListOfID();
1057 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1059 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1062 if ( aGroup->GetType() == SMESH::NODE )
1063 aMeshEditor->RemoveNodes( anIds );
1065 aMeshEditor->RemoveElements( anIds );
1068 RemoveGroup( theGroup );
1070 // Update Python script
1071 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1074 //================================================================================
1076 * \brief Get the list of groups existing in the mesh
1077 * \retval SMESH::ListOfGroups * - list of groups
1079 //================================================================================
1081 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1083 Unexpect aCatch(SALOME_SalomeException);
1084 if (MYDEBUG) MESSAGE("GetGroups");
1086 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1089 TPythonDump aPythonDump;
1090 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1091 aPythonDump << "[ ";
1094 aList->length( _mapGroups.size() );
1096 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1097 for ( ; it != _mapGroups.end(); it++ ) {
1098 if ( CORBA::is_nil( it->second )) continue;
1099 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1101 if (i > 1) aPythonDump << ", ";
1102 aPythonDump << it->second;
1106 catch(SALOME_Exception & S_ex) {
1107 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1110 // Update Python script
1111 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1112 aPythonDump << " ] = " << _this() << ".GetGroups()";
1114 return aList._retn();
1117 //=============================================================================
1119 * Get number of groups existing in the mesh
1121 //=============================================================================
1123 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1125 Unexpect aCatch(SALOME_SalomeException);
1126 return _mapGroups.size();
1129 //=============================================================================
1131 * New group is created. All mesh elements that are
1132 * present in initial groups are added to the new one
1134 //=============================================================================
1135 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1136 SMESH::SMESH_GroupBase_ptr theGroup2,
1137 const char* theName )
1138 throw (SALOME::SALOME_Exception)
1141 _preMeshInfo->FullLoadFromFile();
1145 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1146 theGroup1->GetType() != theGroup2->GetType() )
1147 return SMESH::SMESH_Group::_nil();
1150 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1151 if ( aResGrp->_is_nil() )
1152 return SMESH::SMESH_Group::_nil();
1154 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1155 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1157 TColStd_MapOfInteger aResMap;
1159 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1160 aResMap.Add( anIds1[ i1 ] );
1162 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1163 aResMap.Add( anIds2[ i2 ] );
1165 SMESH::long_array_var aResIds = new SMESH::long_array;
1166 aResIds->length( aResMap.Extent() );
1169 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1170 for( ; anIter.More(); anIter.Next() )
1171 aResIds[ resI++ ] = anIter.Key();
1173 aResGrp->Add( aResIds );
1175 // Clear python lines, created by CreateGroup() and Add()
1176 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1177 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1178 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1180 // Update Python script
1181 TPythonDump() << aResGrp << " = " << _this() << ".UnionGroups( "
1182 << theGroup1 << ", " << theGroup2 << ", '"
1183 << theName << "' )";
1185 return aResGrp._retn();
1189 return SMESH::SMESH_Group::_nil();
1193 //=============================================================================
1195 \brief Union list of groups. New group is created. All mesh elements that are
1196 present in initial groups are added to the new one.
1197 \param theGroups list of groups
1198 \param theName name of group to be created
1199 \return pointer on the group
1201 //=============================================================================
1202 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1203 const char* theName )
1204 throw (SALOME::SALOME_Exception)
1207 _preMeshInfo->FullLoadFromFile();
1210 return SMESH::SMESH_Group::_nil();
1214 vector< int > anIds;
1215 SMESH::ElementType aType = SMESH::ALL;
1216 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1218 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1219 if ( CORBA::is_nil( aGrp ) )
1223 SMESH::ElementType aCurrType = aGrp->GetType();
1224 if ( aType == SMESH::ALL )
1228 if ( aType != aCurrType )
1229 return SMESH::SMESH_Group::_nil();
1233 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1234 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1236 int aCurrId = aCurrIds[ i ];
1237 anIds.push_back( aCurrId );
1242 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1243 if ( aResGrp->_is_nil() )
1244 return SMESH::SMESH_Group::_nil();
1246 // Create array of identifiers
1247 SMESH::long_array_var aResIds = new SMESH::long_array;
1248 aResIds->length( anIds.size() );
1250 //NCollection_Map< int >::Iterator anIter( anIds );
1251 for ( int i = 0; i<anIds.size(); i++ )
1253 aResIds[ i ] = anIds[i];
1255 aResGrp->Add( aResIds );
1257 // Clear python lines, created by CreateGroup() and Add()
1258 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1259 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1260 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1262 // Update Python script
1264 TPythonDump() << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1265 << &theGroups << ", '" << theName << "' )";
1267 return aResGrp._retn();
1271 return SMESH::SMESH_Group::_nil();
1275 //=============================================================================
1277 * New group is created. All mesh elements that are
1278 * present in both initial groups are added to the new one.
1280 //=============================================================================
1281 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1282 SMESH::SMESH_GroupBase_ptr theGroup2,
1283 const char* theName )
1284 throw (SALOME::SALOME_Exception)
1287 _preMeshInfo->FullLoadFromFile();
1289 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1290 theGroup1->GetType() != theGroup2->GetType() )
1291 return SMESH::SMESH_Group::_nil();
1293 // Create Intersection
1294 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1295 if ( aResGrp->_is_nil() )
1298 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1299 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1301 TColStd_MapOfInteger aMap1;
1303 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1304 aMap1.Add( anIds1[ i1 ] );
1306 TColStd_SequenceOfInteger aSeq;
1308 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1309 if ( aMap1.Contains( anIds2[ i2 ] ) )
1310 aSeq.Append( anIds2[ i2 ] );
1312 SMESH::long_array_var aResIds = new SMESH::long_array;
1313 aResIds->length( aSeq.Length() );
1315 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1316 aResIds[ resI ] = aSeq( resI + 1 );
1318 aResGrp->Add( aResIds );
1320 // Clear python lines, created by CreateGroup() and Add()
1321 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1322 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1323 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1325 // Update Python script
1326 TPythonDump() << aResGrp << " = " << _this() << ".IntersectGroups( "
1327 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1329 return aResGrp._retn();
1332 //=============================================================================
1334 \brief Intersect list of groups. New group is created. All mesh elements that
1335 are present in all initial groups simultaneously are added to the new one.
1336 \param theGroups list of groups
1337 \param theName name of group to be created
1338 \return pointer on the group
1340 //=============================================================================
1341 SMESH::SMESH_Group_ptr
1342 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1343 const char* theName )
1344 throw (SALOME::SALOME_Exception)
1347 _preMeshInfo->FullLoadFromFile();
1350 return SMESH::SMESH_Group::_nil();
1354 NCollection_DataMap< int, int > anIdToCount;
1355 SMESH::ElementType aType = SMESH::ALL;
1356 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1358 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1359 if ( CORBA::is_nil( aGrp ) )
1363 SMESH::ElementType aCurrType = aGrp->GetType();
1364 if ( aType == SMESH::ALL )
1368 if ( aType != aCurrType )
1369 return SMESH::SMESH_Group::_nil();
1372 // calculates number of occurance ids in groups
1373 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1374 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1376 int aCurrId = aCurrIds[ i ];
1377 if ( !anIdToCount.IsBound( aCurrId ) )
1378 anIdToCount.Bind( aCurrId, 1 );
1380 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1384 // create map of ids
1385 int nbGrp = theGroups.length();
1386 vector< int > anIds;
1387 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1388 for ( ; anIter.More(); anIter.Next() )
1390 int aCurrId = anIter.Key();
1391 int aCurrNb = anIter.Value();
1392 if ( aCurrNb == nbGrp )
1393 anIds.push_back( aCurrId );
1397 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1398 if ( aResGrp->_is_nil() )
1399 return SMESH::SMESH_Group::_nil();
1401 // Create array of identifiers
1402 SMESH::long_array_var aResIds = new SMESH::long_array;
1403 aResIds->length( anIds.size() );
1405 //NCollection_Map< int >::Iterator aListIter( anIds );
1406 for ( int i = 0; i<anIds.size(); i++ )
1408 aResIds[ i ] = anIds[i];
1410 aResGrp->Add( aResIds );
1412 // Clear python lines, created by CreateGroup() and Add()
1413 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1414 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1415 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1417 // Update Python script
1419 TPythonDump() << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1420 << &theGroups << ", '" << theName << "' )";
1422 return aResGrp._retn();
1426 return SMESH::SMESH_Group::_nil();
1430 //=============================================================================
1432 * New group is created. All mesh elements that are present in
1433 * main group but do not present in tool group are added to the new one
1435 //=============================================================================
1436 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1437 SMESH::SMESH_GroupBase_ptr theGroup2,
1438 const char* theName )
1439 throw (SALOME::SALOME_Exception)
1442 _preMeshInfo->FullLoadFromFile();
1444 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1445 theGroup1->GetType() != theGroup2->GetType() )
1446 return SMESH::SMESH_Group::_nil();
1449 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1450 if ( aResGrp->_is_nil() )
1453 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1454 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1456 TColStd_MapOfInteger aMap2;
1458 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1459 aMap2.Add( anIds2[ i2 ] );
1461 TColStd_SequenceOfInteger aSeq;
1462 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1463 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1464 aSeq.Append( anIds1[ i1 ] );
1466 SMESH::long_array_var aResIds = new SMESH::long_array;
1467 aResIds->length( aSeq.Length() );
1469 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1470 aResIds[ resI ] = aSeq( resI + 1 );
1472 aResGrp->Add( aResIds );
1474 // Clear python lines, created by CreateGroup() and Add()
1475 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1476 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1477 _gen_i->RemoveLastFromPythonScript(aStudy->StudyId());
1479 // Update Python script
1480 TPythonDump() << aResGrp << " = " << _this() << ".CutGroups( "
1481 << theGroup1 << ", " << theGroup2 << ", '"
1482 << theName << "' )";
1484 return aResGrp._retn();
1487 //=============================================================================
1489 \brief Cut lists of groups. New group is created. All mesh elements that are
1490 present in main groups but do not present in tool groups are added to the new one
1491 \param theMainGroups list of main groups
1492 \param theToolGroups list of tool groups
1493 \param theName name of group to be created
1494 \return pointer on the group
1496 //=============================================================================
1497 SMESH::SMESH_Group_ptr
1498 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1499 const SMESH::ListOfGroups& theToolGroups,
1500 const char* theName )
1501 throw (SALOME::SALOME_Exception)
1504 _preMeshInfo->FullLoadFromFile();
1507 return SMESH::SMESH_Group::_nil();
1511 set< int > aToolIds;
1512 SMESH::ElementType aType = SMESH::ALL;
1514 // iterate through tool groups
1515 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1517 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1518 if ( CORBA::is_nil( aGrp ) )
1522 SMESH::ElementType aCurrType = aGrp->GetType();
1523 if ( aType == SMESH::ALL )
1527 if ( aType != aCurrType )
1528 return SMESH::SMESH_Group::_nil();
1532 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1533 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1535 int aCurrId = aCurrIds[ i ];
1536 aToolIds.insert( aCurrId );
1540 vector< int > anIds; // result
1542 // Iterate through main group
1543 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1545 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1546 if ( CORBA::is_nil( aGrp ) )
1550 SMESH::ElementType aCurrType = aGrp->GetType();
1551 if ( aType == SMESH::ALL )
1555 if ( aType != aCurrType )
1556 return SMESH::SMESH_Group::_nil();
1560 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1561 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1563 int aCurrId = aCurrIds[ i ];
1564 if ( !aToolIds.count( aCurrId ) )
1565 anIds.push_back( aCurrId );
1570 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1571 if ( aResGrp->_is_nil() )
1572 return SMESH::SMESH_Group::_nil();
1574 // Create array of identifiers
1575 SMESH::long_array_var aResIds = new SMESH::long_array;
1576 aResIds->length( anIds.size() );
1578 for (int i=0; i<anIds.size(); i++ )
1580 aResIds[ i ] = anIds[i];
1582 aResGrp->Add( aResIds );
1584 // Clear python lines, created by CreateGroup() and Add()
1585 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1586 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1587 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1589 // Update Python script
1591 TPythonDump() << aResGrp << " = " << _this() << ".CutListOfGroups( "
1592 << &theMainGroups << ", " << &theToolGroups << ", '"
1593 << theName << "' )";
1595 return aResGrp._retn();
1599 return SMESH::SMESH_Group::_nil();
1603 //=============================================================================
1605 \brief Create groups of entities from existing groups of superior dimensions
1607 1) extract all nodes from each group,
1608 2) combine all elements of specified dimension laying on these nodes.
1609 \param theGroups list of source groups
1610 \param theElemType dimension of elements
1611 \param theName name of new group
1612 \return pointer on new group
1614 //=============================================================================
1615 SMESH::SMESH_Group_ptr
1616 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1617 SMESH::ElementType theElemType,
1618 const char* theName )
1619 throw (SALOME::SALOME_Exception)
1622 _preMeshInfo->FullLoadFromFile();
1624 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1626 if ( !theName || !aMeshDS )
1627 return SMESH::SMESH_Group::_nil();
1629 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1633 // Create map of nodes from all groups
1635 set< int > aNodeMap;
1637 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1639 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1640 if ( CORBA::is_nil( aGrp ) )
1643 SMESH::ElementType aType = aGrp->GetType();
1644 if ( aType == SMESH::ALL )
1646 else if ( aType == SMESH::NODE )
1648 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1649 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1651 int aCurrId = aCurrIds[ i ];
1652 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1654 aNodeMap.insert( aNode->GetID() );
1659 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1660 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1662 int aCurrId = aCurrIds[ i ];
1663 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1666 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1667 while( aNodeIter->more() )
1669 const SMDS_MeshNode* aNode =
1670 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1672 aNodeMap.insert( aNode->GetID() );
1678 // Get result identifiers
1680 vector< int > aResultIds;
1681 if ( theElemType == SMESH::NODE )
1683 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1684 set<int>::iterator iter = aNodeMap.begin();
1685 for ( ; iter != aNodeMap.end(); iter++ )
1686 aResultIds.push_back( *iter);
1690 // Create list of elements of given dimension constructed on the nodes
1691 vector< int > anElemList;
1692 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1693 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1694 set<int>::iterator iter = aNodeMap.begin();
1695 for ( ; iter != aNodeMap.end(); iter++ )
1697 const SMDS_MeshElement* aNode =
1698 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1702 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1703 while( anElemIter->more() )
1705 const SMDS_MeshElement* anElem =
1706 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1707 if ( anElem && anElem->GetType() == anElemType )
1708 anElemList.push_back( anElem->GetID() );
1712 // check whether all nodes of elements are present in nodes map
1713 for (int i=0; i< anElemList.size(); i++)
1715 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1720 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1721 while( aNodeIter->more() )
1723 const SMDS_MeshNode* aNode =
1724 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1725 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1732 aResultIds.push_back( anElem->GetID() );
1738 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1739 if ( aResGrp->_is_nil() )
1740 return SMESH::SMESH_Group::_nil();
1742 // Create array of identifiers
1743 SMESH::long_array_var aResIds = new SMESH::long_array;
1744 aResIds->length( aResultIds.size() );
1746 for (int i=0; i< aResultIds.size(); i++)
1747 aResIds[ i ] = aResultIds[i];
1748 aResGrp->Add( aResIds );
1750 // Remove strings corresponding to group creation
1751 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
1752 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1753 _gen_i->RemoveLastFromPythonScript( aStudy->StudyId() );
1755 // Update Python script
1757 TPythonDump() << aResGrp << " = " << _this() << ".CreateDimGroup( "
1758 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1760 return aResGrp._retn();
1764 return SMESH::SMESH_Group::_nil();
1768 //================================================================================
1770 * \brief Remember GEOM group data
1772 //================================================================================
1774 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1775 CORBA::Object_ptr theSmeshObj)
1777 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1780 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1781 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1782 if ( groupSO->_is_nil() )
1785 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1786 GEOM::GEOM_IGroupOperations_var groupOp =
1787 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1788 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1791 _geomGroupData.push_back( TGeomGroupData() );
1792 TGeomGroupData & groupData = _geomGroupData.back();
1794 CORBA::String_var entry = groupSO->GetID();
1795 groupData._groupEntry = entry.in();
1797 for ( int i = 0; i < ids->length(); ++i )
1798 groupData._indices.insert( ids[i] );
1800 groupData._smeshObject = theSmeshObj;
1803 //================================================================================
1805 * Remove GEOM group data relating to removed smesh object
1807 //================================================================================
1809 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1811 list<TGeomGroupData>::iterator
1812 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1813 for ( ; data != dataEnd; ++data ) {
1814 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1815 _geomGroupData.erase( data );
1821 //================================================================================
1823 * \brief Return new group contents if it has been changed and update group data
1825 //================================================================================
1827 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1829 TopoDS_Shape newShape;
1832 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1833 if ( study->_is_nil() ) return newShape; // means "not changed"
1834 SALOMEDS::SObject_var groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1835 if ( !groupSO->_is_nil() )
1837 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1838 if ( CORBA::is_nil( groupObj )) return newShape;
1839 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1841 // get indices of group items
1842 set<int> curIndices;
1843 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1844 GEOM::GEOM_IGroupOperations_var groupOp =
1845 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1846 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1847 for ( int i = 0; i < ids->length(); ++i )
1848 curIndices.insert( ids[i] );
1850 if ( groupData._indices == curIndices )
1851 return newShape; // group not changed
1854 groupData._indices = curIndices;
1856 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1857 if ( !geomClient ) return newShape;
1858 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1859 geomClient->RemoveShapeFromBuffer( groupIOR );
1860 newShape = _gen_i->GeomObjectToShape( geomGroup );
1863 if ( newShape.IsNull() ) {
1864 // geom group becomes empty - return empty compound
1865 TopoDS_Compound compound;
1866 BRep_Builder().MakeCompound(compound);
1867 newShape = compound;
1874 //=============================================================================
1876 * \brief Storage of shape and index used in CheckGeomGroupModif()
1878 //=============================================================================
1879 struct TIndexedShape
1882 TopoDS_Shape _shape;
1883 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1886 //=============================================================================
1888 * \brief Update objects depending on changed geom groups
1890 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1891 * issue 0020210: Update of a smesh group after modification of the associated geom group
1893 //=============================================================================
1895 void SMESH_Mesh_i::CheckGeomGroupModif()
1897 if ( !_impl->HasShapeToMesh() ) return;
1899 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1900 if ( study->_is_nil() ) return;
1902 CORBA::Long nbEntities = NbNodes() + NbElements();
1904 // Check if group contents changed
1906 typedef map< string, TopoDS_Shape > TEntry2Geom;
1907 TEntry2Geom newGroupContents;
1909 list<TGeomGroupData>::iterator
1910 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1911 for ( ; data != dataEnd; ++data )
1913 pair< TEntry2Geom::iterator, bool > it_new =
1914 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1915 bool processedGroup = !it_new.second;
1916 TopoDS_Shape& newShape = it_new.first->second;
1917 if ( !processedGroup )
1918 newShape = newGroupShape( *data );
1919 if ( newShape.IsNull() )
1920 continue; // no changes
1923 _preMeshInfo->ForgetOrLoad();
1925 if ( processedGroup ) { // update group indices
1926 list<TGeomGroupData>::iterator data2 = data;
1927 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1928 data->_indices = data2->_indices;
1931 // Update SMESH objects according to new GEOM group contents
1933 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1934 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1936 int oldID = submesh->GetId();
1937 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1939 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1941 // update hypotheses
1942 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1943 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1944 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1946 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1947 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1949 // care of submeshes
1950 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1951 int newID = newSubmesh->GetId();
1952 if ( newID != oldID ) {
1953 _mapSubMesh [ newID ] = newSubmesh;
1954 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1955 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1956 _mapSubMesh. erase(oldID);
1957 _mapSubMesh_i. erase(oldID);
1958 _mapSubMeshIor.erase(oldID);
1959 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1964 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1965 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1966 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1968 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1970 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1971 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1972 ds->SetShape( newShape );
1977 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1978 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1980 // Remove groups and submeshes basing on removed sub-shapes
1982 TopTools_MapOfShape newShapeMap;
1983 TopoDS_Iterator shapeIt( newShape );
1984 for ( ; shapeIt.More(); shapeIt.Next() )
1985 newShapeMap.Add( shapeIt.Value() );
1987 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1988 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1990 if ( newShapeMap.Contains( shapeIt.Value() ))
1992 TopTools_IndexedMapOfShape oldShapeMap;
1993 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1994 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1996 const TopoDS_Shape& oldShape = oldShapeMap(i);
1997 int oldInd = meshDS->ShapeToIndex( oldShape );
1999 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2000 if ( i_smIor != _mapSubMeshIor.end() ) {
2001 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2004 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2005 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2007 // check if a group bases on oldInd shape
2008 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2009 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2010 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2011 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2013 RemoveGroup( i_grp->second ); // several groups can base on same shape
2014 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2019 // Reassign hypotheses and update groups after setting the new shape to mesh
2021 // collect anassigned hypotheses
2022 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2023 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2024 TShapeHypList assignedHyps;
2025 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2027 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2028 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2029 if ( !hyps.empty() ) {
2030 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2031 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2032 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2035 // collect shapes supporting groups
2036 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2037 TShapeTypeList groupData;
2038 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2039 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2040 for ( ; grIt != groups.end(); ++grIt )
2042 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2044 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2046 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2047 _impl->ShapeToMesh( newShape );
2049 // reassign hypotheses
2050 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2051 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2053 TIndexedShape& geom = indS_hyps->first;
2054 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2055 int oldID = geom._index;
2056 int newID = meshDS->ShapeToIndex( geom._shape );
2059 if ( oldID == 1 ) { // main shape
2061 geom._shape = newShape;
2063 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2064 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2065 // care of submeshes
2066 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2067 if ( newID != oldID ) {
2068 _mapSubMesh [ newID ] = newSubmesh;
2069 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2070 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2071 _mapSubMesh. erase(oldID);
2072 _mapSubMesh_i. erase(oldID);
2073 _mapSubMeshIor.erase(oldID);
2074 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2078 TShapeTypeList::iterator geomType = groupData.begin();
2079 for ( ; geomType != groupData.end(); ++geomType )
2081 const TIndexedShape& geom = geomType->first;
2082 int oldID = geom._index;
2083 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2086 SALOMEDS::SObject_var groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2087 CORBA::String_var name = groupSO->GetName();
2089 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2091 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2092 group_i->changeLocalId( newID );
2095 break; // everything has been updated
2098 } // loop on group data
2102 CORBA::Long newNbEntities = NbNodes() + NbElements();
2103 list< SALOMEDS::SObject_var > soToUpdateIcons;
2104 if ( newNbEntities != nbEntities )
2106 // Add all SObjects with icons to soToUpdateIcons
2107 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2109 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2110 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2111 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2113 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2114 i_gr != _mapGroups.end(); ++i_gr ) // groups
2115 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2118 list< SALOMEDS::SObject_var >::iterator so = soToUpdateIcons.begin();
2119 for ( ; so != soToUpdateIcons.end(); ++so )
2120 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2123 //=============================================================================
2125 * \brief Create standalone group from a group on geometry or filter
2127 //=============================================================================
2129 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2132 _preMeshInfo->FullLoadFromFile();
2134 SMESH::SMESH_Group_var aGroup;
2135 if ( theGroup->_is_nil() )
2136 return aGroup._retn();
2138 Unexpect aCatch(SALOME_SalomeException);
2140 SMESH_GroupBase_i* aGroupToRem =
2141 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2143 return aGroup._retn();
2145 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2147 int anId = aGroupToRem->GetLocalID();
2148 if ( !_impl->ConvertToStandalone( anId ) )
2149 return aGroup._retn();
2150 removeGeomGroupData( theGroup );
2152 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2154 // remove old instance of group from own map
2155 _mapGroups.erase( anId );
2157 SALOMEDS::StudyBuilder_var builder;
2158 SALOMEDS::SObject_var aGroupSO;
2159 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2160 if ( !aStudy->_is_nil() ) {
2161 builder = aStudy->NewBuilder();
2162 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2163 if ( !aGroupSO->_is_nil() ) {
2165 // remove reference to geometry
2166 SALOMEDS::ChildIterator_var chItr = aStudy->NewChildIterator(aGroupSO);
2167 for ( ; chItr->More(); chItr->Next() )
2168 // Remove group's child SObject
2169 builder->RemoveObject( chItr->Value() );
2171 // Update Python script
2172 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2173 << aGroupSO << " )";
2175 // change icon of Group on Filter
2178 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2179 const int isEmpty = ( elemTypes->length() == 0 );
2182 SALOMEDS::GenericAttribute_var anAttr =
2183 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2184 SALOMEDS::AttributePixMap_var pm = SALOMEDS::AttributePixMap::_narrow( anAttr );
2185 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2191 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2192 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2193 aGroupImpl->Register();
2194 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2196 // remember new group in own map
2197 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2198 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2200 // register CORBA object for persistence
2201 /*int nextId =*/ _gen_i->RegisterObject( aGroup );
2203 builder->SetIOR( aGroupSO, _gen_i->GetORB()->object_to_string( aGroup ) );
2205 return aGroup._retn();
2208 //=============================================================================
2212 //=============================================================================
2214 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2216 if(MYDEBUG) MESSAGE( "createSubMesh" );
2217 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2219 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2220 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2221 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2222 SMESH::SMESH_subMesh_var subMesh
2223 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2225 _mapSubMesh[subMeshId] = mySubMesh;
2226 _mapSubMesh_i[subMeshId] = subMeshServant;
2227 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2229 // register CORBA object for persistence
2230 int nextId = _gen_i->RegisterObject( subMesh );
2231 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2233 // to track changes of GEOM groups
2234 addGeomGroupData( theSubShapeObject, subMesh );
2236 return subMesh._retn();
2239 //=======================================================================
2240 //function : getSubMesh
2242 //=======================================================================
2244 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2246 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2247 if ( it == _mapSubMeshIor.end() )
2248 return SMESH::SMESH_subMesh::_nil();
2250 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2254 //=============================================================================
2258 //=============================================================================
2260 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2261 GEOM::GEOM_Object_ptr theSubShapeObject )
2263 bool isHypChanged = false;
2264 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2265 return isHypChanged;
2267 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2269 CORBA::Long shapeId = theSubMesh->GetId();
2270 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2272 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2275 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2276 isHypChanged = !hyps.empty();
2277 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2278 for ( ; hyp != hyps.end(); ++hyp )
2279 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2286 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2287 isHypChanged = ( aHypList->length() > 0 );
2288 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2289 removeHypothesis( theSubShapeObject, aHypList[i] );
2292 catch( const SALOME::SALOME_Exception& ) {
2293 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2295 removeGeomGroupData( theSubShapeObject );
2297 int subMeshId = theSubMesh->GetId();
2299 _mapSubMesh.erase(subMeshId);
2300 _mapSubMesh_i.erase(subMeshId);
2301 _mapSubMeshIor.erase(subMeshId);
2303 return isHypChanged;
2306 //=============================================================================
2310 //=============================================================================
2312 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2313 const char* theName,
2314 const TopoDS_Shape& theShape,
2315 const SMESH_PredicatePtr& thePredicate )
2317 std::string newName;
2318 if ( !theName || strlen( theName ) == 0 )
2320 std::set< std::string > presentNames;
2321 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2322 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2323 presentNames.insert( i_gr->second->GetName() );
2325 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2326 } while ( !presentNames.insert( newName ).second );
2327 theName = newName.c_str();
2330 SMESH::SMESH_GroupBase_var aGroup;
2331 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2333 SMESH_GroupBase_i* aGroupImpl;
2334 if ( !theShape.IsNull() )
2335 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2336 else if ( thePredicate )
2337 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2339 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2341 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2342 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
2343 aGroupImpl->Register();
2344 // PAL7962: san -- To ensure correct mapping of servant and correct reference counting in GenericObj_i
2346 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2347 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2349 // register CORBA object for persistence
2350 int nextId = _gen_i->RegisterObject( aGroup );
2351 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2353 // to track changes of GEOM groups
2354 if ( !theShape.IsNull() ) {
2355 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2356 addGeomGroupData( geom, aGroup );
2359 return aGroup._retn();
2362 //=============================================================================
2364 * SMESH_Mesh_i::removeGroup
2366 * Should be called by ~SMESH_Group_i()
2368 //=============================================================================
2370 void SMESH_Mesh_i::removeGroup( const int theId )
2372 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2373 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2374 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2375 _mapGroups.erase( theId );
2376 removeGeomGroupData( group );
2377 if (! _impl->RemoveGroup( theId ))
2379 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2380 RemoveGroup( group );
2385 //=============================================================================
2389 //=============================================================================
2391 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2392 throw(SALOME::SALOME_Exception)
2395 _preMeshInfo->FullLoadFromFile();
2397 SMESH::log_array_var aLog;
2399 list < SMESHDS_Command * >logDS = _impl->GetLog();
2400 aLog = new SMESH::log_array;
2402 int lg = logDS.size();
2405 list < SMESHDS_Command * >::iterator its = logDS.begin();
2406 while(its != logDS.end()){
2407 SMESHDS_Command *com = *its;
2408 int comType = com->GetType();
2410 int lgcom = com->GetNumber();
2412 const list < int >&intList = com->GetIndexes();
2413 int inum = intList.size();
2415 list < int >::const_iterator ii = intList.begin();
2416 const list < double >&coordList = com->GetCoords();
2417 int rnum = coordList.size();
2419 list < double >::const_iterator ir = coordList.begin();
2420 aLog[indexLog].commandType = comType;
2421 aLog[indexLog].number = lgcom;
2422 aLog[indexLog].coords.length(rnum);
2423 aLog[indexLog].indexes.length(inum);
2424 for(int i = 0; i < rnum; i++){
2425 aLog[indexLog].coords[i] = *ir;
2426 //MESSAGE(" "<<i<<" "<<ir.Value());
2429 for(int i = 0; i < inum; i++){
2430 aLog[indexLog].indexes[i] = *ii;
2431 //MESSAGE(" "<<i<<" "<<ii.Value());
2440 catch(SALOME_Exception & S_ex){
2441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2443 return aLog._retn();
2447 //=============================================================================
2451 //=============================================================================
2453 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2455 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2459 //=============================================================================
2463 //=============================================================================
2465 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2467 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2471 //=============================================================================
2475 //=============================================================================
2477 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2482 //=============================================================================
2485 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2486 // issue 0020918: groups removal is caused by hyp modification
2487 // issue 0021208: to forget not loaded mesh data at hyp modification
2488 struct TCallUp_i : public SMESH_Mesh::TCallUp
2490 SMESH_Mesh_i* _mesh;
2491 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2492 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2493 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2494 virtual void Load () { _mesh->Load(); }
2498 //================================================================================
2500 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2502 //================================================================================
2504 void SMESH_Mesh_i::onHypothesisModified()
2507 _preMeshInfo->ForgetOrLoad();
2510 //=============================================================================
2514 //=============================================================================
2516 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2518 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2521 _impl->SetCallUp( new TCallUp_i(this));
2524 //=============================================================================
2528 //=============================================================================
2530 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2532 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2536 //=============================================================================
2538 * Return mesh editor
2540 //=============================================================================
2542 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2545 _preMeshInfo->FullLoadFromFile();
2547 // Create MeshEditor
2548 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2549 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2551 // Update Python script
2552 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2554 return aMesh._retn();
2557 //=============================================================================
2559 * Return mesh edition previewer
2561 //=============================================================================
2563 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2566 _preMeshInfo->FullLoadFromFile();
2568 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2569 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2570 return aMesh._retn();
2573 //================================================================================
2575 * \brief Return true if the mesh has been edited since a last total re-compute
2576 * and those modifications may prevent successful partial re-compute
2578 //================================================================================
2580 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 return _impl->HasModificationsToDiscard();
2586 //================================================================================
2588 * \brief Returns a random unique color
2590 //================================================================================
2592 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2594 const int MAX_ATTEMPTS = 100;
2596 double tolerance = 0.5;
2597 SALOMEDS::Color col;
2601 // generate random color
2602 double red = (double)rand() / RAND_MAX;
2603 double green = (double)rand() / RAND_MAX;
2604 double blue = (double)rand() / RAND_MAX;
2605 // check existence in the list of the existing colors
2606 bool matched = false;
2607 std::list<SALOMEDS::Color>::const_iterator it;
2608 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2609 SALOMEDS::Color color = *it;
2610 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2611 matched = tol < tolerance;
2613 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2614 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2622 //=============================================================================
2624 * Sets auto-color mode. If it is on, groups get unique random colors
2626 //=============================================================================
2628 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2630 Unexpect aCatch(SALOME_SalomeException);
2631 _impl->SetAutoColor(theAutoColor);
2633 TPythonDump pyDump; // not to dump group->SetColor() from below code
2634 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2636 std::list<SALOMEDS::Color> aReservedColors;
2637 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2638 for ( ; it != _mapGroups.end(); it++ ) {
2639 if ( CORBA::is_nil( it->second )) continue;
2640 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2641 it->second->SetColor( aColor );
2642 aReservedColors.push_back( aColor );
2646 //=============================================================================
2648 * Returns true if auto-color mode is on
2650 //=============================================================================
2652 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2654 Unexpect aCatch(SALOME_SalomeException);
2655 return _impl->GetAutoColor();
2658 //=============================================================================
2660 * Checks if there are groups with equal names
2662 //=============================================================================
2664 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2666 return _impl->HasDuplicatedGroupNamesMED();
2669 //================================================================================
2671 * \brief Care of a file before exporting mesh into it
2673 //================================================================================
2675 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2677 TCollection_AsciiString aFullName ((char*)file);
2678 OSD_Path aPath (aFullName);
2679 OSD_File aFile (aPath);
2680 if (aFile.Exists()) {
2681 // existing filesystem node
2682 if (aFile.KindOfFile() == OSD_FILE) {
2683 if (aFile.IsWriteable()) {
2688 if (aFile.Failed()) {
2689 TCollection_AsciiString msg ("File ");
2690 msg += aFullName + " cannot be replaced.";
2691 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2694 TCollection_AsciiString msg ("File ");
2695 msg += aFullName + " cannot be overwritten.";
2696 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2699 TCollection_AsciiString msg ("Location ");
2700 msg += aFullName + " is not a file.";
2701 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2704 // nonexisting file; check if it can be created
2706 aFile.Build(OSD_WriteOnly, OSD_Protection());
2707 if (aFile.Failed()) {
2708 TCollection_AsciiString msg ("You cannot create the file ");
2709 msg += aFullName + ". Check the directory existance and access rights.";
2710 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2718 //================================================================================
2720 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2721 * \param file - file name
2722 * \param overwrite - to erase the file or not
2723 * \retval string - mesh name
2725 //================================================================================
2727 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2728 CORBA::Boolean overwrite)
2731 PrepareForWriting(file, overwrite);
2732 string aMeshName = "Mesh";
2733 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2734 if ( !aStudy->_is_nil() ) {
2735 SALOMEDS::SObject_var aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2736 if ( !aMeshSO->_is_nil() ) {
2737 CORBA::String_var name = aMeshSO->GetName();
2739 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2740 if ( !aStudy->GetProperties()->IsLocked() )
2742 SALOMEDS::GenericAttribute_var anAttr;
2743 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2744 SALOMEDS::AttributeExternalFileDef_var aFileName;
2745 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2746 aFileName = SALOMEDS::AttributeExternalFileDef::_narrow(anAttr);
2747 ASSERT(!aFileName->_is_nil());
2748 aFileName->SetValue(file);
2749 SALOMEDS::AttributeFileType_var aFileType;
2750 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2751 aFileType = SALOMEDS::AttributeFileType::_narrow(anAttr);
2752 ASSERT(!aFileType->_is_nil());
2753 aFileType->SetValue("FICHIERMED");
2757 // Update Python script
2758 // set name of mesh before export
2759 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2761 // check names of groups
2767 //================================================================================
2769 * \brief Export to med file
2771 //================================================================================
2773 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2774 CORBA::Boolean auto_groups,
2775 SMESH::MED_VERSION theVersion,
2776 CORBA::Boolean overwrite)
2777 throw(SALOME::SALOME_Exception)
2779 Unexpect aCatch(SALOME_SalomeException);
2781 _preMeshInfo->FullLoadFromFile();
2783 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2784 TPythonDump() << _this() << ".ExportToMEDX( r'"
2785 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2787 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2790 //================================================================================
2792 * \brief Export a mesh to a med file
2794 //================================================================================
2796 void SMESH_Mesh_i::ExportToMED (const char* file,
2797 CORBA::Boolean auto_groups,
2798 SMESH::MED_VERSION theVersion)
2799 throw(SALOME::SALOME_Exception)
2801 ExportToMEDX(file,auto_groups,theVersion,true);
2804 //================================================================================
2806 * \brief Export a mesh to a med file
2808 //================================================================================
2810 void SMESH_Mesh_i::ExportMED (const char* file,
2811 CORBA::Boolean auto_groups)
2812 throw(SALOME::SALOME_Exception)
2814 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2817 //================================================================================
2819 * \brief Export a mesh to a SAUV file
2821 //================================================================================
2823 void SMESH_Mesh_i::ExportSAUV (const char* file,
2824 CORBA::Boolean auto_groups)
2825 throw(SALOME::SALOME_Exception)
2827 Unexpect aCatch(SALOME_SalomeException);
2829 _preMeshInfo->FullLoadFromFile();
2831 string aMeshName = prepareMeshNameAndGroups(file, true);
2832 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2833 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2837 //================================================================================
2839 * \brief Export a mesh to a DAT file
2841 //================================================================================
2843 void SMESH_Mesh_i::ExportDAT (const char *file)
2844 throw(SALOME::SALOME_Exception)
2846 Unexpect aCatch(SALOME_SalomeException);
2848 _preMeshInfo->FullLoadFromFile();
2850 // Update Python script
2851 // check names of groups
2853 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2856 PrepareForWriting(file);
2857 _impl->ExportDAT(file);
2860 //================================================================================
2862 * \brief Export a mesh to an UNV file
2864 //================================================================================
2866 void SMESH_Mesh_i::ExportUNV (const char *file)
2867 throw(SALOME::SALOME_Exception)
2869 Unexpect aCatch(SALOME_SalomeException);
2871 _preMeshInfo->FullLoadFromFile();
2873 // Update Python script
2874 // check names of groups
2876 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2879 PrepareForWriting(file);
2880 _impl->ExportUNV(file);
2883 //================================================================================
2885 * \brief Export a mesh to an STL file
2887 //================================================================================
2889 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2890 throw(SALOME::SALOME_Exception)
2892 Unexpect aCatch(SALOME_SalomeException);
2894 _preMeshInfo->FullLoadFromFile();
2896 // Update Python script
2897 // check names of groups
2899 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2902 PrepareForWriting(file);
2903 _impl->ExportSTL(file, isascii);
2906 //================================================================================
2908 * \brief Export a part of mesh to a med file
2910 //================================================================================
2912 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2914 CORBA::Boolean auto_groups,
2915 ::SMESH::MED_VERSION version,
2916 ::CORBA::Boolean overwrite)
2917 throw (SALOME::SALOME_Exception)
2919 Unexpect aCatch(SALOME_SalomeException);
2921 _preMeshInfo->FullLoadFromFile();
2923 PrepareForWriting(file, overwrite);
2925 string aMeshName = "Mesh";
2926 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
2927 if ( !aStudy->_is_nil() ) {
2928 SALOMEDS::SObject_var SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2929 if ( !SO->_is_nil() ) {
2930 CORBA::String_var name = SO->GetName();
2934 SMESH_MeshPartDS partDS( meshPart );
2935 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2937 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2938 << auto_groups << ", " << version << ", " << overwrite << " )";
2941 //================================================================================
2943 * \brief Export a part of mesh to a DAT file
2945 //================================================================================
2947 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2949 throw (SALOME::SALOME_Exception)
2951 Unexpect aCatch(SALOME_SalomeException);
2953 _preMeshInfo->FullLoadFromFile();
2955 PrepareForWriting(file);
2957 SMESH_MeshPartDS partDS( meshPart );
2958 _impl->ExportDAT(file,&partDS);
2960 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2962 //================================================================================
2964 * \brief Export a part of mesh to an UNV file
2966 //================================================================================
2968 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2970 throw (SALOME::SALOME_Exception)
2972 Unexpect aCatch(SALOME_SalomeException);
2974 _preMeshInfo->FullLoadFromFile();
2976 PrepareForWriting(file);
2978 SMESH_MeshPartDS partDS( meshPart );
2979 _impl->ExportUNV(file, &partDS);
2981 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2983 //================================================================================
2985 * \brief Export a part of mesh to an STL file
2987 //================================================================================
2989 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2991 ::CORBA::Boolean isascii)
2992 throw (SALOME::SALOME_Exception)
2994 Unexpect aCatch(SALOME_SalomeException);
2996 _preMeshInfo->FullLoadFromFile();
2998 PrepareForWriting(file);
3000 SMESH_MeshPartDS partDS( meshPart );
3001 _impl->ExportSTL(file, isascii, &partDS);
3003 TPythonDump() << _this() << ".ExportPartToSTL( "
3004 << meshPart<< ", r'" << file << "', " << isascii << ")";
3007 //================================================================================
3009 * \brief Export a part of mesh to an STL file
3011 //================================================================================
3013 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3015 CORBA::Boolean overwrite)
3016 throw (SALOME::SALOME_Exception)
3019 Unexpect aCatch(SALOME_SalomeException);
3021 _preMeshInfo->FullLoadFromFile();
3023 PrepareForWriting(file,overwrite);
3025 SMESH_MeshPartDS partDS( meshPart );
3026 _impl->ExportCGNS(file, &partDS);
3028 TPythonDump() << _this() << ".ExportCGNS( r'"
3029 << file << "', " << overwrite << ", "<< meshPart<< ")";
3031 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3035 //================================================================================
3037 * \brief Export a part of mesh to a GMF file
3039 //================================================================================
3041 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3043 throw (SALOME::SALOME_Exception)
3045 Unexpect aCatch(SALOME_SalomeException);
3047 _preMeshInfo->FullLoadFromFile();
3049 PrepareForWriting(file,/*overwrite=*/true);
3051 SMESH_MeshPartDS partDS( meshPart );
3052 _impl->ExportGMF(file, &partDS);
3054 TPythonDump() << _this() << ".ExportGMF( r'"
3055 << file << "', "<< meshPart<< ")";
3058 //=============================================================================
3060 * Return implementation of SALOME_MED::MESH interfaces
3062 //=============================================================================
3064 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3066 Unexpect aCatch(SALOME_SalomeException);
3068 _preMeshInfo->FullLoadFromFile();
3070 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3071 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3072 return aMesh._retn();
3075 //=============================================================================
3077 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3079 Unexpect aCatch(SALOME_SalomeException);
3081 return _preMeshInfo->NbNodes();
3083 return _impl->NbNodes();
3086 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3088 Unexpect aCatch(SALOME_SalomeException);
3090 return _preMeshInfo->NbElements();
3092 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3095 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3097 Unexpect aCatch(SALOME_SalomeException);
3099 return _preMeshInfo->Nb0DElements();
3101 return _impl->Nb0DElements();
3104 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3106 Unexpect aCatch(SALOME_SalomeException);
3108 return _preMeshInfo->NbBalls();
3110 return _impl->NbBalls();
3113 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3117 return _preMeshInfo->NbEdges();
3119 return _impl->NbEdges();
3122 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3123 throw(SALOME::SALOME_Exception)
3125 Unexpect aCatch(SALOME_SalomeException);
3127 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3129 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3132 //=============================================================================
3134 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3136 Unexpect aCatch(SALOME_SalomeException);
3138 return _preMeshInfo->NbFaces();
3140 return _impl->NbFaces();
3143 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3145 Unexpect aCatch(SALOME_SalomeException);
3147 return _preMeshInfo->NbTriangles();
3149 return _impl->NbTriangles();
3152 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3154 Unexpect aCatch(SALOME_SalomeException);
3156 return _preMeshInfo->NbQuadrangles();
3158 return _impl->NbQuadrangles();
3161 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3163 Unexpect aCatch(SALOME_SalomeException);
3165 return _preMeshInfo->NbBiQuadQuadrangles();
3167 return _impl->NbBiQuadQuadrangles();
3170 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3172 Unexpect aCatch(SALOME_SalomeException);
3174 return _preMeshInfo->NbPolygons();
3176 return _impl->NbPolygons();
3179 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3180 throw(SALOME::SALOME_Exception)
3182 Unexpect aCatch(SALOME_SalomeException);
3184 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3186 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3189 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3190 throw(SALOME::SALOME_Exception)
3192 Unexpect aCatch(SALOME_SalomeException);
3194 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3196 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3199 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3200 throw(SALOME::SALOME_Exception)
3202 Unexpect aCatch(SALOME_SalomeException);
3204 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3206 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3209 //=============================================================================
3211 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3213 Unexpect aCatch(SALOME_SalomeException);
3215 return _preMeshInfo->NbVolumes();
3217 return _impl->NbVolumes();
3220 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3222 Unexpect aCatch(SALOME_SalomeException);
3224 return _preMeshInfo->NbTetras();
3226 return _impl->NbTetras();
3229 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3231 Unexpect aCatch(SALOME_SalomeException);
3233 return _preMeshInfo->NbHexas();
3235 return _impl->NbHexas();
3238 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3240 Unexpect aCatch(SALOME_SalomeException);
3242 return _preMeshInfo->NbTriQuadHexas();
3244 return _impl->NbTriQuadraticHexas();
3247 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3249 Unexpect aCatch(SALOME_SalomeException);
3251 return _preMeshInfo->NbPyramids();
3253 return _impl->NbPyramids();
3256 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3258 Unexpect aCatch(SALOME_SalomeException);
3260 return _preMeshInfo->NbPrisms();
3262 return _impl->NbPrisms();
3265 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3267 Unexpect aCatch(SALOME_SalomeException);
3269 return _preMeshInfo->NbHexPrisms();
3271 return _impl->NbHexagonalPrisms();
3274 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3276 Unexpect aCatch(SALOME_SalomeException);
3278 return _preMeshInfo->NbPolyhedrons();
3280 return _impl->NbPolyhedrons();
3283 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3284 throw(SALOME::SALOME_Exception)
3286 Unexpect aCatch(SALOME_SalomeException);
3288 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3290 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3293 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3294 throw(SALOME::SALOME_Exception)
3296 Unexpect aCatch(SALOME_SalomeException);
3298 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3300 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3303 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3304 throw(SALOME::SALOME_Exception)
3306 Unexpect aCatch(SALOME_SalomeException);
3308 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3310 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3313 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3314 throw(SALOME::SALOME_Exception)
3316 Unexpect aCatch(SALOME_SalomeException);
3318 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3320 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3323 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3324 throw(SALOME::SALOME_Exception)
3326 Unexpect aCatch(SALOME_SalomeException);
3328 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3330 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3333 //=============================================================================
3335 * Returns nb of published sub-meshes
3337 //=============================================================================
3339 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3341 Unexpect aCatch(SALOME_SalomeException);
3342 return _mapSubMesh_i.size();
3345 //=============================================================================
3347 * Dumps mesh into a string
3349 //=============================================================================
3351 char* SMESH_Mesh_i::Dump()
3355 return CORBA::string_dup( os.str().c_str() );
3358 //=============================================================================
3360 * Method of SMESH_IDSource interface
3362 //=============================================================================
3364 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3366 return GetElementsId();
3369 //=============================================================================
3371 * Returns ids of all elements
3373 //=============================================================================
3375 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3376 throw (SALOME::SALOME_Exception)
3378 Unexpect aCatch(SALOME_SalomeException);
3380 _preMeshInfo->FullLoadFromFile();
3382 SMESH::long_array_var aResult = new SMESH::long_array();
3383 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3385 if ( aSMESHDS_Mesh == NULL )
3386 return aResult._retn();
3388 long nbElements = NbElements();
3389 aResult->length( nbElements );
3390 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3391 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3392 aResult[i] = anIt->next()->GetID();
3394 return aResult._retn();
3398 //=============================================================================
3400 * Returns ids of all elements of given type
3402 //=============================================================================
3404 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3405 throw (SALOME::SALOME_Exception)
3407 Unexpect aCatch(SALOME_SalomeException);
3409 _preMeshInfo->FullLoadFromFile();
3411 SMESH::long_array_var aResult = new SMESH::long_array();
3412 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3414 if ( aSMESHDS_Mesh == NULL )
3415 return aResult._retn();
3417 long nbElements = NbElements();
3419 // No sense in returning ids of elements along with ids of nodes:
3420 // when theElemType == SMESH::ALL, return node ids only if
3421 // there are no elements
3422 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3423 return GetNodesId();
3425 aResult->length( nbElements );
3429 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3430 while ( i < nbElements && anIt->more() ) {
3431 const SMDS_MeshElement* anElem = anIt->next();
3432 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3433 aResult[i++] = anElem->GetID();
3436 aResult->length( i );
3438 return aResult._retn();
3441 //=============================================================================
3443 * Returns ids of all nodes
3445 //=============================================================================
3447 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3448 throw (SALOME::SALOME_Exception)
3450 Unexpect aCatch(SALOME_SalomeException);
3452 _preMeshInfo->FullLoadFromFile();
3454 SMESH::long_array_var aResult = new SMESH::long_array();
3455 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3457 if ( aSMESHDS_Mesh == NULL )
3458 return aResult._retn();
3460 long nbNodes = NbNodes();
3461 aResult->length( nbNodes );
3462 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3463 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3464 aResult[i] = anIt->next()->GetID();
3466 return aResult._retn();
3469 //=============================================================================
3473 //=============================================================================
3475 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3476 throw (SALOME::SALOME_Exception)
3479 _preMeshInfo->FullLoadFromFile();
3481 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3484 //=============================================================================
3488 //=============================================================================
3490 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3491 throw (SALOME::SALOME_Exception)
3494 _preMeshInfo->FullLoadFromFile();
3496 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3498 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3500 return ( SMESH::EntityType ) e->GetEntityType();
3503 //=============================================================================
3505 * Returns ID of elements for given submesh
3507 //=============================================================================
3508 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3509 throw (SALOME::SALOME_Exception)
3512 _preMeshInfo->FullLoadFromFile();
3514 SMESH::long_array_var aResult = new SMESH::long_array();
3516 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3517 if(!SM) return aResult._retn();
3519 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3520 if(!SDSM) return aResult._retn();
3522 aResult->length(SDSM->NbElements());
3524 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3526 while ( eIt->more() ) {
3527 aResult[i++] = eIt->next()->GetID();
3530 return aResult._retn();
3534 //=============================================================================
3536 * Returns ID of nodes for given submesh
3537 * If param all==true - returns all nodes, else -
3538 * returns only nodes on shapes.
3540 //=============================================================================
3541 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3543 throw (SALOME::SALOME_Exception)
3546 _preMeshInfo->FullLoadFromFile();
3548 SMESH::long_array_var aResult = new SMESH::long_array();
3550 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3551 if(!SM) return aResult._retn();
3553 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3554 if(!SDSM) return aResult._retn();
3557 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3558 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3559 while ( nIt->more() ) {
3560 const SMDS_MeshNode* elem = nIt->next();
3561 theElems.insert( elem->GetID() );
3564 else { // all nodes of submesh elements
3565 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3566 while ( eIt->more() ) {
3567 const SMDS_MeshElement* anElem = eIt->next();
3568 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3569 while ( nIt->more() ) {
3570 const SMDS_MeshElement* elem = nIt->next();
3571 theElems.insert( elem->GetID() );
3576 aResult->length(theElems.size());
3577 set<int>::iterator itElem;
3579 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3580 aResult[i++] = *itElem;
3582 return aResult._retn();
3585 //=============================================================================
3587 * Returns type of elements for given submesh
3589 //=============================================================================
3591 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3592 throw (SALOME::SALOME_Exception)
3595 _preMeshInfo->FullLoadFromFile();
3597 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3598 if(!SM) return SMESH::ALL;
3600 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3601 if(!SDSM) return SMESH::ALL;
3603 if(SDSM->NbElements()==0)
3604 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3606 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3607 const SMDS_MeshElement* anElem = eIt->next();
3608 return ( SMESH::ElementType ) anElem->GetType();
3612 //=============================================================================
3614 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3616 //=============================================================================
3618 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3621 _preMeshInfo->FullLoadFromFile();
3623 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3625 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3630 //=============================================================================
3632 * Get XYZ coordinates of node as list of double
3633 * If there is not node for given ID - returns empty list
3635 //=============================================================================
3637 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3640 _preMeshInfo->FullLoadFromFile();
3642 SMESH::double_array_var aResult = new SMESH::double_array();
3643 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3644 if ( aSMESHDS_Mesh == NULL )
3645 return aResult._retn();
3648 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3650 return aResult._retn();
3654 aResult[0] = aNode->X();
3655 aResult[1] = aNode->Y();
3656 aResult[2] = aNode->Z();
3657 return aResult._retn();
3661 //=============================================================================
3663 * For given node returns list of IDs of inverse elements
3664 * If there is not node for given ID - returns empty list
3666 //=============================================================================
3668 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3671 _preMeshInfo->FullLoadFromFile();
3673 SMESH::long_array_var aResult = new SMESH::long_array();
3674 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3675 if ( aSMESHDS_Mesh == NULL )
3676 return aResult._retn();
3679 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3681 return aResult._retn();
3683 // find inverse elements
3684 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3685 TColStd_SequenceOfInteger IDs;
3686 while(eIt->more()) {
3687 const SMDS_MeshElement* elem = eIt->next();
3688 IDs.Append(elem->GetID());
3690 if(IDs.Length()>0) {
3691 aResult->length(IDs.Length());
3693 for(; i<=IDs.Length(); i++) {
3694 aResult[i-1] = IDs.Value(i);
3697 return aResult._retn();
3700 //=============================================================================
3702 * \brief Return position of a node on shape
3704 //=============================================================================
3706 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3709 _preMeshInfo->FullLoadFromFile();
3711 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3712 aNodePosition->shapeID = 0;
3713 aNodePosition->shapeType = GEOM::SHAPE;
3715 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3716 if ( !mesh ) return aNodePosition;
3718 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3720 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3722 aNodePosition->shapeID = aNode->getshapeId();
3723 switch ( pos->GetTypeOfPosition() ) {
3725 aNodePosition->shapeType = GEOM::EDGE;
3726 aNodePosition->params.length(1);
3727 aNodePosition->params[0] =
3728 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3731 aNodePosition->shapeType = GEOM::FACE;
3732 aNodePosition->params.length(2);
3733 aNodePosition->params[0] =
3734 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3735 aNodePosition->params[1] =
3736 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3738 case SMDS_TOP_VERTEX:
3739 aNodePosition->shapeType = GEOM::VERTEX;
3741 case SMDS_TOP_3DSPACE:
3742 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3743 aNodePosition->shapeType = GEOM::SOLID;
3744 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3745 aNodePosition->shapeType = GEOM::SHELL;
3751 return aNodePosition;
3754 //=============================================================================
3756 * If given element is node returns IDs of shape from position
3757 * If there is not node for given ID - returns -1
3759 //=============================================================================
3761 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3764 _preMeshInfo->FullLoadFromFile();
3766 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3767 if ( aSMESHDS_Mesh == NULL )
3771 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3773 return aNode->getshapeId();
3780 //=============================================================================
3782 * For given element returns ID of result shape after
3783 * ::FindShape() from SMESH_MeshEditor
3784 * If there is not element for given ID - returns -1
3786 //=============================================================================
3788 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3791 _preMeshInfo->FullLoadFromFile();
3793 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3794 if ( aSMESHDS_Mesh == NULL )
3797 // try to find element
3798 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3802 //SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
3803 ::SMESH_MeshEditor aMeshEditor(_impl);
3804 int index = aMeshEditor.FindShape( elem );
3812 //=============================================================================
3814 * Returns number of nodes for given element
3815 * If there is not element for given ID - returns -1
3817 //=============================================================================
3819 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3822 _preMeshInfo->FullLoadFromFile();
3824 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3825 if ( aSMESHDS_Mesh == NULL ) return -1;
3826 // try to find element
3827 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3828 if(!elem) return -1;
3829 return elem->NbNodes();
3833 //=============================================================================
3835 * Returns ID of node by given index for given element
3836 * If there is not element for given ID - returns -1
3837 * If there is not node for given index - returns -2
3839 //=============================================================================
3841 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3844 _preMeshInfo->FullLoadFromFile();
3846 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3847 if ( aSMESHDS_Mesh == NULL ) return -1;
3848 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3849 if(!elem) return -1;
3850 if( index>=elem->NbNodes() || index<0 ) return -1;
3851 return elem->GetNode(index)->GetID();
3854 //=============================================================================
3856 * Returns IDs of nodes of given element
3858 //=============================================================================
3860 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3863 _preMeshInfo->FullLoadFromFile();
3865 SMESH::long_array_var aResult = new SMESH::long_array();
3866 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3868 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3870 aResult->length( elem->NbNodes() );
3871 for ( int i = 0; i < elem->NbNodes(); ++i )
3872 aResult[ i ] = elem->GetNode( i )->GetID();
3875 return aResult._retn();
3878 //=============================================================================
3880 * Returns true if given node is medium node
3881 * in given quadratic element
3883 //=============================================================================
3885 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3888 _preMeshInfo->FullLoadFromFile();
3890 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3891 if ( aSMESHDS_Mesh == NULL ) return false;
3893 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3894 if(!aNode) return false;
3895 // try to find element
3896 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3897 if(!elem) return false;
3899 return elem->IsMediumNode(aNode);
3903 //=============================================================================
3905 * Returns true if given node is medium node
3906 * in one of quadratic elements
3908 //=============================================================================
3910 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3911 SMESH::ElementType theElemType)
3914 _preMeshInfo->FullLoadFromFile();
3916 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3917 if ( aSMESHDS_Mesh == NULL ) return false;
3920 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3921 if(!aNode) return false;
3923 SMESH_MesherHelper aHelper( *(_impl) );
3925 SMDSAbs_ElementType aType;
3926 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3927 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3928 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3929 else aType = SMDSAbs_All;
3931 return aHelper.IsMedium(aNode,aType);
3935 //=============================================================================
3937 * Returns number of edges for given element
3939 //=============================================================================
3941 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3944 _preMeshInfo->FullLoadFromFile();
3946 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3947 if ( aSMESHDS_Mesh == NULL ) return -1;
3948 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3949 if(!elem) return -1;
3950 return elem->NbEdges();
3954 //=============================================================================
3956 * Returns number of faces for given element
3958 //=============================================================================
3960 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3963 _preMeshInfo->FullLoadFromFile();
3965 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3966 if ( aSMESHDS_Mesh == NULL ) return -1;
3967 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3968 if(!elem) return -1;
3969 return elem->NbFaces();
3972 //=======================================================================
3973 //function : GetElemFaceNodes
3974 //purpose : Returns nodes of given face (counted from zero) for given element.
3975 //=======================================================================
3977 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3978 CORBA::Short faceIndex)
3981 _preMeshInfo->FullLoadFromFile();
3983 SMESH::long_array_var aResult = new SMESH::long_array();
3984 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3986 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3988 SMDS_VolumeTool vtool( elem );
3989 if ( faceIndex < vtool.NbFaces() )
3991 aResult->length( vtool.NbFaceNodes( faceIndex ));
3992 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3993 for ( int i = 0; i < aResult->length(); ++i )
3994 aResult[ i ] = nn[ i ]->GetID();
3998 return aResult._retn();
4001 //=======================================================================
4002 //function : FindElementByNodes
4003 //purpose : Returns an element based on all given nodes.
4004 //=======================================================================
4006 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4009 _preMeshInfo->FullLoadFromFile();
4011 CORBA::Long elemID(0);
4012 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4014 vector< const SMDS_MeshNode * > nn( nodes.length() );
4015 for ( int i = 0; i < nodes.length(); ++i )
4016 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4019 const SMDS_MeshElement* elem = mesh->FindElement( nn );
4020 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4021 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4022 _impl->NbVolumes( ORDER_QUADRATIC )))
4023 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4025 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4030 //=============================================================================
4032 * Returns true if given element is polygon
4034 //=============================================================================
4036 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4039 _preMeshInfo->FullLoadFromFile();
4041 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4042 if ( aSMESHDS_Mesh == NULL ) return false;
4043 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4044 if(!elem) return false;
4045 return elem->IsPoly();
4049 //=============================================================================
4051 * Returns true if given element is quadratic
4053 //=============================================================================
4055 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4058 _preMeshInfo->FullLoadFromFile();
4060 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4061 if ( aSMESHDS_Mesh == NULL ) return false;
4062 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4063 if(!elem) return false;
4064 return elem->IsQuadratic();
4067 //=============================================================================
4069 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4071 //=============================================================================
4073 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4076 _preMeshInfo->FullLoadFromFile();
4078 if ( const SMDS_BallElement* ball =
4079 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4080 return ball->GetDiameter();
4085 //=============================================================================
4087 * Returns bary center for given element
4089 //=============================================================================
4091 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4094 _preMeshInfo->FullLoadFromFile();
4096 SMESH::double_array_var aResult = new SMESH::double_array();
4097 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4098 if ( aSMESHDS_Mesh == NULL )
4099 return aResult._retn();
4101 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4103 return aResult._retn();
4105 if(elem->GetType()==SMDSAbs_Volume) {
4106 SMDS_VolumeTool aTool;
4107 if(aTool.Set(elem)) {
4109 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4114 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4116 double x=0., y=0., z=0.;
4117 for(; anIt->more(); ) {
4119 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4133 return aResult._retn();
4137 //=============================================================================
4139 * Create and publish group servants if any groups were imported or created anyhow
4141 //=============================================================================
4143 void SMESH_Mesh_i::CreateGroupServants()
4145 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4148 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4149 while ( groupIt->more() )
4151 ::SMESH_Group* group = groupIt->next();
4152 int anId = group->GetGroupDS()->GetID();
4154 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4155 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4157 addedIDs.insert( anId );
4159 SMESH_GroupBase_i* aGroupImpl;
4161 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4162 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4164 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4165 shape = groupOnGeom->GetShape();
4168 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4171 // To ensure correct mapping of servant and correct reference counting in GenericObj_i
4172 SMESH_Gen_i::GetPOA()->activate_object( aGroupImpl );
4173 aGroupImpl->Register();
4175 SMESH::SMESH_GroupBase_var groupVar =
4176 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4177 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4179 // register CORBA object for persistence
4180 int nextId = _gen_i->RegisterObject( groupVar );
4181 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4183 // publishing the groups in the study
4184 if ( !aStudy->_is_nil() ) {
4185 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4186 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4189 if ( !addedIDs.empty() )
4192 set<int>::iterator id = addedIDs.begin();
4193 for ( ; id != addedIDs.end(); ++id )
4195 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4196 int i = std::distance( _mapGroups.begin(), it );
4197 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4202 //=============================================================================
4204 * \brief Return groups cantained in _mapGroups by their IDs
4206 //=============================================================================
4208 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4210 int nbGroups = groupIDs.size();
4211 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4212 aList->length( nbGroups );
4214 list<int>::const_iterator ids = groupIDs.begin();
4215 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4217 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4218 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4219 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4221 aList->length( nbGroups );
4222 return aList._retn();
4225 //=============================================================================
4227 * \brief Return information about imported file
4229 //=============================================================================
4231 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4233 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4234 if ( !res.operator->() ) {
4235 res = new SALOME_MED::MedFileInfo;
4237 res->fileSize = res->major = res->minor = res->release = -1;
4242 //=============================================================================
4244 * \brief Pass names of mesh groups from study to mesh DS
4246 //=============================================================================
4248 void SMESH_Mesh_i::checkGroupNames()
4250 int nbGrp = NbGroups();
4254 SALOMEDS::Study_ptr aStudy = _gen_i->GetCurrentStudy();
4255 if ( aStudy->_is_nil() )
4256 return; // nothing to do
4258 SMESH::ListOfGroups* grpList = 0;
4259 // avoid dump of "GetGroups"
4261 // store python dump into a local variable inside local scope
4262 SMESH::TPythonDump pDump; // do not delete this line of code
4263 grpList = GetGroups();
4266 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4267 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4270 SALOMEDS::SObject_var aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4271 if ( aGrpSO->_is_nil() )
4273 // correct name of the mesh group if necessary
4274 const char* guiName = aGrpSO->GetName();
4275 if ( strcmp(guiName, aGrp->GetName()) )
4276 aGrp->SetName( guiName );
4280 //=============================================================================
4282 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4284 //=============================================================================
4285 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4287 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4288 // CORBA::string_dup(theParameters));
4289 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4292 //=============================================================================
4294 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4296 //=============================================================================
4297 char* SMESH_Mesh_i::GetParameters()
4299 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4300 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4303 //=============================================================================
4305 * \brief Returns list of notebook variables used for last Mesh operation
4307 //=============================================================================
4308 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4310 SMESH::string_array_var aResult = new SMESH::string_array();
4311 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4313 char *aParameters = GetParameters();
4314 SALOMEDS::Study_ptr aStudy = gen->GetCurrentStudy();
4315 if(!aStudy->_is_nil()) {
4316 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4317 if(aSections->length() > 0) {
4318 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4319 aResult->length(aVars.length());
4320 for(int i = 0;i < aVars.length();i++)
4321 aResult[i] = CORBA::string_dup( aVars[i]);
4325 return aResult._retn();
4328 //=======================================================================
4329 //function : GetTypes
4330 //purpose : Returns types of elements it contains
4331 //=======================================================================
4333 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4336 return _preMeshInfo->GetTypes();
4338 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4342 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4343 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4344 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4345 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4346 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4347 types->length( nbTypes );
4349 return types._retn();
4352 //=======================================================================
4353 //function : GetMesh
4354 //purpose : Returns self
4355 //=======================================================================
4357 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4359 return SMESH::SMESH_Mesh::_duplicate( _this() );
4362 //=======================================================================
4363 //function : IsMeshInfoCorrect
4364 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4365 // * happen if mesh data is not yet fully loaded from the file of study.
4366 //=======================================================================
4368 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4370 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4373 //=============================================================================
4375 * \brief Returns statistic of mesh elements
4377 //=============================================================================
4379 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4382 return _preMeshInfo->GetMeshInfo();
4384 SMESH::long_array_var aRes = new SMESH::long_array();
4385 aRes->length(SMESH::Entity_Last);
4386 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4388 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4390 return aRes._retn();
4391 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4392 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4393 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4394 return aRes._retn();
4397 //=============================================================================
4399 * \brief Collect statistic of mesh elements given by iterator
4401 //=============================================================================
4403 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4404 SMESH::long_array& theInfo)
4406 if (!theItr) return;
4407 while (theItr->more())
4408 theInfo[ theItr->next()->GetEntityType() ]++;
4411 //=============================================================================
4412 namespace // Finding concurrent hypotheses
4413 //=============================================================================
4417 * \brief mapping of mesh dimension into shape type
4419 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4421 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4423 case 0: aType = TopAbs_VERTEX; break;
4424 case 1: aType = TopAbs_EDGE; break;
4425 case 2: aType = TopAbs_FACE; break;
4427 default:aType = TopAbs_SOLID; break;
4432 //-----------------------------------------------------------------------------
4434 * \brief Internal structure used to find concurent submeshes
4436 * It represents a pair < submesh, concurent dimension >, where
4437 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4438 * with another submesh. In other words, it is dimension of a hypothesis assigned
4445 int _dim; //!< a dimension the algo can build (concurrent dimension)
4446 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4447 TopTools_MapOfShape _shapeMap;
4448 SMESH_subMesh* _subMesh;
4449 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4451 //-----------------------------------------------------------------------------
4452 // Return the algorithm
4453 const SMESH_Algo* GetAlgo() const
4454 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4456 //-----------------------------------------------------------------------------
4458 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4460 const TopoDS_Shape& theShape)
4462 _subMesh = (SMESH_subMesh*)theSubMesh;
4463 SetShape( theDim, theShape );
4466 //-----------------------------------------------------------------------------
4468 void SetShape(const int theDim,
4469 const TopoDS_Shape& theShape)
4472 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4473 if (_dim >= _ownDim)
4474 _shapeMap.Add( theShape );
4476 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4477 for( ; anExp.More(); anExp.Next() )
4478 _shapeMap.Add( anExp.Current() );
4482 //-----------------------------------------------------------------------------
4483 //! Check sharing of sub-shapes
4484 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4485 const TopTools_MapOfShape& theToFind,
4486 const TopAbs_ShapeEnum theType)
4488 bool isShared = false;
4489 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4490 for (; !isShared && anItr.More(); anItr.Next() )
4492 const TopoDS_Shape aSubSh = anItr.Key();
4493 // check for case when concurrent dimensions are same
4494 isShared = theToFind.Contains( aSubSh );
4495 // check for sub-shape with concurrent dimension
4496 TopExp_Explorer anExp( aSubSh, theType );
4497 for ( ; !isShared && anExp.More(); anExp.Next() )
4498 isShared = theToFind.Contains( anExp.Current() );
4503 //-----------------------------------------------------------------------------
4504 //! check algorithms
4505 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4506 const SMESHDS_Hypothesis* theA2)
4508 if ( !theA1 || !theA2 ||
4509 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4510 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4511 return false; // one of the hypothesis is not algorithm
4512 // check algorithm names (should be equal)
4513 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4517 //-----------------------------------------------------------------------------
4518 //! Check if sub-shape hypotheses are concurrent
4519 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4521 if ( _subMesh == theOther->_subMesh )
4522 return false; // same sub-shape - should not be
4524 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4525 // any of the two submeshes is not on COMPOUND shape )
4526 // -> no concurrency
4527 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4528 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4529 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4530 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4531 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4534 // bool checkSubShape = ( _dim >= theOther->_dim )
4535 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4536 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4537 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4538 if ( !checkSubShape )
4541 // check algorithms to be same
4542 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4543 return true; // different algorithms -> concurrency !
4545 // check hypothesises for concurrence (skip first as algorithm)
4547 // pointers should be same, because it is referened from mesh hypothesis partition
4548 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4549 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4550 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4551 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4553 // the submeshes are concurrent if their algorithms has different parameters
4554 return nbSame != theOther->_hypotheses.size() - 1;
4557 // Return true if algorithm of this SMESH_DimHyp is used if no
4558 // sub-mesh order is imposed by the user
4559 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4561 // NeedDiscreteBoundary() algo has a higher priority
4562 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4563 theOther->GetAlgo()->NeedDiscreteBoundary() )
4564 return !this->GetAlgo()->NeedDiscreteBoundary();
4566 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4569 }; // end of SMESH_DimHyp
4570 //-----------------------------------------------------------------------------
4572 typedef list<const SMESH_DimHyp*> TDimHypList;
4574 //-----------------------------------------------------------------------------
4576 void addDimHypInstance(const int theDim,
4577 const TopoDS_Shape& theShape,
4578 const SMESH_Algo* theAlgo,
4579 const SMESH_subMesh* theSubMesh,
4580 const list <const SMESHDS_Hypothesis*>& theHypList,
4581 TDimHypList* theDimHypListArr )
4583 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4584 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4585 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4586 dimHyp->_hypotheses.push_front(theAlgo);
4587 listOfdimHyp.push_back( dimHyp );
4590 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4591 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4592 theHypList.begin(), theHypList.end() );
4595 //-----------------------------------------------------------------------------
4596 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4597 TDimHypList& theListOfConcurr)
4599 if ( theListOfConcurr.empty() )
4601 theListOfConcurr.push_back( theDimHyp );
4605 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4606 while ( hypIt != theListOfConcurr.end() &&
4607 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4609 theListOfConcurr.insert( hypIt, theDimHyp );
4613 //-----------------------------------------------------------------------------
4614 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4615 const TDimHypList& theListOfDimHyp,
4616 TDimHypList& theListOfConcurrHyp,
4617 set<int>& theSetOfConcurrId )
4619 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4620 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4622 const SMESH_DimHyp* curDimHyp = *rIt;
4623 if ( curDimHyp == theDimHyp )
4624 break; // meet own dimHyp pointer in same dimension
4626 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4627 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4629 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4634 //-----------------------------------------------------------------------------
4635 void unionLists(TListOfInt& theListOfId,
4636 TListOfListOfInt& theListOfListOfId,
4639 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4640 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4642 continue; //skip already treated lists
4643 // check if other list has any same submesh object
4644 TListOfInt& otherListOfId = *it;
4645 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4646 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4649 // union two lists (from source into target)
4650 TListOfInt::iterator it2 = otherListOfId.begin();
4651 for ( ; it2 != otherListOfId.end(); it2++ ) {
4652 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4653 theListOfId.push_back(*it2);
4655 // clear source list
4656 otherListOfId.clear();
4659 //-----------------------------------------------------------------------------
4661 //! free memory allocated for dimension-hypothesis objects
4662 void removeDimHyps( TDimHypList* theArrOfList )
4664 for (int i = 0; i < 4; i++ ) {
4665 TDimHypList& listOfdimHyp = theArrOfList[i];
4666 TDimHypList::const_iterator it = listOfdimHyp.begin();
4667 for ( ; it != listOfdimHyp.end(); it++ )
4672 //-----------------------------------------------------------------------------
4674 * \brief find common submeshes with given submesh
4675 * \param theSubMeshList list of already collected submesh to check
4676 * \param theSubMesh given submesh to intersect with other
4677 * \param theCommonSubMeshes collected common submeshes
4679 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4680 const SMESH_subMesh* theSubMesh,
4681 set<const SMESH_subMesh*>& theCommon )
4685 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4686 for ( ; it != theSubMeshList.end(); it++ )
4687 theSubMesh->FindIntersection( *it, theCommon );
4688 theSubMeshList.push_back( theSubMesh );
4689 //theCommon.insert( theSubMesh );
4694 //=============================================================================
4696 * \brief Return submesh objects list in meshing order
4698 //=============================================================================
4700 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4702 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4704 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4706 return aResult._retn();
4708 ::SMESH_Mesh& mesh = GetImpl();
4709 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4710 if ( !anOrder.size() ) {
4712 // collect submeshes and detect concurrent algorithms and hypothesises
4713 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4715 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4716 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4717 ::SMESH_subMesh* sm = (*i_sm).second;
4719 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4721 // list of assigned hypothesises
4722 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4723 // Find out dimensions where the submesh can be concurrent.
4724 // We define the dimensions by algo of each of hypotheses in hypList
4725 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4726 for( ; hypIt != hypList.end(); hypIt++ ) {
4727 SMESH_Algo* anAlgo = 0;
4728 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4729 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4730 // hyp it-self is algo
4731 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4733 // try to find algorithm with help of sub-shapes
4734 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4735 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4736 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4739 continue; // no algorithm assigned to a current submesh
4741 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4742 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4744 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4745 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4746 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4748 } // end iterations on submesh
4750 // iterate on created dimension-hypotheses and check for concurrents
4751 for ( int i = 0; i < 4; i++ ) {
4752 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4753 // check for concurrents in own and other dimensions (step-by-step)
4754 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4755 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4756 const SMESH_DimHyp* dimHyp = *dhIt;
4757 TDimHypList listOfConcurr;
4758 set<int> setOfConcurrIds;
4759 // looking for concurrents and collect into own list
4760 for ( int j = i; j < 4; j++ )
4761 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4762 // check if any concurrents found
4763 if ( listOfConcurr.size() > 0 ) {
4764 // add own submesh to list of concurrent
4765 addInOrderOfPriority( dimHyp, listOfConcurr );
4766 list<int> listOfConcurrIds;
4767 TDimHypList::iterator hypIt = listOfConcurr.begin();
4768 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4769 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4770 anOrder.push_back( listOfConcurrIds );
4775 removeDimHyps(dimHypListArr);
4777 // now, minimise the number of concurrent groups
4778 // Here we assume that lists of submeshes can have same submesh
4779 // in case of multi-dimension algorithms, as result
4780 // list with common submesh has to be united into one list
4782 TListOfListOfInt::iterator listIt = anOrder.begin();
4783 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4784 unionLists( *listIt, anOrder, listIndx + 1 );
4786 // convert submesh ids into interface instances
4787 // and dump command into python
4788 convertMeshOrder( anOrder, aResult, false );
4790 return aResult._retn();
4793 //=============================================================================
4795 * \brief Set submesh object order
4796 * \param theSubMeshArray submesh array order
4798 //=============================================================================
4800 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4803 _preMeshInfo->ForgetOrLoad();
4806 ::SMESH_Mesh& mesh = GetImpl();
4808 TPythonDump aPythonDump; // prevent dump of called methods
4809 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4811 TListOfListOfInt subMeshOrder;
4812 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4814 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4815 TListOfInt subMeshIds;
4816 aPythonDump << "[ ";
4817 // Collect subMeshes which should be clear
4818 // do it list-by-list, because modification of submesh order
4819 // take effect between concurrent submeshes only
4820 set<const SMESH_subMesh*> subMeshToClear;
4821 list<const SMESH_subMesh*> subMeshList;
4822 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4824 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4826 aPythonDump << ", ";
4827 aPythonDump << subMesh;
4828 subMeshIds.push_back( subMesh->GetId() );
4829 // detect common parts of submeshes
4830 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4831 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4833 aPythonDump << " ]";
4834 subMeshOrder.push_back( subMeshIds );
4836 // clear collected submeshes
4837 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4838 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4839 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4840 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4842 aPythonDump << " ])";
4844 mesh.SetMeshOrder( subMeshOrder );
4850 //=============================================================================
4852 * \brief Convert submesh ids into submesh interfaces
4854 //=============================================================================
4856 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4857 SMESH::submesh_array_array& theResOrder,
4858 const bool theIsDump)
4860 int nbSet = theIdsOrder.size();
4861 TPythonDump aPythonDump; // prevent dump of called methods
4863 aPythonDump << "[ ";
4864 theResOrder.length(nbSet);
4865 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4867 for( ; it != theIdsOrder.end(); it++ ) {
4868 // translate submesh identificators into submesh objects
4869 // takeing into account real number of concurrent lists
4870 const TListOfInt& aSubOrder = (*it);
4871 if (!aSubOrder.size())
4874 aPythonDump << "[ ";
4875 // convert shape indeces into interfaces
4876 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4877 aResSubSet->length(aSubOrder.size());
4878 TListOfInt::const_iterator subIt = aSubOrder.begin();
4879 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4880 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4882 SMESH::SMESH_subMesh_var subMesh =
4883 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4886 aPythonDump << ", ";
4887 aPythonDump << subMesh;
4889 aResSubSet[ j++ ] = subMesh;
4892 aPythonDump << " ]";
4893 theResOrder[ listIndx++ ] = aResSubSet;
4895 // correct number of lists
4896 theResOrder.length( listIndx );
4899 // finilise python dump
4900 aPythonDump << " ]";
4901 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4905 //================================================================================
4907 // Implementation of SMESH_MeshPartDS
4909 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4910 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4912 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4913 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4915 _meshDS = mesh_i->GetImpl().GetMeshDS();
4917 SetPersistentId( _meshDS->GetPersistentId() );
4919 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4921 // <meshPart> is the whole mesh
4922 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4924 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4925 myGroupSet = _meshDS->GetGroups();
4930 SMESH::long_array_var anIDs = meshPart->GetIDs();
4931 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4932 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4934 for (int i=0; i < anIDs->length(); i++)
4935 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4936 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4941 for (int i=0; i < anIDs->length(); i++)
4942 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4943 if ( _elements[ e->GetType() ].insert( e ).second )
4946 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4947 while ( nIt->more() )
4949 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4950 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4957 _meshDS = 0; // to enforce iteration on _elements and _nodes
4960 // -------------------------------------------------------------------------------------
4961 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
4962 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
4965 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
4966 for ( ; partIt != meshPart.end(); ++partIt )
4967 if ( const SMDS_MeshElement * e = *partIt )
4968 if ( _elements[ e->GetType() ].insert( e ).second )
4971 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4972 while ( nIt->more() )
4974 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4975 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4981 // -------------------------------------------------------------------------------------
4982 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
4984 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
4986 typedef SMDS_SetIterator
4987 <const SMDS_MeshElement*,
4988 TIDSortedElemSet::const_iterator,
4989 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4990 SMDS_MeshElement::GeomFilter
4993 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
4995 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4996 _elements[type].end(),
4997 SMDS_MeshElement::GeomFilter( geomType )));
4999 // -------------------------------------------------------------------------------------
5000 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5002 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5004 typedef SMDS_SetIterator
5005 <const SMDS_MeshElement*,
5006 TIDSortedElemSet::const_iterator,
5007 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5008 SMDS_MeshElement::EntityFilter
5011 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5013 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5014 _elements[type].end(),
5015 SMDS_MeshElement::EntityFilter( entity )));
5017 // -------------------------------------------------------------------------------------
5018 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5020 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5021 if ( type == SMDSAbs_All && !_meshDS )
5023 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5025 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5026 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5028 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5030 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5031 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5033 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5034 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5036 // -------------------------------------------------------------------------------------
5037 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5038 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5040 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5041 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5042 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5044 // -------------------------------------------------------------------------------------
5045 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5046 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5047 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5048 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5049 #undef _GET_ITER_DEFINE
5051 // END Implementation of SMESH_MeshPartDS
5053 //================================================================================