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_MeshGroup.hxx"
35 #include "SMDS_SetIterator.hxx"
36 #include "SMDS_VolumeTool.hxx"
37 #include "SMESHDS_Command.hxx"
38 #include "SMESHDS_CommandType.hxx"
39 #include "SMESHDS_Group.hxx"
40 #include "SMESHDS_GroupOnGeom.hxx"
41 #include "SMESH_Filter_i.hxx"
42 #include "SMESH_Gen_i.hxx"
43 #include "SMESH_Group.hxx"
44 #include "SMESH_Group_i.hxx"
45 #include "SMESH_MEDMesh_i.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MeshEditor_i.hxx"
48 #include "SMESH_MeshPartDS.hxx"
49 #include "SMESH_MesherHelper.hxx"
50 #include "SMESH_PreMeshInfo.hxx"
51 #include "SMESH_PythonDump.hxx"
52 #include "SMESH_subMesh_i.hxx"
55 #include <SALOMEDS_Attributes_wrap.hxx>
56 #include <SALOMEDS_wrap.hxx>
57 #include <SALOME_NamingService.hxx>
58 #include <Utils_ExceptHandlers.hxx>
59 #include <Utils_SINGLETON.hxx>
60 #include <utilities.h>
62 #include <GEOMImpl_Types.hxx>
63 #include <GEOM_GenericObjPtr.h>
66 #include <BRep_Builder.hxx>
67 #include <OSD_Directory.hxx>
68 #include <OSD_File.hxx>
69 #include <OSD_Path.hxx>
70 #include <OSD_Protection.hxx>
71 #include <Standard_OutOfMemory.hxx>
72 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
73 #include <TColStd_MapOfInteger.hxx>
74 #include <TColStd_SequenceOfInteger.hxx>
75 #include <TCollection_AsciiString.hxx>
77 #include <TopExp_Explorer.hxx>
78 #include <TopTools_MapIteratorOfMapOfShape.hxx>
79 #include <TopTools_MapOfShape.hxx>
80 #include <TopoDS_Compound.hxx>
82 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
101 int SMESH_Mesh_i::_idGenerator = 0;
103 //=============================================================================
107 //=============================================================================
109 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
111 CORBA::Long studyId )
112 : SALOME::GenericObj_i( thePOA )
114 MESSAGE("SMESH_Mesh_i");
117 _id = _idGenerator++;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
138 //_impl->RemoveGroup( aGroup->GetLocalID() );
139 aGroup->myMeshServant = 0;
140 aGroup->UnRegister();
145 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
146 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
147 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
149 aSubMesh->UnRegister();
151 _mapSubMeshIor.clear();
153 // destroy hypotheses
154 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
155 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
156 if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
162 delete _impl; _impl = NULL;
163 delete _preMeshInfo; _preMeshInfo = NULL;
166 //=============================================================================
170 * Associates <this> mesh with <theShape> and puts a reference
171 * to <theShape> into the current study;
172 * the previous shape is substituted by the new one.
174 //=============================================================================
176 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
177 throw (SALOME::SALOME_Exception)
179 Unexpect aCatch(SALOME_SalomeException);
181 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
183 catch(SALOME_Exception & S_ex) {
184 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
186 // to track changes of GEOM groups
187 addGeomGroupData( theShapeObject, _this() );
190 //================================================================================
192 * \brief return true if mesh has a shape to build a shape on
194 //================================================================================
196 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
197 throw (SALOME::SALOME_Exception)
199 Unexpect aCatch(SALOME_SalomeException);
202 res = _impl->HasShapeToMesh();
204 catch(SALOME_Exception & S_ex) {
205 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
210 //=======================================================================
211 //function : GetShapeToMesh
213 //=======================================================================
215 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
216 throw (SALOME::SALOME_Exception)
218 Unexpect aCatch(SALOME_SalomeException);
219 GEOM::GEOM_Object_var aShapeObj;
221 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
223 aShapeObj = _gen_i->ShapeToGeomObject( S );
225 catch(SALOME_Exception & S_ex) {
226 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
228 return aShapeObj._retn();
231 //================================================================================
233 * \brief Return false if the mesh is not yet fully loaded from the study file
235 //================================================================================
237 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
239 Unexpect aCatch(SALOME_SalomeException);
240 return !_preMeshInfo;
243 //================================================================================
245 * \brief Load full mesh data from the study file
247 //================================================================================
249 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
253 _preMeshInfo->FullLoadFromFile();
256 //================================================================================
258 * \brief Remove all nodes and elements
260 //================================================================================
262 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
266 _preMeshInfo->ForgetAllData();
270 CheckGeomGroupModif(); // issue 20145
272 catch(SALOME_Exception & S_ex) {
273 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
275 _impl->GetMeshDS()->Modified();
277 TPythonDump() << _this() << ".Clear()";
280 //================================================================================
282 * \brief Remove all nodes and elements for indicated shape
284 //================================================================================
286 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
287 throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->FullLoadFromFile();
294 _impl->ClearSubMesh( ShapeID );
296 catch(SALOME_Exception & S_ex) {
297 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
299 _impl->GetMeshDS()->Modified();
301 TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )";
304 //=============================================================================
306 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
308 //=============================================================================
310 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
312 SMESH::DriverMED_ReadStatus res;
315 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
316 res = SMESH::DRS_OK; break;
317 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
318 res = SMESH::DRS_EMPTY; break;
319 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
320 res = SMESH::DRS_WARN_RENUMBER; break;
321 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
322 res = SMESH::DRS_WARN_SKIP_ELEM; break;
323 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
325 res = SMESH::DRS_FAIL; break;
330 //=============================================================================
332 * Convert ::SMESH_ComputeError to SMESH::ComputeError
334 //=============================================================================
336 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
338 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
339 errVar->subShapeID = -1;
340 errVar->hasBadMesh = false;
342 if ( !errorPtr || errorPtr->IsOK() )
344 errVar->code = SMESH::COMPERR_OK;
348 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
349 errVar->comment = errorPtr->myComment.c_str();
351 return errVar._retn();
354 //=============================================================================
358 * Imports mesh data from MED file
360 //=============================================================================
362 SMESH::DriverMED_ReadStatus
363 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
364 throw ( SALOME::SALOME_Exception )
366 Unexpect aCatch(SALOME_SalomeException);
369 status = _impl->MEDToMesh( theFileName, theMeshName );
371 catch( SALOME_Exception& S_ex ) {
372 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
375 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
378 CreateGroupServants();
380 int major, minor, release;
381 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
382 major = minor = release = -1;
383 _medFileInfo = new SALOME_MED::MedFileInfo();
384 _medFileInfo->fileName = theFileName;
385 _medFileInfo->fileSize = 0;
388 if ( ::_stati64( theFileName, &d ) != -1 )
391 if ( ::stat64( theFileName, &d ) != -1 )
393 _medFileInfo->fileSize = d.st_size;
394 _medFileInfo->major = major;
395 _medFileInfo->minor = minor;
396 _medFileInfo->release = release;
398 return ConvertDriverMEDReadStatus(status);
401 //================================================================================
403 * \brief Imports mesh data from the CGNS file
405 //================================================================================
407 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
408 const int theMeshIndex,
409 std::string& theMeshName )
410 throw ( SALOME::SALOME_Exception )
412 Unexpect aCatch(SALOME_SalomeException);
415 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
417 catch( SALOME_Exception& S_ex ) {
418 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
421 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
424 CreateGroupServants();
426 return ConvertDriverMEDReadStatus(status);
429 //================================================================================
431 * \brief Return string representation of a MED file version comprising nbDigits
433 //================================================================================
435 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
437 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
439 return CORBA::string_dup( ver.c_str() );
442 //=============================================================================
446 * Imports mesh data from MED file
448 //=============================================================================
450 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
451 throw ( SALOME::SALOME_Exception )
455 // Read mesh with name = <theMeshName> into SMESH_Mesh
456 _impl->UNVToMesh( theFileName );
458 CreateGroupServants();
460 SMESH_CATCH( SMESH::throwCorbaException );
465 //=============================================================================
469 * Imports mesh data from STL file
471 //=============================================================================
472 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
473 throw ( SALOME::SALOME_Exception )
477 // Read mesh with name = <theMeshName> into SMESH_Mesh
478 _impl->STLToMesh( theFileName );
480 SMESH_CATCH( SMESH::throwCorbaException );
485 //================================================================================
487 * \brief Function used in SMESH_CATCH by ImportGMFFile()
489 //================================================================================
493 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
495 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
499 //================================================================================
501 * \brief Imports data from a GMF file and returns an error description
503 //================================================================================
505 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
506 bool theMakeRequiredGroups )
507 throw (SALOME::SALOME_Exception)
509 SMESH_ComputeErrorPtr error;
512 #define SMESH_CAUGHT error =
515 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
517 SMESH_CATCH( exceptionToComputeError );
521 CreateGroupServants();
523 return ConvertComputeError( error );
526 //=============================================================================
530 //=============================================================================
532 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
534 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
535 (SMESH_Hypothesis::Hypothesis_Status theStatus)
538 RETURNCASE( HYP_OK );
539 RETURNCASE( HYP_MISSING );
540 RETURNCASE( HYP_CONCURENT );
541 RETURNCASE( HYP_BAD_PARAMETER );
542 RETURNCASE( HYP_HIDDEN_ALGO );
543 RETURNCASE( HYP_HIDING_ALGO );
544 RETURNCASE( HYP_UNKNOWN_FATAL );
545 RETURNCASE( HYP_INCOMPATIBLE );
546 RETURNCASE( HYP_NOTCONFORM );
547 RETURNCASE( HYP_ALREADY_EXIST );
548 RETURNCASE( HYP_BAD_DIM );
549 RETURNCASE( HYP_BAD_SUBSHAPE );
550 RETURNCASE( HYP_BAD_GEOMETRY );
551 RETURNCASE( HYP_NEED_SHAPE );
554 return SMESH::HYP_UNKNOWN_FATAL;
557 //=============================================================================
561 * calls internal addHypothesis() and then adds a reference to <anHyp> under
562 * the SObject actually having a reference to <aSubShape>.
563 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
565 //=============================================================================
567 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
568 SMESH::SMESH_Hypothesis_ptr anHyp)
569 throw(SALOME::SALOME_Exception)
571 Unexpect aCatch(SALOME_SalomeException);
573 _preMeshInfo->ForgetOrLoad();
575 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
577 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
578 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
579 aSubShapeObject, anHyp );
581 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
583 // Update Python script
584 if(_impl->HasShapeToMesh()) {
585 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
586 << aSubShapeObject << ", " << anHyp << " )";
589 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
592 return ConvertHypothesisStatus(status);
595 //=============================================================================
599 //=============================================================================
601 SMESH_Hypothesis::Hypothesis_Status
602 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
603 SMESH::SMESH_Hypothesis_ptr anHyp)
605 if(MYDEBUG) MESSAGE("addHypothesis");
607 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
608 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
611 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
612 if (CORBA::is_nil(myHyp))
613 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
616 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
619 TopoDS_Shape myLocSubShape;
620 //use PseudoShape in case if mesh has no shape
622 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
624 myLocSubShape = _impl->GetShapeToMesh();
626 int hypId = myHyp->GetId();
627 status = _impl->AddHypothesis(myLocSubShape, hypId);
628 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
629 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
630 _mapHypo[hypId]->Register();
631 // assure there is a corresponding submesh
632 if ( !_impl->IsMainShape( myLocSubShape )) {
633 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
634 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
635 createSubMesh( aSubShapeObject );
639 catch(SALOME_Exception & S_ex)
641 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
646 //=============================================================================
650 //=============================================================================
652 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
653 SMESH::SMESH_Hypothesis_ptr anHyp)
654 throw(SALOME::SALOME_Exception)
656 Unexpect aCatch(SALOME_SalomeException);
658 _preMeshInfo->ForgetOrLoad();
660 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
662 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
663 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
664 aSubShapeObject, anHyp );
666 // Update Python script
667 // Update Python script
668 if(_impl->HasShapeToMesh()) {
669 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
670 << aSubShapeObject << ", " << anHyp << " )";
673 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
677 return ConvertHypothesisStatus(status);
680 //=============================================================================
684 //=============================================================================
686 SMESH_Hypothesis::Hypothesis_Status
687 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
688 SMESH::SMESH_Hypothesis_ptr anHyp)
690 if(MYDEBUG) MESSAGE("removeHypothesis()");
691 // **** proposer liste de sub-shape (selection multiple)
693 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
694 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
696 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
697 if (CORBA::is_nil(myHyp))
698 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
700 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
703 TopoDS_Shape myLocSubShape;
704 //use PseudoShape in case if mesh has no shape
706 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
708 myLocSubShape = _impl->GetShapeToMesh();
710 int hypId = myHyp->GetId();
711 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
712 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
713 // _mapHypo.erase( hypId );
715 catch(SALOME_Exception & S_ex)
717 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
722 //=============================================================================
726 //=============================================================================
728 SMESH::ListOfHypothesis *
729 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
730 throw(SALOME::SALOME_Exception)
732 Unexpect aCatch(SALOME_SalomeException);
733 if (MYDEBUG) MESSAGE("GetHypothesisList");
734 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
735 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
737 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
740 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
741 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
742 myLocSubShape = _impl->GetShapeToMesh();
743 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
744 int i = 0, n = aLocalList.size();
747 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
748 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
749 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
750 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
755 catch(SALOME_Exception & S_ex) {
756 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
759 return aList._retn();
762 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
764 Unexpect aCatch(SALOME_SalomeException);
765 if (MYDEBUG) MESSAGE("GetSubMeshes");
767 SMESH::submesh_array_var aList = new SMESH::submesh_array();
770 TPythonDump aPythonDump;
771 if ( !_mapSubMeshIor.empty() )
775 aList->length( _mapSubMeshIor.size() );
777 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
778 for ( ; it != _mapSubMeshIor.end(); it++ ) {
779 if ( CORBA::is_nil( it->second )) continue;
780 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
782 if (i > 1) aPythonDump << ", ";
783 aPythonDump << it->second;
787 catch(SALOME_Exception & S_ex) {
788 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
791 // Update Python script
792 if ( !_mapSubMeshIor.empty() )
793 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
795 return aList._retn();
798 //=============================================================================
802 //=============================================================================
803 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
804 const char* theName )
805 throw(SALOME::SALOME_Exception)
807 Unexpect aCatch(SALOME_SalomeException);
808 MESSAGE("SMESH_Mesh_i::GetSubMesh");
809 if (CORBA::is_nil(aSubShapeObject))
810 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
813 SMESH::SMESH_subMesh_var subMesh;
814 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
816 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
818 //Get or Create the SMESH_subMesh object implementation
820 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
822 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
824 TopoDS_Iterator it( myLocSubShape );
826 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
828 subMesh = getSubMesh( subMeshId );
830 // create a new subMesh object servant if there is none for the shape
831 if ( subMesh->_is_nil() )
832 subMesh = createSubMesh( aSubShapeObject );
833 if ( _gen_i->CanPublishInStudy( subMesh )) {
834 SALOMEDS::SObject_wrap aSO =
835 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
836 subMesh, aSubShapeObject, theName );
837 if ( !aSO->_is_nil()) {
838 // Update Python script
839 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
840 << aSubShapeObject << ", '" << theName << "' )";
844 catch(SALOME_Exception & S_ex) {
845 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
847 return subMesh._retn();
850 //=============================================================================
854 //=============================================================================
856 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
857 throw (SALOME::SALOME_Exception)
861 if ( theSubMesh->_is_nil() )
864 GEOM::GEOM_Object_var aSubShapeObject;
865 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
866 if ( !aStudy->_is_nil() ) {
867 // Remove submesh's SObject
868 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
869 if ( !anSO->_is_nil() ) {
870 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
871 SALOMEDS::SObject_wrap anObj, aRef;
872 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
873 anObj->ReferencedObject( aRef.inout() ))
875 CORBA::Object_var obj = aRef->GetObject();
876 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
878 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
879 // aSubShapeObject = theSubMesh->GetSubShape();
881 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
882 builder->RemoveObjectWithChildren( anSO );
884 // Update Python script
885 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
889 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
891 _preMeshInfo->ForgetOrLoad();
893 SMESH_CATCH( SMESH::throwCorbaException );
896 //=============================================================================
900 //=============================================================================
902 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
903 const char* theName )
904 throw(SALOME::SALOME_Exception)
906 Unexpect aCatch(SALOME_SalomeException);
908 _preMeshInfo->FullLoadFromFile();
910 SMESH::SMESH_Group_var aNewGroup =
911 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
913 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
914 SALOMEDS::SObject_wrap aSO =
915 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
916 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
917 if ( !aSO->_is_nil()) {
918 // Update Python script
919 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
920 << theElemType << ", '" << theName << "' )";
923 return aNewGroup._retn();
927 //=============================================================================
931 //=============================================================================
932 SMESH::SMESH_GroupOnGeom_ptr
933 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
935 GEOM::GEOM_Object_ptr theGeomObj)
936 throw(SALOME::SALOME_Exception)
938 Unexpect aCatch(SALOME_SalomeException);
940 _preMeshInfo->FullLoadFromFile();
942 SMESH::SMESH_GroupOnGeom_var aNewGroup;
944 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
945 if ( !aShape.IsNull() )
947 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
948 ( createGroup( theElemType, theName, aShape ));
950 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
951 SALOMEDS::SObject_wrap aSO =
952 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
953 aNewGroup, theGeomObj, theName);
954 if ( !aSO->_is_nil()) {
955 // Update Python script
956 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
957 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
962 return aNewGroup._retn();
965 //================================================================================
967 * \brief Creates a group whose contents is defined by filter
968 * \param theElemType - group type
969 * \param theName - group name
970 * \param theFilter - the filter
971 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
973 //================================================================================
975 SMESH::SMESH_GroupOnFilter_ptr
976 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
978 SMESH::Filter_ptr theFilter )
979 throw (SALOME::SALOME_Exception)
981 Unexpect aCatch(SALOME_SalomeException);
983 _preMeshInfo->FullLoadFromFile();
985 if ( CORBA::is_nil( theFilter ))
986 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
988 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
990 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
992 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
993 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
996 if ( !aNewGroup->_is_nil() )
997 aNewGroup->SetFilter( theFilter );
999 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1001 SALOMEDS::SObject_wrap aSO =
1002 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
1003 GEOM::GEOM_Object::_nil(), theName);
1004 if ( !aSO->_is_nil()) {
1005 // Update Python script
1006 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
1007 << theElemType << ", '" << theName << "', " << theFilter << " )";
1011 return aNewGroup._retn();
1014 //=============================================================================
1018 //=============================================================================
1020 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1021 throw (SALOME::SALOME_Exception)
1023 if ( theGroup->_is_nil() )
1028 SMESH_GroupBase_i* aGroup =
1029 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1033 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1034 if ( !aStudy->_is_nil() ) {
1035 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1037 if ( !aGroupSO->_is_nil() ) {
1038 // Update Python script
1039 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1041 // Remove group's SObject
1042 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1043 builder->RemoveObjectWithChildren( aGroupSO );
1047 // Remove the group from SMESH data structures
1048 removeGroup( aGroup->GetLocalID() );
1050 SMESH_CATCH( SMESH::throwCorbaException );
1053 //=============================================================================
1055 * Remove group with its contents
1057 //=============================================================================
1059 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1060 throw (SALOME::SALOME_Exception)
1064 _preMeshInfo->FullLoadFromFile();
1066 if ( theGroup->_is_nil() )
1069 SMESH_GroupBase_i* aGroup =
1070 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1074 SMESH::long_array_var anIds = aGroup->GetListOfID();
1075 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1077 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1080 if ( aGroup->GetType() == SMESH::NODE )
1081 aMeshEditor->RemoveNodes( anIds );
1083 aMeshEditor->RemoveElements( anIds );
1085 // Update Python script (theGroup must be alive for this)
1086 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1089 RemoveGroup( theGroup );
1091 SMESH_CATCH( SMESH::throwCorbaException );
1094 //================================================================================
1096 * \brief Get the list of groups existing in the mesh
1097 * \retval SMESH::ListOfGroups * - list of groups
1099 //================================================================================
1101 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1103 Unexpect aCatch(SALOME_SalomeException);
1104 if (MYDEBUG) MESSAGE("GetGroups");
1106 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1109 TPythonDump aPythonDump;
1110 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1111 aPythonDump << "[ ";
1114 aList->length( _mapGroups.size() );
1116 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1117 for ( ; it != _mapGroups.end(); it++ ) {
1118 if ( CORBA::is_nil( it->second )) continue;
1119 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1121 if (i > 1) aPythonDump << ", ";
1122 aPythonDump << it->second;
1126 catch(SALOME_Exception & S_ex) {
1127 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1130 // Update Python script
1131 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1132 aPythonDump << " ] = " << _this() << ".GetGroups()";
1134 return aList._retn();
1137 //=============================================================================
1139 * Get number of groups existing in the mesh
1141 //=============================================================================
1143 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1145 Unexpect aCatch(SALOME_SalomeException);
1146 return _mapGroups.size();
1149 //=============================================================================
1151 * New group is created. All mesh elements that are
1152 * present in initial groups are added to the new one
1154 //=============================================================================
1155 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1156 SMESH::SMESH_GroupBase_ptr theGroup2,
1157 const char* theName )
1158 throw (SALOME::SALOME_Exception)
1160 SMESH::SMESH_Group_var aResGrp;
1164 _preMeshInfo->FullLoadFromFile();
1166 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1167 theGroup1->GetType() != theGroup2->GetType() )
1168 return SMESH::SMESH_Group::_nil();
1173 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1174 if ( aResGrp->_is_nil() )
1175 return SMESH::SMESH_Group::_nil();
1177 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1178 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1180 TColStd_MapOfInteger aResMap;
1182 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1183 aResMap.Add( anIds1[ i1 ] );
1185 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1186 aResMap.Add( anIds2[ i2 ] );
1188 SMESH::long_array_var aResIds = new SMESH::long_array;
1189 aResIds->length( aResMap.Extent() );
1192 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1193 for( ; anIter.More(); anIter.Next() )
1194 aResIds[ resI++ ] = anIter.Key();
1196 aResGrp->Add( aResIds );
1198 // Update Python script
1199 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1200 << theGroup1 << ", " << theGroup2 << ", '"
1201 << theName << "' )";
1203 SMESH_CATCH( SMESH::throwCorbaException );
1205 return aResGrp._retn();
1208 //=============================================================================
1210 \brief Union list of groups. New group is created. All mesh elements that are
1211 present in initial groups are added to the new one.
1212 \param theGroups list of groups
1213 \param theName name of group to be created
1214 \return pointer on the group
1216 //=============================================================================
1217 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1218 const char* theName )
1219 throw (SALOME::SALOME_Exception)
1222 _preMeshInfo->FullLoadFromFile();
1225 return SMESH::SMESH_Group::_nil();
1227 SMESH::SMESH_Group_var aResGrp;
1231 vector< int > anIds;
1232 SMESH::ElementType aType = SMESH::ALL;
1233 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1235 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1236 if ( CORBA::is_nil( aGrp ) )
1240 SMESH::ElementType aCurrType = aGrp->GetType();
1241 if ( aType == SMESH::ALL )
1245 if ( aType != aCurrType )
1246 return SMESH::SMESH_Group::_nil();
1250 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1251 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1253 int aCurrId = aCurrIds[ i ];
1254 anIds.push_back( aCurrId );
1261 aResGrp = CreateGroup( aType, theName );
1262 if ( aResGrp->_is_nil() )
1263 return SMESH::SMESH_Group::_nil();
1265 // Create array of identifiers
1266 SMESH::long_array_var aResIds = new SMESH::long_array;
1267 aResIds->length( anIds.size() );
1269 for ( size_t i = 0; i<anIds.size(); i++ )
1270 aResIds[ i ] = anIds[i];
1271 aResGrp->Add( aResIds );
1273 // Update Python script
1274 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1275 << &theGroups << ", '" << theName << "' )";
1277 SMESH_CATCH( SMESH::throwCorbaException );
1279 return aResGrp._retn();
1282 //=============================================================================
1284 * New group is created. All mesh elements that are
1285 * present in both initial groups are added to the new one.
1287 //=============================================================================
1288 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1289 SMESH::SMESH_GroupBase_ptr theGroup2,
1290 const char* theName )
1291 throw (SALOME::SALOME_Exception)
1293 SMESH::SMESH_Group_var aResGrp;
1297 _preMeshInfo->FullLoadFromFile();
1299 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1300 theGroup1->GetType() != theGroup2->GetType() )
1301 return SMESH::SMESH_Group::_nil();
1305 // Create Intersection
1306 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1307 if ( aResGrp->_is_nil() )
1310 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1311 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1313 TColStd_MapOfInteger aMap1;
1315 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1316 aMap1.Add( anIds1[ i1 ] );
1318 TColStd_SequenceOfInteger aSeq;
1319 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1320 if ( aMap1.Contains( anIds2[ i2 ] ) )
1321 aSeq.Append( anIds2[ i2 ] );
1323 SMESH::long_array_var aResIds = new SMESH::long_array;
1324 aResIds->length( aSeq.Length() );
1325 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1326 aResIds[ resI ] = aSeq( resI + 1 );
1327 aResGrp->Add( aResIds );
1329 // Update Python script
1330 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1331 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1333 SMESH_CATCH( SMESH::throwCorbaException );
1335 return aResGrp._retn();
1338 //=============================================================================
1340 \brief Intersect list of groups. New group is created. All mesh elements that
1341 are present in all initial groups simultaneously are added to the new one.
1342 \param theGroups list of groups
1343 \param theName name of group to be created
1344 \return pointer on the group
1346 //=============================================================================
1347 SMESH::SMESH_Group_ptr
1348 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1349 const char* theName )
1350 throw (SALOME::SALOME_Exception)
1352 SMESH::SMESH_Group_var aResGrp;
1356 _preMeshInfo->FullLoadFromFile();
1359 return SMESH::SMESH_Group::_nil();
1361 NCollection_DataMap< int, int > anIdToCount;
1362 SMESH::ElementType aType = SMESH::ALL;
1363 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1365 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1366 if ( CORBA::is_nil( aGrp ) )
1370 SMESH::ElementType aCurrType = aGrp->GetType();
1371 if ( aType == SMESH::ALL )
1375 if ( aType != aCurrType )
1376 return SMESH::SMESH_Group::_nil();
1379 // calculates number of occurance ids in groups
1380 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1381 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1383 int aCurrId = aCurrIds[ i ];
1384 if ( !anIdToCount.IsBound( aCurrId ) )
1385 anIdToCount.Bind( aCurrId, 1 );
1387 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1391 // create map of ids
1392 int nbGrp = theGroups.length();
1393 vector< int > anIds;
1394 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1395 for ( ; anIter.More(); anIter.Next() )
1397 int aCurrId = anIter.Key();
1398 int aCurrNb = anIter.Value();
1399 if ( aCurrNb == nbGrp )
1400 anIds.push_back( aCurrId );
1406 aResGrp = CreateGroup( aType, theName );
1407 if ( aResGrp->_is_nil() )
1408 return SMESH::SMESH_Group::_nil();
1410 // Create array of identifiers
1411 SMESH::long_array_var aResIds = new SMESH::long_array;
1412 aResIds->length( anIds.size() );
1414 for ( size_t i = 0; i<anIds.size(); i++ )
1415 aResIds[ i ] = anIds[i];
1416 aResGrp->Add( aResIds );
1418 // Update Python script
1419 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1420 << &theGroups << ", '" << theName << "' )";
1422 SMESH_CATCH( SMESH::throwCorbaException );
1424 return aResGrp._retn();
1427 //=============================================================================
1429 * New group is created. All mesh elements that are present in
1430 * main group but do not present in tool group are added to the new one
1432 //=============================================================================
1433 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1434 SMESH::SMESH_GroupBase_ptr theGroup2,
1435 const char* theName )
1436 throw (SALOME::SALOME_Exception)
1438 SMESH::SMESH_Group_var aResGrp;
1442 _preMeshInfo->FullLoadFromFile();
1444 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1445 theGroup1->GetType() != theGroup2->GetType() )
1446 return SMESH::SMESH_Group::_nil();
1451 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1452 if ( aResGrp->_is_nil() )
1455 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1456 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1458 TColStd_MapOfInteger aMap2;
1460 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1461 aMap2.Add( anIds2[ i2 ] );
1463 TColStd_SequenceOfInteger aSeq;
1464 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1465 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1466 aSeq.Append( anIds1[ i1 ] );
1468 SMESH::long_array_var aResIds = new SMESH::long_array;
1469 aResIds->length( aSeq.Length() );
1471 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1472 aResIds[ resI ] = aSeq( resI + 1 );
1473 aResGrp->Add( aResIds );
1475 // Update Python script
1476 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1477 << theGroup1 << ", " << theGroup2 << ", '"
1478 << theName << "' )";
1480 SMESH_CATCH( SMESH::throwCorbaException );
1482 return aResGrp._retn();
1485 //=============================================================================
1487 \brief Cut lists of groups. New group is created. All mesh elements that are
1488 present in main groups but do not present in tool groups are added to the new one
1489 \param theMainGroups list of main groups
1490 \param theToolGroups list of tool groups
1491 \param theName name of group to be created
1492 \return pointer on the group
1494 //=============================================================================
1495 SMESH::SMESH_Group_ptr
1496 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1497 const SMESH::ListOfGroups& theToolGroups,
1498 const char* theName )
1499 throw (SALOME::SALOME_Exception)
1501 SMESH::SMESH_Group_var aResGrp;
1505 _preMeshInfo->FullLoadFromFile();
1508 return SMESH::SMESH_Group::_nil();
1510 set< int > aToolIds;
1511 SMESH::ElementType aType = SMESH::ALL;
1513 // iterate through tool groups
1514 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1516 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1517 if ( CORBA::is_nil( aGrp ) )
1521 SMESH::ElementType aCurrType = aGrp->GetType();
1522 if ( aType == SMESH::ALL )
1526 if ( aType != aCurrType )
1527 return SMESH::SMESH_Group::_nil();
1531 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1532 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1534 int aCurrId = aCurrIds[ i ];
1535 aToolIds.insert( aCurrId );
1539 vector< int > anIds; // result
1541 // Iterate through main group
1542 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1544 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1545 if ( CORBA::is_nil( aGrp ) )
1549 SMESH::ElementType aCurrType = aGrp->GetType();
1550 if ( aType == SMESH::ALL )
1554 if ( aType != aCurrType )
1555 return SMESH::SMESH_Group::_nil();
1559 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1560 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1562 int aCurrId = aCurrIds[ i ];
1563 if ( !aToolIds.count( aCurrId ) )
1564 anIds.push_back( aCurrId );
1571 aResGrp = CreateGroup( aType, theName );
1572 if ( aResGrp->_is_nil() )
1573 return SMESH::SMESH_Group::_nil();
1575 // Create array of identifiers
1576 SMESH::long_array_var aResIds = new SMESH::long_array;
1577 aResIds->length( anIds.size() );
1579 for (int i=0; i<anIds.size(); i++ )
1580 aResIds[ i ] = anIds[i];
1581 aResGrp->Add( aResIds );
1583 // Update Python script
1584 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1585 << &theMainGroups << ", " << &theToolGroups << ", '"
1586 << theName << "' )";
1588 SMESH_CATCH( SMESH::throwCorbaException );
1590 return aResGrp._retn();
1593 //=============================================================================
1595 \brief Create groups of entities from existing groups of superior dimensions
1597 1) extract all nodes from each group,
1598 2) combine all elements of specified dimension laying on these nodes.
1599 \param theGroups list of source groups
1600 \param theElemType dimension of elements
1601 \param theName name of new group
1602 \return pointer on new group
1606 //=============================================================================
1608 SMESH::SMESH_Group_ptr
1609 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1610 SMESH::ElementType theElemType,
1611 const char* theName )
1612 throw (SALOME::SALOME_Exception)
1614 SMESH::SMESH_Group_var aResGrp;
1618 _preMeshInfo->FullLoadFromFile();
1620 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1622 if ( !theName || !aMeshDS )
1623 return SMESH::SMESH_Group::_nil();
1625 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1631 aResGrp = CreateGroup( theElemType, theName );
1632 if ( aResGrp->_is_nil() )
1633 return SMESH::SMESH_Group::_nil();
1635 SMESHDS_GroupBase* groupBaseDS =
1636 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1637 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1639 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1641 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1642 if ( CORBA::is_nil( aGrp ) )
1645 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1646 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1648 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1650 while ( elIt->more() ) {
1651 const SMDS_MeshElement* el = elIt->next();
1652 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1653 while ( nIt->more() )
1654 resGroupCore.Add( nIt->next() );
1657 else // get elements of theElemType based on nodes of every element of group
1659 while ( elIt->more() )
1661 const SMDS_MeshElement* el = elIt->next(); // an element of group
1662 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1663 TIDSortedElemSet checkedElems;
1664 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1665 while ( nIt->more() )
1667 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1668 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1669 // check nodes of elements of theElemType around el
1670 while ( elOfTypeIt->more() )
1672 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1673 if ( !checkedElems.insert( elOfType ).second ) continue;
1675 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1676 bool allNodesOK = true;
1677 while ( nIt2->more() && allNodesOK )
1678 allNodesOK = elNodes.count( nIt2->next() );
1680 resGroupCore.Add( elOfType );
1687 // Update Python script
1688 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1689 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1691 SMESH_CATCH( SMESH::throwCorbaException );
1693 return aResGrp._retn();
1696 //================================================================================
1698 * \brief Remember GEOM group data
1700 //================================================================================
1702 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1703 CORBA::Object_ptr theSmeshObj)
1705 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1708 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1709 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1710 if ( groupSO->_is_nil() )
1713 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1714 GEOM::GEOM_IGroupOperations_wrap groupOp =
1715 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1716 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1719 _geomGroupData.push_back( TGeomGroupData() );
1720 TGeomGroupData & groupData = _geomGroupData.back();
1722 CORBA::String_var entry = groupSO->GetID();
1723 groupData._groupEntry = entry.in();
1725 for ( int i = 0; i < ids->length(); ++i )
1726 groupData._indices.insert( ids[i] );
1728 groupData._smeshObject = theSmeshObj;
1731 //================================================================================
1733 * Remove GEOM group data relating to removed smesh object
1735 //================================================================================
1737 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1739 list<TGeomGroupData>::iterator
1740 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1741 for ( ; data != dataEnd; ++data ) {
1742 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1743 _geomGroupData.erase( data );
1749 //================================================================================
1751 * \brief Return new group contents if it has been changed and update group data
1753 //================================================================================
1755 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1757 TopoDS_Shape newShape;
1760 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1761 if ( study->_is_nil() ) return newShape; // means "not changed"
1762 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1763 if ( !groupSO->_is_nil() )
1765 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1766 if ( CORBA::is_nil( groupObj )) return newShape;
1767 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1769 // get indices of group items
1770 set<int> curIndices;
1771 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1772 GEOM::GEOM_IGroupOperations_wrap groupOp =
1773 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1774 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1775 for ( int i = 0; i < ids->length(); ++i )
1776 curIndices.insert( ids[i] );
1778 if ( groupData._indices == curIndices )
1779 return newShape; // group not changed
1782 groupData._indices = curIndices;
1784 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1785 if ( !geomClient ) return newShape;
1786 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1787 geomClient->RemoveShapeFromBuffer( groupIOR );
1788 newShape = _gen_i->GeomObjectToShape( geomGroup );
1791 if ( newShape.IsNull() ) {
1792 // geom group becomes empty - return empty compound
1793 TopoDS_Compound compound;
1794 BRep_Builder().MakeCompound(compound);
1795 newShape = compound;
1802 //=============================================================================
1804 * \brief Storage of shape and index used in CheckGeomGroupModif()
1806 //=============================================================================
1807 struct TIndexedShape
1810 TopoDS_Shape _shape;
1811 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1814 //=============================================================================
1816 * \brief Update objects depending on changed geom groups
1818 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1819 * issue 0020210: Update of a smesh group after modification of the associated geom group
1821 //=============================================================================
1823 void SMESH_Mesh_i::CheckGeomGroupModif()
1825 if ( !_impl->HasShapeToMesh() ) return;
1827 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1828 if ( study->_is_nil() ) return;
1830 CORBA::Long nbEntities = NbNodes() + NbElements();
1832 // Check if group contents changed
1834 typedef map< string, TopoDS_Shape > TEntry2Geom;
1835 TEntry2Geom newGroupContents;
1837 list<TGeomGroupData>::iterator
1838 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1839 for ( ; data != dataEnd; ++data )
1841 pair< TEntry2Geom::iterator, bool > it_new =
1842 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1843 bool processedGroup = !it_new.second;
1844 TopoDS_Shape& newShape = it_new.first->second;
1845 if ( !processedGroup )
1846 newShape = newGroupShape( *data );
1847 if ( newShape.IsNull() )
1848 continue; // no changes
1851 _preMeshInfo->ForgetOrLoad();
1853 if ( processedGroup ) { // update group indices
1854 list<TGeomGroupData>::iterator data2 = data;
1855 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1856 data->_indices = data2->_indices;
1859 // Update SMESH objects according to new GEOM group contents
1861 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1862 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1864 int oldID = submesh->GetId();
1865 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1867 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1869 // update hypotheses
1870 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1871 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1872 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1874 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1875 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1877 // care of submeshes
1878 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1879 int newID = newSubmesh->GetId();
1880 if ( newID != oldID ) {
1881 _mapSubMesh [ newID ] = newSubmesh;
1882 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1883 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1884 _mapSubMesh. erase(oldID);
1885 _mapSubMesh_i. erase(oldID);
1886 _mapSubMeshIor.erase(oldID);
1887 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1892 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1893 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1894 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1896 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1898 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1899 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1900 ds->SetShape( newShape );
1905 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1906 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1908 // Remove groups and submeshes basing on removed sub-shapes
1910 TopTools_MapOfShape newShapeMap;
1911 TopoDS_Iterator shapeIt( newShape );
1912 for ( ; shapeIt.More(); shapeIt.Next() )
1913 newShapeMap.Add( shapeIt.Value() );
1915 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1916 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1918 if ( newShapeMap.Contains( shapeIt.Value() ))
1920 TopTools_IndexedMapOfShape oldShapeMap;
1921 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1922 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1924 const TopoDS_Shape& oldShape = oldShapeMap(i);
1925 int oldInd = meshDS->ShapeToIndex( oldShape );
1927 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1928 if ( i_smIor != _mapSubMeshIor.end() ) {
1929 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1932 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1933 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1935 // check if a group bases on oldInd shape
1936 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1937 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1938 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1939 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1941 RemoveGroup( i_grp->second ); // several groups can base on same shape
1942 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1947 // Reassign hypotheses and update groups after setting the new shape to mesh
1949 // collect anassigned hypotheses
1950 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1951 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1952 TShapeHypList assignedHyps;
1953 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1955 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1956 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1957 if ( !hyps.empty() ) {
1958 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1959 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1960 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1963 // collect shapes supporting groups
1964 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1965 TShapeTypeList groupData;
1966 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1967 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1968 for ( ; grIt != groups.end(); ++grIt )
1970 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1972 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1974 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1975 _impl->ShapeToMesh( newShape );
1977 // reassign hypotheses
1978 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1979 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1981 TIndexedShape& geom = indS_hyps->first;
1982 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1983 int oldID = geom._index;
1984 int newID = meshDS->ShapeToIndex( geom._shape );
1987 if ( oldID == 1 ) { // main shape
1989 geom._shape = newShape;
1991 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1992 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1993 // care of submeshes
1994 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1995 if ( newID != oldID ) {
1996 _mapSubMesh [ newID ] = newSubmesh;
1997 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1998 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1999 _mapSubMesh. erase(oldID);
2000 _mapSubMesh_i. erase(oldID);
2001 _mapSubMeshIor.erase(oldID);
2002 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2006 TShapeTypeList::iterator geomType = groupData.begin();
2007 for ( ; geomType != groupData.end(); ++geomType )
2009 const TIndexedShape& geom = geomType->first;
2010 int oldID = geom._index;
2011 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2014 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2015 CORBA::String_var name = groupSO->GetName();
2017 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2019 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2020 group_i->changeLocalId( newID );
2023 break; // everything has been updated
2026 } // loop on group data
2030 CORBA::Long newNbEntities = NbNodes() + NbElements();
2031 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2032 if ( newNbEntities != nbEntities )
2034 // Add all SObjects with icons to soToUpdateIcons
2035 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2037 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2038 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2039 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2041 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2042 i_gr != _mapGroups.end(); ++i_gr ) // groups
2043 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2046 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2047 for ( ; so != soToUpdateIcons.end(); ++so )
2048 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2051 //=============================================================================
2053 * \brief Create standalone group from a group on geometry or filter
2055 //=============================================================================
2057 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2058 throw (SALOME::SALOME_Exception)
2060 SMESH::SMESH_Group_var aGroup;
2065 _preMeshInfo->FullLoadFromFile();
2067 if ( theGroup->_is_nil() )
2068 return aGroup._retn();
2070 SMESH_GroupBase_i* aGroupToRem =
2071 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2073 return aGroup._retn();
2075 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2077 int anId = aGroupToRem->GetLocalID();
2078 if ( !_impl->ConvertToStandalone( anId ) )
2079 return aGroup._retn();
2080 removeGeomGroupData( theGroup );
2082 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2084 // remove old instance of group from own map
2085 _mapGroups.erase( anId );
2087 SALOMEDS::StudyBuilder_var builder;
2088 SALOMEDS::SObject_wrap aGroupSO;
2089 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2090 if ( !aStudy->_is_nil() ) {
2091 builder = aStudy->NewBuilder();
2092 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2093 if ( !aGroupSO->_is_nil() )
2095 // remove reference to geometry
2096 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2097 for ( ; chItr->More(); chItr->Next() )
2098 // Remove group's child SObject
2099 builder->RemoveObject( chItr->Value() );
2101 // Update Python script
2102 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2103 << aGroupSO << " )";
2105 // change icon of Group on Filter
2108 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2109 const int isEmpty = ( elemTypes->length() == 0 );
2112 SALOMEDS::GenericAttribute_wrap anAttr =
2113 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2114 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2115 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2121 // remember new group in own map
2122 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2123 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2125 // register CORBA object for persistence
2126 _gen_i->RegisterObject( aGroup );
2128 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2129 builder->SetIOR( aGroupSO, ior.in() );
2131 SMESH_CATCH( SMESH::throwCorbaException );
2133 return aGroup._retn();
2136 //=============================================================================
2140 //=============================================================================
2142 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2144 if(MYDEBUG) MESSAGE( "createSubMesh" );
2145 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2147 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2148 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2149 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2150 SMESH::SMESH_subMesh_var subMesh
2151 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2153 _mapSubMesh[subMeshId] = mySubMesh;
2154 _mapSubMesh_i[subMeshId] = subMeshServant;
2155 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2157 // register CORBA object for persistence
2158 int nextId = _gen_i->RegisterObject( subMesh );
2159 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2161 // to track changes of GEOM groups
2162 addGeomGroupData( theSubShapeObject, subMesh );
2164 return subMesh._retn();
2167 //=======================================================================
2168 //function : getSubMesh
2170 //=======================================================================
2172 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2174 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2175 if ( it == _mapSubMeshIor.end() )
2176 return SMESH::SMESH_subMesh::_nil();
2178 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2182 //=============================================================================
2186 //=============================================================================
2188 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2189 GEOM::GEOM_Object_ptr theSubShapeObject )
2191 bool isHypChanged = false;
2192 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2193 return isHypChanged;
2195 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2197 CORBA::Long shapeId = theSubMesh->GetId();
2198 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2200 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2203 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2204 isHypChanged = !hyps.empty();
2205 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2206 for ( ; hyp != hyps.end(); ++hyp )
2207 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2214 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2215 isHypChanged = ( aHypList->length() > 0 );
2216 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2217 removeHypothesis( theSubShapeObject, aHypList[i] );
2220 catch( const SALOME::SALOME_Exception& ) {
2221 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2223 removeGeomGroupData( theSubShapeObject );
2225 int subMeshId = theSubMesh->GetId();
2227 _mapSubMesh.erase(subMeshId);
2228 _mapSubMesh_i.erase(subMeshId);
2229 _mapSubMeshIor.erase(subMeshId);
2231 return isHypChanged;
2234 //=============================================================================
2238 //=============================================================================
2240 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2241 const char* theName,
2242 const TopoDS_Shape& theShape,
2243 const SMESH_PredicatePtr& thePredicate )
2245 std::string newName;
2246 if ( !theName || strlen( theName ) == 0 )
2248 std::set< std::string > presentNames;
2249 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2250 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2251 presentNames.insert( i_gr->second->GetName() );
2253 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2254 } while ( !presentNames.insert( newName ).second );
2255 theName = newName.c_str();
2258 SMESH::SMESH_GroupBase_var aGroup;
2259 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2261 SMESH_GroupBase_i* aGroupImpl;
2262 if ( !theShape.IsNull() )
2263 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2264 else if ( thePredicate )
2265 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2267 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2269 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2270 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2272 // register CORBA object for persistence
2273 int nextId = _gen_i->RegisterObject( aGroup );
2274 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2276 // to track changes of GEOM groups
2277 if ( !theShape.IsNull() ) {
2278 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2279 addGeomGroupData( geom, aGroup );
2282 return aGroup._retn();
2285 //=============================================================================
2287 * SMESH_Mesh_i::removeGroup
2289 * Should be called by ~SMESH_Group_i()
2291 //=============================================================================
2293 void SMESH_Mesh_i::removeGroup( const int theId )
2295 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2296 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2297 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2298 _mapGroups.erase( theId );
2299 removeGeomGroupData( group );
2300 if (! _impl->RemoveGroup( theId ))
2302 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2303 RemoveGroup( group );
2308 //=============================================================================
2312 //=============================================================================
2314 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2315 throw(SALOME::SALOME_Exception)
2317 SMESH::log_array_var aLog;
2321 _preMeshInfo->FullLoadFromFile();
2323 list < SMESHDS_Command * >logDS = _impl->GetLog();
2324 aLog = new SMESH::log_array;
2326 int lg = logDS.size();
2329 list < SMESHDS_Command * >::iterator its = logDS.begin();
2330 while(its != logDS.end()){
2331 SMESHDS_Command *com = *its;
2332 int comType = com->GetType();
2334 int lgcom = com->GetNumber();
2336 const list < int >&intList = com->GetIndexes();
2337 int inum = intList.size();
2339 list < int >::const_iterator ii = intList.begin();
2340 const list < double >&coordList = com->GetCoords();
2341 int rnum = coordList.size();
2343 list < double >::const_iterator ir = coordList.begin();
2344 aLog[indexLog].commandType = comType;
2345 aLog[indexLog].number = lgcom;
2346 aLog[indexLog].coords.length(rnum);
2347 aLog[indexLog].indexes.length(inum);
2348 for(int i = 0; i < rnum; i++){
2349 aLog[indexLog].coords[i] = *ir;
2350 //MESSAGE(" "<<i<<" "<<ir.Value());
2353 for(int i = 0; i < inum; i++){
2354 aLog[indexLog].indexes[i] = *ii;
2355 //MESSAGE(" "<<i<<" "<<ii.Value());
2364 SMESH_CATCH( SMESH::throwCorbaException );
2366 return aLog._retn();
2370 //=============================================================================
2374 //=============================================================================
2376 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2380 SMESH_CATCH( SMESH::throwCorbaException );
2383 //=============================================================================
2387 //=============================================================================
2389 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2394 //=============================================================================
2398 //=============================================================================
2400 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2405 //=============================================================================
2408 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2409 // issue 0020918: groups removal is caused by hyp modification
2410 // issue 0021208: to forget not loaded mesh data at hyp modification
2411 struct TCallUp_i : public SMESH_Mesh::TCallUp
2413 SMESH_Mesh_i* _mesh;
2414 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2415 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2416 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2417 virtual void Load () { _mesh->Load(); }
2421 //================================================================================
2423 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2425 //================================================================================
2427 void SMESH_Mesh_i::onHypothesisModified()
2430 _preMeshInfo->ForgetOrLoad();
2433 //=============================================================================
2437 //=============================================================================
2439 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2441 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2444 _impl->SetCallUp( new TCallUp_i(this));
2447 //=============================================================================
2451 //=============================================================================
2453 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2455 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2459 //=============================================================================
2461 * Return mesh editor
2463 //=============================================================================
2465 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2466 throw (SALOME::SALOME_Exception)
2468 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2472 _preMeshInfo->FullLoadFromFile();
2474 // Create MeshEditor
2475 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2476 aMeshEdVar = aMeshEditor->_this();
2478 // Update Python script
2479 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2481 SMESH_CATCH( SMESH::throwCorbaException );
2483 return aMeshEdVar._retn();
2486 //=============================================================================
2488 * Return mesh edition previewer
2490 //=============================================================================
2492 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2493 throw (SALOME::SALOME_Exception)
2495 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2499 _preMeshInfo->FullLoadFromFile();
2501 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2502 aMeshEdVar = aMeshEditor->_this();
2504 SMESH_CATCH( SMESH::throwCorbaException );
2506 return aMeshEdVar._retn();
2509 //================================================================================
2511 * \brief Return true if the mesh has been edited since a last total re-compute
2512 * and those modifications may prevent successful partial re-compute
2514 //================================================================================
2516 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2518 Unexpect aCatch(SALOME_SalomeException);
2519 return _impl->HasModificationsToDiscard();
2522 //================================================================================
2524 * \brief Returns a random unique color
2526 //================================================================================
2528 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2530 const int MAX_ATTEMPTS = 100;
2532 double tolerance = 0.5;
2533 SALOMEDS::Color col;
2537 // generate random color
2538 double red = (double)rand() / RAND_MAX;
2539 double green = (double)rand() / RAND_MAX;
2540 double blue = (double)rand() / RAND_MAX;
2541 // check existence in the list of the existing colors
2542 bool matched = false;
2543 std::list<SALOMEDS::Color>::const_iterator it;
2544 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2545 SALOMEDS::Color color = *it;
2546 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2547 matched = tol < tolerance;
2549 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2550 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2558 //=============================================================================
2560 * Sets auto-color mode. If it is on, groups get unique random colors
2562 //=============================================================================
2564 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2566 Unexpect aCatch(SALOME_SalomeException);
2567 _impl->SetAutoColor(theAutoColor);
2569 TPythonDump pyDump; // not to dump group->SetColor() from below code
2570 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2572 std::list<SALOMEDS::Color> aReservedColors;
2573 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2574 for ( ; it != _mapGroups.end(); it++ ) {
2575 if ( CORBA::is_nil( it->second )) continue;
2576 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2577 it->second->SetColor( aColor );
2578 aReservedColors.push_back( aColor );
2582 //=============================================================================
2584 * Returns true if auto-color mode is on
2586 //=============================================================================
2588 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2590 Unexpect aCatch(SALOME_SalomeException);
2591 return _impl->GetAutoColor();
2594 //=============================================================================
2596 * Checks if there are groups with equal names
2598 //=============================================================================
2600 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2602 return _impl->HasDuplicatedGroupNamesMED();
2605 //================================================================================
2607 * \brief Care of a file before exporting mesh into it
2609 //================================================================================
2611 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2613 TCollection_AsciiString aFullName ((char*)file);
2614 OSD_Path aPath (aFullName);
2615 OSD_File aFile (aPath);
2616 if (aFile.Exists()) {
2617 // existing filesystem node
2618 if (aFile.KindOfFile() == OSD_FILE) {
2619 if (aFile.IsWriteable()) {
2624 if (aFile.Failed()) {
2625 TCollection_AsciiString msg ("File ");
2626 msg += aFullName + " cannot be replaced.";
2627 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2630 TCollection_AsciiString msg ("File ");
2631 msg += aFullName + " cannot be overwritten.";
2632 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2635 TCollection_AsciiString msg ("Location ");
2636 msg += aFullName + " is not a file.";
2637 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2640 // nonexisting file; check if it can be created
2642 aFile.Build(OSD_WriteOnly, OSD_Protection());
2643 if (aFile.Failed()) {
2644 TCollection_AsciiString msg ("You cannot create the file ");
2645 msg += aFullName + ". Check the directory existance and access rights.";
2646 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2654 //================================================================================
2656 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2657 * \param file - file name
2658 * \param overwrite - to erase the file or not
2659 * \retval string - mesh name
2661 //================================================================================
2663 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2664 CORBA::Boolean overwrite)
2667 PrepareForWriting(file, overwrite);
2668 string aMeshName = "Mesh";
2669 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2670 if ( !aStudy->_is_nil() ) {
2671 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2672 if ( !aMeshSO->_is_nil() ) {
2673 CORBA::String_var name = aMeshSO->GetName();
2675 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2676 if ( !aStudy->GetProperties()->IsLocked() )
2678 SALOMEDS::GenericAttribute_wrap anAttr;
2679 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2680 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2681 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2682 ASSERT(!aFileName->_is_nil());
2683 aFileName->SetValue(file);
2684 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2685 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2686 ASSERT(!aFileType->_is_nil());
2687 aFileType->SetValue("FICHIERMED");
2691 // Update Python script
2692 // set name of mesh before export
2693 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2695 // check names of groups
2701 //================================================================================
2703 * \brief Export to med file
2705 //================================================================================
2707 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2708 CORBA::Boolean auto_groups,
2709 SMESH::MED_VERSION theVersion,
2710 CORBA::Boolean overwrite)
2711 throw(SALOME::SALOME_Exception)
2713 Unexpect aCatch(SALOME_SalomeException);
2715 _preMeshInfo->FullLoadFromFile();
2717 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2718 TPythonDump() << _this() << ".ExportToMEDX( r'"
2719 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2721 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2724 //================================================================================
2726 * \brief Export a mesh to a med file
2728 //================================================================================
2730 void SMESH_Mesh_i::ExportToMED (const char* file,
2731 CORBA::Boolean auto_groups,
2732 SMESH::MED_VERSION theVersion)
2733 throw(SALOME::SALOME_Exception)
2735 ExportToMEDX(file,auto_groups,theVersion,true);
2738 //================================================================================
2740 * \brief Export a mesh to a med file
2742 //================================================================================
2744 void SMESH_Mesh_i::ExportMED (const char* file,
2745 CORBA::Boolean auto_groups)
2746 throw(SALOME::SALOME_Exception)
2748 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2751 //================================================================================
2753 * \brief Export a mesh to a SAUV file
2755 //================================================================================
2757 void SMESH_Mesh_i::ExportSAUV (const char* file,
2758 CORBA::Boolean auto_groups)
2759 throw(SALOME::SALOME_Exception)
2761 Unexpect aCatch(SALOME_SalomeException);
2763 _preMeshInfo->FullLoadFromFile();
2765 string aMeshName = prepareMeshNameAndGroups(file, true);
2766 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2767 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2771 //================================================================================
2773 * \brief Export a mesh to a DAT file
2775 //================================================================================
2777 void SMESH_Mesh_i::ExportDAT (const char *file)
2778 throw(SALOME::SALOME_Exception)
2780 Unexpect aCatch(SALOME_SalomeException);
2782 _preMeshInfo->FullLoadFromFile();
2784 // Update Python script
2785 // check names of groups
2787 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2790 PrepareForWriting(file);
2791 _impl->ExportDAT(file);
2794 //================================================================================
2796 * \brief Export a mesh to an UNV file
2798 //================================================================================
2800 void SMESH_Mesh_i::ExportUNV (const char *file)
2801 throw(SALOME::SALOME_Exception)
2803 Unexpect aCatch(SALOME_SalomeException);
2805 _preMeshInfo->FullLoadFromFile();
2807 // Update Python script
2808 // check names of groups
2810 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2813 PrepareForWriting(file);
2814 _impl->ExportUNV(file);
2817 //================================================================================
2819 * \brief Export a mesh to an STL file
2821 //================================================================================
2823 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2824 throw(SALOME::SALOME_Exception)
2826 Unexpect aCatch(SALOME_SalomeException);
2828 _preMeshInfo->FullLoadFromFile();
2830 // Update Python script
2831 // check names of groups
2833 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2836 PrepareForWriting(file);
2837 _impl->ExportSTL(file, isascii);
2840 //================================================================================
2842 * \brief Export a part of mesh to a med file
2844 //================================================================================
2846 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2848 CORBA::Boolean auto_groups,
2849 ::SMESH::MED_VERSION version,
2850 ::CORBA::Boolean overwrite)
2851 throw (SALOME::SALOME_Exception)
2853 Unexpect aCatch(SALOME_SalomeException);
2855 _preMeshInfo->FullLoadFromFile();
2857 PrepareForWriting(file, overwrite);
2859 string aMeshName = "Mesh";
2860 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2861 if ( !aStudy->_is_nil() ) {
2862 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2863 if ( !SO->_is_nil() ) {
2864 CORBA::String_var name = SO->GetName();
2868 SMESH_MeshPartDS partDS( meshPart );
2869 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2871 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2872 << auto_groups << ", " << version << ", " << overwrite << " )";
2875 //================================================================================
2877 * \brief Export a part of mesh to a DAT file
2879 //================================================================================
2881 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2883 throw (SALOME::SALOME_Exception)
2885 Unexpect aCatch(SALOME_SalomeException);
2887 _preMeshInfo->FullLoadFromFile();
2889 PrepareForWriting(file);
2891 SMESH_MeshPartDS partDS( meshPart );
2892 _impl->ExportDAT(file,&partDS);
2894 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2896 //================================================================================
2898 * \brief Export a part of mesh to an UNV file
2900 //================================================================================
2902 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2904 throw (SALOME::SALOME_Exception)
2906 Unexpect aCatch(SALOME_SalomeException);
2908 _preMeshInfo->FullLoadFromFile();
2910 PrepareForWriting(file);
2912 SMESH_MeshPartDS partDS( meshPart );
2913 _impl->ExportUNV(file, &partDS);
2915 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2917 //================================================================================
2919 * \brief Export a part of mesh to an STL file
2921 //================================================================================
2923 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2925 ::CORBA::Boolean isascii)
2926 throw (SALOME::SALOME_Exception)
2928 Unexpect aCatch(SALOME_SalomeException);
2930 _preMeshInfo->FullLoadFromFile();
2932 PrepareForWriting(file);
2934 SMESH_MeshPartDS partDS( meshPart );
2935 _impl->ExportSTL(file, isascii, &partDS);
2937 TPythonDump() << _this() << ".ExportPartToSTL( "
2938 << meshPart<< ", r'" << file << "', " << isascii << ")";
2941 //================================================================================
2943 * \brief Export a part of mesh to an STL file
2945 //================================================================================
2947 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2949 CORBA::Boolean overwrite)
2950 throw (SALOME::SALOME_Exception)
2953 Unexpect aCatch(SALOME_SalomeException);
2955 _preMeshInfo->FullLoadFromFile();
2957 PrepareForWriting(file,overwrite);
2959 SMESH_MeshPartDS partDS( meshPart );
2960 _impl->ExportCGNS(file, &partDS);
2962 TPythonDump() << _this() << ".ExportCGNS( "
2963 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2965 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2969 //================================================================================
2971 * \brief Export a part of mesh to a GMF file
2973 //================================================================================
2975 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2977 bool withRequiredGroups)
2978 throw (SALOME::SALOME_Exception)
2980 Unexpect aCatch(SALOME_SalomeException);
2982 _preMeshInfo->FullLoadFromFile();
2984 PrepareForWriting(file,/*overwrite=*/true);
2986 SMESH_MeshPartDS partDS( meshPart );
2987 _impl->ExportGMF(file, &partDS, withRequiredGroups);
2989 TPythonDump() << _this() << ".ExportGMF( "
2990 << meshPart<< ", r'"
2992 << withRequiredGroups << ")";
2995 //=============================================================================
2997 * Return implementation of SALOME_MED::MESH interfaces
2999 //=============================================================================
3001 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3003 Unexpect aCatch(SALOME_SalomeException);
3005 _preMeshInfo->FullLoadFromFile();
3007 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3008 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3009 return aMesh._retn();
3012 //=============================================================================
3014 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3016 Unexpect aCatch(SALOME_SalomeException);
3018 return _preMeshInfo->NbNodes();
3020 return _impl->NbNodes();
3023 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3025 Unexpect aCatch(SALOME_SalomeException);
3027 return _preMeshInfo->NbElements();
3029 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3032 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3034 Unexpect aCatch(SALOME_SalomeException);
3036 return _preMeshInfo->Nb0DElements();
3038 return _impl->Nb0DElements();
3041 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3043 Unexpect aCatch(SALOME_SalomeException);
3045 return _preMeshInfo->NbBalls();
3047 return _impl->NbBalls();
3050 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3052 Unexpect aCatch(SALOME_SalomeException);
3054 return _preMeshInfo->NbEdges();
3056 return _impl->NbEdges();
3059 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3060 throw(SALOME::SALOME_Exception)
3062 Unexpect aCatch(SALOME_SalomeException);
3064 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3066 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3069 //=============================================================================
3071 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3073 Unexpect aCatch(SALOME_SalomeException);
3075 return _preMeshInfo->NbFaces();
3077 return _impl->NbFaces();
3080 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3082 Unexpect aCatch(SALOME_SalomeException);
3084 return _preMeshInfo->NbTriangles();
3086 return _impl->NbTriangles();
3089 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3091 Unexpect aCatch(SALOME_SalomeException);
3093 return _preMeshInfo->NbQuadrangles();
3095 return _impl->NbQuadrangles();
3098 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3100 Unexpect aCatch(SALOME_SalomeException);
3102 return _preMeshInfo->NbBiQuadQuadrangles();
3104 return _impl->NbBiQuadQuadrangles();
3107 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3109 Unexpect aCatch(SALOME_SalomeException);
3111 return _preMeshInfo->NbPolygons();
3113 return _impl->NbPolygons();
3116 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3117 throw(SALOME::SALOME_Exception)
3119 Unexpect aCatch(SALOME_SalomeException);
3121 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3123 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3126 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3127 throw(SALOME::SALOME_Exception)
3129 Unexpect aCatch(SALOME_SalomeException);
3131 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3133 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3136 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3137 throw(SALOME::SALOME_Exception)
3139 Unexpect aCatch(SALOME_SalomeException);
3141 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3143 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3146 //=============================================================================
3148 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3150 Unexpect aCatch(SALOME_SalomeException);
3152 return _preMeshInfo->NbVolumes();
3154 return _impl->NbVolumes();
3157 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3159 Unexpect aCatch(SALOME_SalomeException);
3161 return _preMeshInfo->NbTetras();
3163 return _impl->NbTetras();
3166 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3168 Unexpect aCatch(SALOME_SalomeException);
3170 return _preMeshInfo->NbHexas();
3172 return _impl->NbHexas();
3175 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3177 Unexpect aCatch(SALOME_SalomeException);
3179 return _preMeshInfo->NbTriQuadHexas();
3181 return _impl->NbTriQuadraticHexas();
3184 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3186 Unexpect aCatch(SALOME_SalomeException);
3188 return _preMeshInfo->NbPyramids();
3190 return _impl->NbPyramids();
3193 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3195 Unexpect aCatch(SALOME_SalomeException);
3197 return _preMeshInfo->NbPrisms();
3199 return _impl->NbPrisms();
3202 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3204 Unexpect aCatch(SALOME_SalomeException);
3206 return _preMeshInfo->NbHexPrisms();
3208 return _impl->NbHexagonalPrisms();
3211 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3213 Unexpect aCatch(SALOME_SalomeException);
3215 return _preMeshInfo->NbPolyhedrons();
3217 return _impl->NbPolyhedrons();
3220 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3221 throw(SALOME::SALOME_Exception)
3223 Unexpect aCatch(SALOME_SalomeException);
3225 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3227 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3230 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3231 throw(SALOME::SALOME_Exception)
3233 Unexpect aCatch(SALOME_SalomeException);
3235 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3237 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3240 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3241 throw(SALOME::SALOME_Exception)
3243 Unexpect aCatch(SALOME_SalomeException);
3245 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3247 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3250 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3251 throw(SALOME::SALOME_Exception)
3253 Unexpect aCatch(SALOME_SalomeException);
3255 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3257 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3260 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3261 throw(SALOME::SALOME_Exception)
3263 Unexpect aCatch(SALOME_SalomeException);
3265 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3267 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3270 //=============================================================================
3272 * Returns nb of published sub-meshes
3274 //=============================================================================
3276 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3278 Unexpect aCatch(SALOME_SalomeException);
3279 return _mapSubMesh_i.size();
3282 //=============================================================================
3284 * Dumps mesh into a string
3286 //=============================================================================
3288 char* SMESH_Mesh_i::Dump()
3292 return CORBA::string_dup( os.str().c_str() );
3295 //=============================================================================
3297 * Method of SMESH_IDSource interface
3299 //=============================================================================
3301 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3303 return GetElementsId();
3306 //=============================================================================
3308 * Returns ids of all elements
3310 //=============================================================================
3312 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3313 throw (SALOME::SALOME_Exception)
3315 Unexpect aCatch(SALOME_SalomeException);
3317 _preMeshInfo->FullLoadFromFile();
3319 SMESH::long_array_var aResult = new SMESH::long_array();
3320 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3322 if ( aSMESHDS_Mesh == NULL )
3323 return aResult._retn();
3325 long nbElements = NbElements();
3326 aResult->length( nbElements );
3327 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3328 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3329 aResult[i] = anIt->next()->GetID();
3331 return aResult._retn();
3335 //=============================================================================
3337 * Returns ids of all elements of given type
3339 //=============================================================================
3341 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3342 throw (SALOME::SALOME_Exception)
3344 Unexpect aCatch(SALOME_SalomeException);
3346 _preMeshInfo->FullLoadFromFile();
3348 SMESH::long_array_var aResult = new SMESH::long_array();
3349 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3351 if ( aSMESHDS_Mesh == NULL )
3352 return aResult._retn();
3354 long nbElements = NbElements();
3356 // No sense in returning ids of elements along with ids of nodes:
3357 // when theElemType == SMESH::ALL, return node ids only if
3358 // there are no elements
3359 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3360 return GetNodesId();
3362 aResult->length( nbElements );
3366 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3367 while ( i < nbElements && anIt->more() ) {
3368 const SMDS_MeshElement* anElem = anIt->next();
3369 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3370 aResult[i++] = anElem->GetID();
3373 aResult->length( i );
3375 return aResult._retn();
3378 //=============================================================================
3380 * Returns ids of all nodes
3382 //=============================================================================
3384 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3385 throw (SALOME::SALOME_Exception)
3387 Unexpect aCatch(SALOME_SalomeException);
3389 _preMeshInfo->FullLoadFromFile();
3391 SMESH::long_array_var aResult = new SMESH::long_array();
3392 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3394 if ( aSMESHDS_Mesh == NULL )
3395 return aResult._retn();
3397 long nbNodes = NbNodes();
3398 aResult->length( nbNodes );
3399 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3400 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3401 aResult[i] = anIt->next()->GetID();
3403 return aResult._retn();
3406 //=============================================================================
3410 //=============================================================================
3412 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3413 throw (SALOME::SALOME_Exception)
3415 SMESH::ElementType type;
3419 _preMeshInfo->FullLoadFromFile();
3421 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3423 SMESH_CATCH( SMESH::throwCorbaException );
3428 //=============================================================================
3432 //=============================================================================
3434 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3435 throw (SALOME::SALOME_Exception)
3438 _preMeshInfo->FullLoadFromFile();
3440 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3442 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3444 return ( SMESH::EntityType ) e->GetEntityType();
3447 //=============================================================================
3449 * Returns ID of elements for given submesh
3451 //=============================================================================
3452 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3453 throw (SALOME::SALOME_Exception)
3455 SMESH::long_array_var aResult = new SMESH::long_array();
3459 _preMeshInfo->FullLoadFromFile();
3461 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3462 if(!SM) return aResult._retn();
3464 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3465 if(!SDSM) return aResult._retn();
3467 aResult->length(SDSM->NbElements());
3469 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3471 while ( eIt->more() ) {
3472 aResult[i++] = eIt->next()->GetID();
3475 SMESH_CATCH( SMESH::throwCorbaException );
3477 return aResult._retn();
3481 //=============================================================================
3483 * Returns ID of nodes for given submesh
3484 * If param all==true - returns all nodes, else -
3485 * returns only nodes on shapes.
3487 //=============================================================================
3488 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3490 throw (SALOME::SALOME_Exception)
3492 SMESH::long_array_var aResult = new SMESH::long_array();
3496 _preMeshInfo->FullLoadFromFile();
3498 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3499 if(!SM) return aResult._retn();
3501 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3502 if(!SDSM) return aResult._retn();
3505 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3506 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3507 while ( nIt->more() ) {
3508 const SMDS_MeshNode* elem = nIt->next();
3509 theElems.insert( elem->GetID() );
3512 else { // all nodes of submesh elements
3513 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3514 while ( eIt->more() ) {
3515 const SMDS_MeshElement* anElem = eIt->next();
3516 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3517 while ( nIt->more() ) {
3518 const SMDS_MeshElement* elem = nIt->next();
3519 theElems.insert( elem->GetID() );
3524 aResult->length(theElems.size());
3525 set<int>::iterator itElem;
3527 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3528 aResult[i++] = *itElem;
3530 SMESH_CATCH( SMESH::throwCorbaException );
3532 return aResult._retn();
3535 //=============================================================================
3537 * Returns type of elements for given submesh
3539 //=============================================================================
3541 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3542 throw (SALOME::SALOME_Exception)
3544 SMESH::ElementType type;
3548 _preMeshInfo->FullLoadFromFile();
3550 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3551 if(!SM) return SMESH::ALL;
3553 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3554 if(!SDSM) return SMESH::ALL;
3556 if(SDSM->NbElements()==0)
3557 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3559 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3560 const SMDS_MeshElement* anElem = eIt->next();
3562 type = ( SMESH::ElementType ) anElem->GetType();
3564 SMESH_CATCH( SMESH::throwCorbaException );
3570 //=============================================================================
3572 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3574 //=============================================================================
3576 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3579 _preMeshInfo->FullLoadFromFile();
3581 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3583 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3588 //=============================================================================
3590 * Get XYZ coordinates of node as list of double
3591 * If there is not node for given ID - returns empty list
3593 //=============================================================================
3595 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3598 _preMeshInfo->FullLoadFromFile();
3600 SMESH::double_array_var aResult = new SMESH::double_array();
3601 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3602 if ( aSMESHDS_Mesh == NULL )
3603 return aResult._retn();
3606 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3608 return aResult._retn();
3612 aResult[0] = aNode->X();
3613 aResult[1] = aNode->Y();
3614 aResult[2] = aNode->Z();
3615 return aResult._retn();
3619 //=============================================================================
3621 * For given node returns list of IDs of inverse elements
3622 * If there is not node for given ID - returns empty list
3624 //=============================================================================
3626 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3629 _preMeshInfo->FullLoadFromFile();
3631 SMESH::long_array_var aResult = new SMESH::long_array();
3632 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3633 if ( aSMESHDS_Mesh == NULL )
3634 return aResult._retn();
3637 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3639 return aResult._retn();
3641 // find inverse elements
3642 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3643 TColStd_SequenceOfInteger IDs;
3644 while(eIt->more()) {
3645 const SMDS_MeshElement* elem = eIt->next();
3646 IDs.Append(elem->GetID());
3648 if(IDs.Length()>0) {
3649 aResult->length(IDs.Length());
3651 for(; i<=IDs.Length(); i++) {
3652 aResult[i-1] = IDs.Value(i);
3655 return aResult._retn();
3658 //=============================================================================
3660 * \brief Return position of a node on shape
3662 //=============================================================================
3664 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3667 _preMeshInfo->FullLoadFromFile();
3669 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3670 aNodePosition->shapeID = 0;
3671 aNodePosition->shapeType = GEOM::SHAPE;
3673 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3674 if ( !mesh ) return aNodePosition;
3676 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3678 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3680 aNodePosition->shapeID = aNode->getshapeId();
3681 switch ( pos->GetTypeOfPosition() ) {
3683 aNodePosition->shapeType = GEOM::EDGE;
3684 aNodePosition->params.length(1);
3685 aNodePosition->params[0] =
3686 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3689 aNodePosition->shapeType = GEOM::FACE;
3690 aNodePosition->params.length(2);
3691 aNodePosition->params[0] =
3692 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3693 aNodePosition->params[1] =
3694 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3696 case SMDS_TOP_VERTEX:
3697 aNodePosition->shapeType = GEOM::VERTEX;
3699 case SMDS_TOP_3DSPACE:
3700 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3701 aNodePosition->shapeType = GEOM::SOLID;
3702 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3703 aNodePosition->shapeType = GEOM::SHELL;
3709 return aNodePosition;
3712 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3715 _preMeshInfo->FullLoadFromFile();
3717 SMESH::ElementPosition anElementPosition;
3718 anElementPosition.shapeID = 0;
3719 anElementPosition.shapeType = GEOM::SHAPE;
3721 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3722 if ( !mesh ) return anElementPosition;
3724 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3726 anElementPosition.shapeID = anElem->getshapeId();
3727 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3728 if ( !aSp.IsNull() ) {
3729 switch ( aSp.ShapeType() ) {
3731 anElementPosition.shapeType = GEOM::EDGE;
3734 anElementPosition.shapeType = GEOM::FACE;
3737 anElementPosition.shapeType = GEOM::VERTEX;
3740 anElementPosition.shapeType = GEOM::SOLID;
3743 anElementPosition.shapeType = GEOM::SHELL;
3749 return anElementPosition;
3752 //=============================================================================
3754 * If given element is node returns IDs of shape from position
3755 * If there is not node for given ID - returns -1
3757 //=============================================================================
3759 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3762 _preMeshInfo->FullLoadFromFile();
3764 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3765 if ( aSMESHDS_Mesh == NULL )
3769 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3771 return aNode->getshapeId();
3778 //=============================================================================
3780 * For given element returns ID of result shape after
3781 * ::FindShape() from SMESH_MeshEditor
3782 * If there is not element for given ID - returns -1
3784 //=============================================================================
3786 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3789 _preMeshInfo->FullLoadFromFile();
3791 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3792 if ( aSMESHDS_Mesh == NULL )
3795 // try to find element
3796 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3800 ::SMESH_MeshEditor aMeshEditor(_impl);
3801 int index = aMeshEditor.FindShape( elem );
3809 //=============================================================================
3811 * Returns number of nodes for given element
3812 * If there is not element for given ID - returns -1
3814 //=============================================================================
3816 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3819 _preMeshInfo->FullLoadFromFile();
3821 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3822 if ( aSMESHDS_Mesh == NULL ) return -1;
3823 // try to find element
3824 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3825 if(!elem) return -1;
3826 return elem->NbNodes();
3830 //=============================================================================
3832 * Returns ID of node by given index for given element
3833 * If there is not element for given ID - returns -1
3834 * If there is not node for given index - returns -2
3836 //=============================================================================
3838 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3841 _preMeshInfo->FullLoadFromFile();
3843 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3844 if ( aSMESHDS_Mesh == NULL ) return -1;
3845 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3846 if(!elem) return -1;
3847 if( index>=elem->NbNodes() || index<0 ) return -1;
3848 return elem->GetNode(index)->GetID();
3851 //=============================================================================
3853 * Returns IDs of nodes of given element
3855 //=============================================================================
3857 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3860 _preMeshInfo->FullLoadFromFile();
3862 SMESH::long_array_var aResult = new SMESH::long_array();
3863 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3865 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3867 aResult->length( elem->NbNodes() );
3868 for ( int i = 0; i < elem->NbNodes(); ++i )
3869 aResult[ i ] = elem->GetNode( i )->GetID();
3872 return aResult._retn();
3875 //=============================================================================
3877 * Returns true if given node is medium node
3878 * in given quadratic element
3880 //=============================================================================
3882 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3885 _preMeshInfo->FullLoadFromFile();
3887 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3888 if ( aSMESHDS_Mesh == NULL ) return false;
3890 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3891 if(!aNode) return false;
3892 // try to find element
3893 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3894 if(!elem) return false;
3896 return elem->IsMediumNode(aNode);
3900 //=============================================================================
3902 * Returns true if given node is medium node
3903 * in one of quadratic elements
3905 //=============================================================================
3907 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3908 SMESH::ElementType theElemType)
3911 _preMeshInfo->FullLoadFromFile();
3913 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3914 if ( aSMESHDS_Mesh == NULL ) return false;
3917 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3918 if(!aNode) return false;
3920 SMESH_MesherHelper aHelper( *(_impl) );
3922 SMDSAbs_ElementType aType;
3923 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3924 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3925 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3926 else aType = SMDSAbs_All;
3928 return aHelper.IsMedium(aNode,aType);
3932 //=============================================================================
3934 * Returns number of edges for given element
3936 //=============================================================================
3938 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3941 _preMeshInfo->FullLoadFromFile();
3943 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3944 if ( aSMESHDS_Mesh == NULL ) return -1;
3945 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3946 if(!elem) return -1;
3947 return elem->NbEdges();
3951 //=============================================================================
3953 * Returns number of faces for given element
3955 //=============================================================================
3957 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3960 _preMeshInfo->FullLoadFromFile();
3962 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3963 if ( aSMESHDS_Mesh == NULL ) return -1;
3964 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3965 if(!elem) return -1;
3966 return elem->NbFaces();
3969 //=======================================================================
3970 //function : GetElemFaceNodes
3971 //purpose : Returns nodes of given face (counted from zero) for given element.
3972 //=======================================================================
3974 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3975 CORBA::Short faceIndex)
3978 _preMeshInfo->FullLoadFromFile();
3980 SMESH::long_array_var aResult = new SMESH::long_array();
3981 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3983 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3985 SMDS_VolumeTool vtool( elem );
3986 if ( faceIndex < vtool.NbFaces() )
3988 aResult->length( vtool.NbFaceNodes( faceIndex ));
3989 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3990 for ( int i = 0; i < aResult->length(); ++i )
3991 aResult[ i ] = nn[ i ]->GetID();
3995 return aResult._retn();
3998 //=======================================================================
3999 //function : FindElementByNodes
4000 //purpose : Returns an element based on all given nodes.
4001 //=======================================================================
4003 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4006 _preMeshInfo->FullLoadFromFile();
4008 CORBA::Long elemID(0);
4009 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4011 vector< const SMDS_MeshNode * > nn( nodes.length() );
4012 for ( int i = 0; i < nodes.length(); ++i )
4013 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4016 const SMDS_MeshElement* elem = mesh->FindElement( nn );
4017 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4018 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4019 _impl->NbVolumes( ORDER_QUADRATIC )))
4020 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4022 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4027 //=============================================================================
4029 * Returns true if given element is polygon
4031 //=============================================================================
4033 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4036 _preMeshInfo->FullLoadFromFile();
4038 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4039 if ( aSMESHDS_Mesh == NULL ) return false;
4040 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4041 if(!elem) return false;
4042 return elem->IsPoly();
4046 //=============================================================================
4048 * Returns true if given element is quadratic
4050 //=============================================================================
4052 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4055 _preMeshInfo->FullLoadFromFile();
4057 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4058 if ( aSMESHDS_Mesh == NULL ) return false;
4059 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4060 if(!elem) return false;
4061 return elem->IsQuadratic();
4064 //=============================================================================
4066 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4068 //=============================================================================
4070 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4073 _preMeshInfo->FullLoadFromFile();
4075 if ( const SMDS_BallElement* ball =
4076 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4077 return ball->GetDiameter();
4082 //=============================================================================
4084 * Returns bary center for given element
4086 //=============================================================================
4088 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4091 _preMeshInfo->FullLoadFromFile();
4093 SMESH::double_array_var aResult = new SMESH::double_array();
4094 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4095 if ( aSMESHDS_Mesh == NULL )
4096 return aResult._retn();
4098 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4100 return aResult._retn();
4102 if(elem->GetType()==SMDSAbs_Volume) {
4103 SMDS_VolumeTool aTool;
4104 if(aTool.Set(elem)) {
4106 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4111 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4113 double x=0., y=0., z=0.;
4114 for(; anIt->more(); ) {
4116 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4130 return aResult._retn();
4134 //=============================================================================
4136 * Create and publish group servants if any groups were imported or created anyhow
4138 //=============================================================================
4140 void SMESH_Mesh_i::CreateGroupServants()
4142 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4145 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4146 while ( groupIt->more() )
4148 ::SMESH_Group* group = groupIt->next();
4149 int anId = group->GetGroupDS()->GetID();
4151 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4152 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4154 addedIDs.insert( anId );
4156 SMESH_GroupBase_i* aGroupImpl;
4158 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4159 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4161 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4162 shape = groupOnGeom->GetShape();
4165 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4168 SMESH::SMESH_GroupBase_var groupVar =
4169 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4170 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4172 // register CORBA object for persistence
4173 int nextId = _gen_i->RegisterObject( groupVar );
4174 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4176 // publishing the groups in the study
4177 if ( !aStudy->_is_nil() ) {
4178 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4179 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4182 if ( !addedIDs.empty() )
4185 set<int>::iterator id = addedIDs.begin();
4186 for ( ; id != addedIDs.end(); ++id )
4188 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4189 int i = std::distance( _mapGroups.begin(), it );
4190 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4195 //=============================================================================
4197 * \brief Return groups cantained in _mapGroups by their IDs
4199 //=============================================================================
4201 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4203 int nbGroups = groupIDs.size();
4204 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4205 aList->length( nbGroups );
4207 list<int>::const_iterator ids = groupIDs.begin();
4208 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4210 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4211 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4212 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4214 aList->length( nbGroups );
4215 return aList._retn();
4218 //=============================================================================
4220 * \brief Return information about imported file
4222 //=============================================================================
4224 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4226 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4227 if ( !res.operator->() ) {
4228 res = new SALOME_MED::MedFileInfo;
4230 res->fileSize = res->major = res->minor = res->release = -1;
4235 //=============================================================================
4237 * \brief Pass names of mesh groups from study to mesh DS
4239 //=============================================================================
4241 void SMESH_Mesh_i::checkGroupNames()
4243 int nbGrp = NbGroups();
4247 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4248 if ( aStudy->_is_nil() )
4249 return; // nothing to do
4251 SMESH::ListOfGroups* grpList = 0;
4252 // avoid dump of "GetGroups"
4254 // store python dump into a local variable inside local scope
4255 SMESH::TPythonDump pDump; // do not delete this line of code
4256 grpList = GetGroups();
4259 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4260 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4263 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4264 if ( aGrpSO->_is_nil() )
4266 // correct name of the mesh group if necessary
4267 const char* guiName = aGrpSO->GetName();
4268 if ( strcmp(guiName, aGrp->GetName()) )
4269 aGrp->SetName( guiName );
4273 //=============================================================================
4275 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4277 //=============================================================================
4278 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4280 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4281 // CORBA::string_dup(theParameters));
4282 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4285 //=============================================================================
4287 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4289 //=============================================================================
4290 char* SMESH_Mesh_i::GetParameters()
4292 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4293 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4296 //=============================================================================
4298 * \brief Returns list of notebook variables used for last Mesh operation
4300 //=============================================================================
4301 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4303 SMESH::string_array_var aResult = new SMESH::string_array();
4304 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4306 char *aParameters = GetParameters();
4307 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4308 if(!aStudy->_is_nil()) {
4309 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4310 if(aSections->length() > 0) {
4311 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4312 aResult->length(aVars.length());
4313 for(int i = 0;i < aVars.length();i++)
4314 aResult[i] = CORBA::string_dup( aVars[i]);
4318 return aResult._retn();
4321 //=======================================================================
4322 //function : GetTypes
4323 //purpose : Returns types of elements it contains
4324 //=======================================================================
4326 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4329 return _preMeshInfo->GetTypes();
4331 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4335 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4336 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4337 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4338 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4339 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4340 types->length( nbTypes );
4342 return types._retn();
4345 //=======================================================================
4346 //function : GetMesh
4347 //purpose : Returns self
4348 //=======================================================================
4350 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4352 return SMESH::SMESH_Mesh::_duplicate( _this() );
4355 //=======================================================================
4356 //function : IsMeshInfoCorrect
4357 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4358 // * happen if mesh data is not yet fully loaded from the file of study.
4359 //=======================================================================
4361 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4363 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4366 //=============================================================================
4368 * \brief Returns statistic of mesh elements
4370 //=============================================================================
4372 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4375 return _preMeshInfo->GetMeshInfo();
4377 SMESH::long_array_var aRes = new SMESH::long_array();
4378 aRes->length(SMESH::Entity_Last);
4379 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4381 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4383 return aRes._retn();
4384 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4385 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4386 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4387 return aRes._retn();
4390 //=============================================================================
4392 * \brief Collect statistic of mesh elements given by iterator
4394 //=============================================================================
4396 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4397 SMESH::long_array& theInfo)
4399 if (!theItr) return;
4400 while (theItr->more())
4401 theInfo[ theItr->next()->GetEntityType() ]++;
4404 //=============================================================================
4405 namespace // Finding concurrent hypotheses
4406 //=============================================================================
4410 * \brief mapping of mesh dimension into shape type
4412 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4414 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4416 case 0: aType = TopAbs_VERTEX; break;
4417 case 1: aType = TopAbs_EDGE; break;
4418 case 2: aType = TopAbs_FACE; break;
4420 default:aType = TopAbs_SOLID; break;
4425 //-----------------------------------------------------------------------------
4427 * \brief Internal structure used to find concurent submeshes
4429 * It represents a pair < submesh, concurent dimension >, where
4430 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4431 * with another submesh. In other words, it is dimension of a hypothesis assigned
4438 int _dim; //!< a dimension the algo can build (concurrent dimension)
4439 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4440 TopTools_MapOfShape _shapeMap;
4441 SMESH_subMesh* _subMesh;
4442 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4444 //-----------------------------------------------------------------------------
4445 // Return the algorithm
4446 const SMESH_Algo* GetAlgo() const
4447 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4449 //-----------------------------------------------------------------------------
4451 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4453 const TopoDS_Shape& theShape)
4455 _subMesh = (SMESH_subMesh*)theSubMesh;
4456 SetShape( theDim, theShape );
4459 //-----------------------------------------------------------------------------
4461 void SetShape(const int theDim,
4462 const TopoDS_Shape& theShape)
4465 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4466 if (_dim >= _ownDim)
4467 _shapeMap.Add( theShape );
4469 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4470 for( ; anExp.More(); anExp.Next() )
4471 _shapeMap.Add( anExp.Current() );
4475 //-----------------------------------------------------------------------------
4476 //! Check sharing of sub-shapes
4477 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4478 const TopTools_MapOfShape& theToFind,
4479 const TopAbs_ShapeEnum theType)
4481 bool isShared = false;
4482 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4483 for (; !isShared && anItr.More(); anItr.Next() )
4485 const TopoDS_Shape aSubSh = anItr.Key();
4486 // check for case when concurrent dimensions are same
4487 isShared = theToFind.Contains( aSubSh );
4488 // check for sub-shape with concurrent dimension
4489 TopExp_Explorer anExp( aSubSh, theType );
4490 for ( ; !isShared && anExp.More(); anExp.Next() )
4491 isShared = theToFind.Contains( anExp.Current() );
4496 //-----------------------------------------------------------------------------
4497 //! check algorithms
4498 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4499 const SMESHDS_Hypothesis* theA2)
4501 if ( !theA1 || !theA2 ||
4502 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4503 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4504 return false; // one of the hypothesis is not algorithm
4505 // check algorithm names (should be equal)
4506 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4510 //-----------------------------------------------------------------------------
4511 //! Check if sub-shape hypotheses are concurrent
4512 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4514 if ( _subMesh == theOther->_subMesh )
4515 return false; // same sub-shape - should not be
4517 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4518 // any of the two submeshes is not on COMPOUND shape )
4519 // -> no concurrency
4520 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4521 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4522 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4523 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4524 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4527 // bool checkSubShape = ( _dim >= theOther->_dim )
4528 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4529 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4530 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4531 if ( !checkSubShape )
4534 // check algorithms to be same
4535 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4536 return true; // different algorithms -> concurrency !
4538 // check hypothesises for concurrence (skip first as algorithm)
4540 // pointers should be same, because it is referened from mesh hypothesis partition
4541 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4542 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4543 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4544 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4546 // the submeshes are concurrent if their algorithms has different parameters
4547 return nbSame != theOther->_hypotheses.size() - 1;
4550 // Return true if algorithm of this SMESH_DimHyp is used if no
4551 // sub-mesh order is imposed by the user
4552 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4554 // NeedDiscreteBoundary() algo has a higher priority
4555 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4556 theOther->GetAlgo()->NeedDiscreteBoundary() )
4557 return !this->GetAlgo()->NeedDiscreteBoundary();
4559 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4562 }; // end of SMESH_DimHyp
4563 //-----------------------------------------------------------------------------
4565 typedef list<const SMESH_DimHyp*> TDimHypList;
4567 //-----------------------------------------------------------------------------
4569 void addDimHypInstance(const int theDim,
4570 const TopoDS_Shape& theShape,
4571 const SMESH_Algo* theAlgo,
4572 const SMESH_subMesh* theSubMesh,
4573 const list <const SMESHDS_Hypothesis*>& theHypList,
4574 TDimHypList* theDimHypListArr )
4576 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4577 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4578 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4579 dimHyp->_hypotheses.push_front(theAlgo);
4580 listOfdimHyp.push_back( dimHyp );
4583 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4584 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4585 theHypList.begin(), theHypList.end() );
4588 //-----------------------------------------------------------------------------
4589 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4590 TDimHypList& theListOfConcurr)
4592 if ( theListOfConcurr.empty() )
4594 theListOfConcurr.push_back( theDimHyp );
4598 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4599 while ( hypIt != theListOfConcurr.end() &&
4600 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4602 theListOfConcurr.insert( hypIt, theDimHyp );
4606 //-----------------------------------------------------------------------------
4607 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4608 const TDimHypList& theListOfDimHyp,
4609 TDimHypList& theListOfConcurrHyp,
4610 set<int>& theSetOfConcurrId )
4612 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4613 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4615 const SMESH_DimHyp* curDimHyp = *rIt;
4616 if ( curDimHyp == theDimHyp )
4617 break; // meet own dimHyp pointer in same dimension
4619 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4620 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4622 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4627 //-----------------------------------------------------------------------------
4628 void unionLists(TListOfInt& theListOfId,
4629 TListOfListOfInt& theListOfListOfId,
4632 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4633 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4635 continue; //skip already treated lists
4636 // check if other list has any same submesh object
4637 TListOfInt& otherListOfId = *it;
4638 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4639 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4642 // union two lists (from source into target)
4643 TListOfInt::iterator it2 = otherListOfId.begin();
4644 for ( ; it2 != otherListOfId.end(); it2++ ) {
4645 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4646 theListOfId.push_back(*it2);
4648 // clear source list
4649 otherListOfId.clear();
4652 //-----------------------------------------------------------------------------
4654 //! free memory allocated for dimension-hypothesis objects
4655 void removeDimHyps( TDimHypList* theArrOfList )
4657 for (int i = 0; i < 4; i++ ) {
4658 TDimHypList& listOfdimHyp = theArrOfList[i];
4659 TDimHypList::const_iterator it = listOfdimHyp.begin();
4660 for ( ; it != listOfdimHyp.end(); it++ )
4665 //-----------------------------------------------------------------------------
4667 * \brief find common submeshes with given submesh
4668 * \param theSubMeshList list of already collected submesh to check
4669 * \param theSubMesh given submesh to intersect with other
4670 * \param theCommonSubMeshes collected common submeshes
4672 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4673 const SMESH_subMesh* theSubMesh,
4674 set<const SMESH_subMesh*>& theCommon )
4678 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4679 for ( ; it != theSubMeshList.end(); it++ )
4680 theSubMesh->FindIntersection( *it, theCommon );
4681 theSubMeshList.push_back( theSubMesh );
4682 //theCommon.insert( theSubMesh );
4687 //=============================================================================
4689 * \brief Return submesh objects list in meshing order
4691 //=============================================================================
4693 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4695 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4697 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4699 return aResult._retn();
4701 ::SMESH_Mesh& mesh = GetImpl();
4702 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4703 if ( !anOrder.size() ) {
4705 // collect submeshes and detect concurrent algorithms and hypothesises
4706 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4708 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4709 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4710 ::SMESH_subMesh* sm = (*i_sm).second;
4712 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4714 // list of assigned hypothesises
4715 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4716 // Find out dimensions where the submesh can be concurrent.
4717 // We define the dimensions by algo of each of hypotheses in hypList
4718 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4719 for( ; hypIt != hypList.end(); hypIt++ ) {
4720 SMESH_Algo* anAlgo = 0;
4721 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4722 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4723 // hyp it-self is algo
4724 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4726 // try to find algorithm with help of sub-shapes
4727 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4728 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4729 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4732 continue; // no algorithm assigned to a current submesh
4734 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4735 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4737 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4738 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4739 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4741 } // end iterations on submesh
4743 // iterate on created dimension-hypotheses and check for concurrents
4744 for ( int i = 0; i < 4; i++ ) {
4745 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4746 // check for concurrents in own and other dimensions (step-by-step)
4747 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4748 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4749 const SMESH_DimHyp* dimHyp = *dhIt;
4750 TDimHypList listOfConcurr;
4751 set<int> setOfConcurrIds;
4752 // looking for concurrents and collect into own list
4753 for ( int j = i; j < 4; j++ )
4754 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4755 // check if any concurrents found
4756 if ( listOfConcurr.size() > 0 ) {
4757 // add own submesh to list of concurrent
4758 addInOrderOfPriority( dimHyp, listOfConcurr );
4759 list<int> listOfConcurrIds;
4760 TDimHypList::iterator hypIt = listOfConcurr.begin();
4761 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4762 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4763 anOrder.push_back( listOfConcurrIds );
4768 removeDimHyps(dimHypListArr);
4770 // now, minimise the number of concurrent groups
4771 // Here we assume that lists of submeshes can have same submesh
4772 // in case of multi-dimension algorithms, as result
4773 // list with common submesh has to be united into one list
4775 TListOfListOfInt::iterator listIt = anOrder.begin();
4776 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4777 unionLists( *listIt, anOrder, listIndx + 1 );
4779 // convert submesh ids into interface instances
4780 // and dump command into python
4781 convertMeshOrder( anOrder, aResult, false );
4783 return aResult._retn();
4786 //=============================================================================
4788 * \brief Set submesh object order
4789 * \param theSubMeshArray submesh array order
4791 //=============================================================================
4793 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4796 _preMeshInfo->ForgetOrLoad();
4799 ::SMESH_Mesh& mesh = GetImpl();
4801 TPythonDump aPythonDump; // prevent dump of called methods
4802 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4804 TListOfListOfInt subMeshOrder;
4805 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4807 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4808 TListOfInt subMeshIds;
4809 aPythonDump << "[ ";
4810 // Collect subMeshes which should be clear
4811 // do it list-by-list, because modification of submesh order
4812 // take effect between concurrent submeshes only
4813 set<const SMESH_subMesh*> subMeshToClear;
4814 list<const SMESH_subMesh*> subMeshList;
4815 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4817 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4819 aPythonDump << ", ";
4820 aPythonDump << subMesh;
4821 subMeshIds.push_back( subMesh->GetId() );
4822 // detect common parts of submeshes
4823 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4824 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4826 aPythonDump << " ]";
4827 subMeshOrder.push_back( subMeshIds );
4829 // clear collected submeshes
4830 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4831 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4832 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4833 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4835 aPythonDump << " ])";
4837 mesh.SetMeshOrder( subMeshOrder );
4843 //=============================================================================
4845 * \brief Convert submesh ids into submesh interfaces
4847 //=============================================================================
4849 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4850 SMESH::submesh_array_array& theResOrder,
4851 const bool theIsDump)
4853 int nbSet = theIdsOrder.size();
4854 TPythonDump aPythonDump; // prevent dump of called methods
4856 aPythonDump << "[ ";
4857 theResOrder.length(nbSet);
4858 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4860 for( ; it != theIdsOrder.end(); it++ ) {
4861 // translate submesh identificators into submesh objects
4862 // takeing into account real number of concurrent lists
4863 const TListOfInt& aSubOrder = (*it);
4864 if (!aSubOrder.size())
4867 aPythonDump << "[ ";
4868 // convert shape indeces into interfaces
4869 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4870 aResSubSet->length(aSubOrder.size());
4871 TListOfInt::const_iterator subIt = aSubOrder.begin();
4872 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4873 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4875 SMESH::SMESH_subMesh_var subMesh =
4876 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4879 aPythonDump << ", ";
4880 aPythonDump << subMesh;
4882 aResSubSet[ j++ ] = subMesh;
4885 aPythonDump << " ]";
4886 theResOrder[ listIndx++ ] = aResSubSet;
4888 // correct number of lists
4889 theResOrder.length( listIndx );
4892 // finilise python dump
4893 aPythonDump << " ]";
4894 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4898 //================================================================================
4900 // Implementation of SMESH_MeshPartDS
4902 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4903 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4905 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4906 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4908 _meshDS = mesh_i->GetImpl().GetMeshDS();
4910 SetPersistentId( _meshDS->GetPersistentId() );
4912 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4914 // <meshPart> is the whole mesh
4915 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4917 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4918 myGroupSet = _meshDS->GetGroups();
4923 SMESH::long_array_var anIDs = meshPart->GetIDs();
4924 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4925 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4927 for (int i=0; i < anIDs->length(); i++)
4928 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4929 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4934 for (int i=0; i < anIDs->length(); i++)
4935 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4936 if ( _elements[ e->GetType() ].insert( e ).second )
4939 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4940 while ( nIt->more() )
4942 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4943 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4950 _meshDS = 0; // to enforce iteration on _elements and _nodes
4953 // -------------------------------------------------------------------------------------
4954 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
4955 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
4958 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
4959 for ( ; partIt != meshPart.end(); ++partIt )
4960 if ( const SMDS_MeshElement * e = *partIt )
4961 if ( _elements[ e->GetType() ].insert( e ).second )
4964 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4965 while ( nIt->more() )
4967 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4968 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4974 // -------------------------------------------------------------------------------------
4975 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
4977 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
4979 typedef SMDS_SetIterator
4980 <const SMDS_MeshElement*,
4981 TIDSortedElemSet::const_iterator,
4982 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4983 SMDS_MeshElement::GeomFilter
4986 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
4988 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4989 _elements[type].end(),
4990 SMDS_MeshElement::GeomFilter( geomType )));
4992 // -------------------------------------------------------------------------------------
4993 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
4995 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
4997 typedef SMDS_SetIterator
4998 <const SMDS_MeshElement*,
4999 TIDSortedElemSet::const_iterator,
5000 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5001 SMDS_MeshElement::EntityFilter
5004 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5006 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5007 _elements[type].end(),
5008 SMDS_MeshElement::EntityFilter( entity )));
5010 // -------------------------------------------------------------------------------------
5011 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5013 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5014 if ( type == SMDSAbs_All && !_meshDS )
5016 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5018 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5019 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5021 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5023 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5024 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5026 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5027 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5029 // -------------------------------------------------------------------------------------
5030 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5031 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5033 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5034 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5035 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5037 // -------------------------------------------------------------------------------------
5038 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5039 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5040 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5041 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5042 #undef _GET_ITER_DEFINE
5044 // END Implementation of SMESH_MeshPartDS
5046 //================================================================================