1 // Copyright (C) 2007-2013 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 "MED_Factory.hxx"
31 #include "SMDS_EdgePosition.hxx"
32 #include "SMDS_ElemIterator.hxx"
33 #include "SMDS_FacePosition.hxx"
34 #include "SMDS_IteratorOnIterators.hxx"
35 #include "SMDS_MeshGroup.hxx"
36 #include "SMDS_SetIterator.hxx"
37 #include "SMDS_VolumeTool.hxx"
38 #include "SMESHDS_Command.hxx"
39 #include "SMESHDS_CommandType.hxx"
40 #include "SMESHDS_Group.hxx"
41 #include "SMESHDS_GroupOnGeom.hxx"
42 #include "SMESH_Controls.hxx"
43 #include "SMESH_Filter_i.hxx"
44 #include "SMESH_Gen_i.hxx"
45 #include "SMESH_Group.hxx"
46 #include "SMESH_Group_i.hxx"
47 #include "SMESH_MeshAlgos.hxx"
48 #include "SMESH_MeshEditor.hxx"
49 #include "SMESH_MeshEditor_i.hxx"
50 #include "SMESH_MeshPartDS.hxx"
51 #include "SMESH_MesherHelper.hxx"
52 #include "SMESH_PreMeshInfo.hxx"
53 #include "SMESH_PythonDump.hxx"
54 #include "SMESH_subMesh_i.hxx"
57 #include <SALOMEDS_Attributes_wrap.hxx>
58 #include <SALOMEDS_wrap.hxx>
59 #include <SALOME_NamingService.hxx>
60 #include <Utils_ExceptHandlers.hxx>
61 #include <Utils_SINGLETON.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <OSD_Directory.hxx>
70 #include <OSD_File.hxx>
71 #include <OSD_Path.hxx>
72 #include <OSD_Protection.hxx>
73 #include <Standard_OutOfMemory.hxx>
74 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
75 #include <TColStd_MapOfInteger.hxx>
76 #include <TColStd_SequenceOfInteger.hxx>
77 #include <TCollection_AsciiString.hxx>
79 #include <TopExp_Explorer.hxx>
80 #include <TopTools_MapIteratorOfMapOfShape.hxx>
81 #include <TopTools_MapOfShape.hxx>
82 #include <TopoDS_Compound.hxx>
84 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
95 static int MYDEBUG = 0;
97 static int MYDEBUG = 0;
101 using SMESH::TPythonDump;
103 int SMESH_Mesh_i::_idGenerator = 0;
105 //=============================================================================
109 //=============================================================================
111 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
113 CORBA::Long studyId )
114 : SALOME::GenericObj_i( thePOA )
116 MESSAGE("SMESH_Mesh_i");
119 _id = _idGenerator++;
122 _previewEditor = NULL;
126 //=============================================================================
130 //=============================================================================
132 SMESH_Mesh_i::~SMESH_Mesh_i()
134 MESSAGE("~SMESH_Mesh_i");
137 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
138 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
139 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
141 aGroup->UnRegister();
142 SMESH::SMESH_GroupBase_var( itGr->second );
147 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
148 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
149 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
151 aSubMesh->UnRegister();
152 SMESH::SMESH_subMesh_var( itSM->second );
154 _mapSubMeshIor.clear();
156 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
157 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
158 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
159 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
160 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
161 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
164 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
232 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 catch(SALOME_Exception & S_ex) {
235 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
237 return aShapeObj._retn();
240 //================================================================================
242 * \brief Return false if the mesh is not yet fully loaded from the study file
244 //================================================================================
246 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
248 Unexpect aCatch(SALOME_SalomeException);
249 return !_preMeshInfo;
252 //================================================================================
254 * \brief Load full mesh data from the study file
256 //================================================================================
258 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
260 Unexpect aCatch(SALOME_SalomeException);
262 _preMeshInfo->FullLoadFromFile();
265 //================================================================================
267 * \brief Remove all nodes and elements
269 //================================================================================
271 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
273 Unexpect aCatch(SALOME_SalomeException);
275 _preMeshInfo->ForgetAllData();
279 CheckGeomGroupModif(); // issue 20145
281 catch(SALOME_Exception & S_ex) {
282 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
284 _impl->GetMeshDS()->Modified();
286 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
289 //================================================================================
291 * \brief Remove all nodes and elements for indicated shape
293 //================================================================================
295 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
296 throw (SALOME::SALOME_Exception)
298 Unexpect aCatch(SALOME_SalomeException);
300 _preMeshInfo->FullLoadFromFile();
303 _impl->ClearSubMesh( ShapeID );
305 catch(SALOME_Exception & S_ex) {
306 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
308 _impl->GetMeshDS()->Modified();
310 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
313 //=============================================================================
315 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
317 //=============================================================================
319 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
321 SMESH::DriverMED_ReadStatus res;
324 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
325 res = SMESH::DRS_OK; break;
326 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
327 res = SMESH::DRS_EMPTY; break;
328 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
329 res = SMESH::DRS_WARN_RENUMBER; break;
330 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
331 res = SMESH::DRS_WARN_SKIP_ELEM; break;
332 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
333 res = SMESH::DRS_WARN_DESCENDING; break;
334 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
336 res = SMESH::DRS_FAIL; break;
341 //=============================================================================
343 * Convert ::SMESH_ComputeError to SMESH::ComputeError
345 //=============================================================================
347 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
349 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
350 errVar->subShapeID = -1;
351 errVar->hasBadMesh = false;
353 if ( !errorPtr || errorPtr->IsOK() )
355 errVar->code = SMESH::COMPERR_OK;
359 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
360 errVar->comment = errorPtr->myComment.c_str();
362 return errVar._retn();
365 //=============================================================================
369 * Imports mesh data from MED file
371 //=============================================================================
373 SMESH::DriverMED_ReadStatus
374 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
375 throw ( SALOME::SALOME_Exception )
377 Unexpect aCatch(SALOME_SalomeException);
380 status = _impl->MEDToMesh( theFileName, theMeshName );
382 catch( SALOME_Exception& S_ex ) {
383 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
386 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
389 CreateGroupServants();
391 int major, minor, release;
392 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
393 major = minor = release = -1;
394 _medFileInfo = new SMESH::MedFileInfo();
395 _medFileInfo->fileName = theFileName;
396 _medFileInfo->fileSize = 0;
397 _medFileInfo->major = major;
398 _medFileInfo->minor = minor;
399 _medFileInfo->release = release;
402 if ( ::_stati64( theFileName, &d ) != -1 )
405 if ( ::stat64( theFileName, &d ) != -1 )
407 _medFileInfo->fileSize = d.st_size;
409 return ConvertDriverMEDReadStatus(status);
412 //================================================================================
414 * \brief Imports mesh data from the CGNS file
416 //================================================================================
418 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
419 const int theMeshIndex,
420 std::string& theMeshName )
421 throw ( SALOME::SALOME_Exception )
423 Unexpect aCatch(SALOME_SalomeException);
426 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
428 catch( SALOME_Exception& S_ex ) {
429 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
432 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
435 CreateGroupServants();
437 return ConvertDriverMEDReadStatus(status);
440 //================================================================================
442 * \brief Return string representation of a MED file version comprising nbDigits
444 //================================================================================
446 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
448 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
450 return CORBA::string_dup( ver.c_str() );
453 //=============================================================================
457 * Imports mesh data from MED file
459 //=============================================================================
461 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
462 throw ( SALOME::SALOME_Exception )
466 // Read mesh with name = <theMeshName> into SMESH_Mesh
467 _impl->UNVToMesh( theFileName );
469 CreateGroupServants();
471 SMESH_CATCH( SMESH::throwCorbaException );
476 //=============================================================================
480 * Imports mesh data from STL file
482 //=============================================================================
483 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
484 throw ( SALOME::SALOME_Exception )
488 // Read mesh with name = <theMeshName> into SMESH_Mesh
489 _impl->STLToMesh( theFileName );
491 SMESH_CATCH( SMESH::throwCorbaException );
496 //================================================================================
498 * \brief Function used in SMESH_CATCH by ImportGMFFile()
500 //================================================================================
504 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
506 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
510 //================================================================================
512 * \brief Imports data from a GMF file and returns an error description
514 //================================================================================
516 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
517 bool theMakeRequiredGroups )
518 throw (SALOME::SALOME_Exception)
520 SMESH_ComputeErrorPtr error;
523 #define SMESH_CAUGHT error =
526 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
528 SMESH_CATCH( exceptionToComputeError );
532 CreateGroupServants();
534 return ConvertComputeError( error );
537 //=============================================================================
541 //=============================================================================
543 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
545 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
546 (SMESH_Hypothesis::Hypothesis_Status theStatus)
549 RETURNCASE( HYP_OK );
550 RETURNCASE( HYP_MISSING );
551 RETURNCASE( HYP_CONCURENT );
552 RETURNCASE( HYP_BAD_PARAMETER );
553 RETURNCASE( HYP_HIDDEN_ALGO );
554 RETURNCASE( HYP_HIDING_ALGO );
555 RETURNCASE( HYP_UNKNOWN_FATAL );
556 RETURNCASE( HYP_INCOMPATIBLE );
557 RETURNCASE( HYP_NOTCONFORM );
558 RETURNCASE( HYP_ALREADY_EXIST );
559 RETURNCASE( HYP_BAD_DIM );
560 RETURNCASE( HYP_BAD_SUBSHAPE );
561 RETURNCASE( HYP_BAD_GEOMETRY );
562 RETURNCASE( HYP_NEED_SHAPE );
565 return SMESH::HYP_UNKNOWN_FATAL;
568 //=============================================================================
572 * calls internal addHypothesis() and then adds a reference to <anHyp> under
573 * the SObject actually having a reference to <aSubShape>.
574 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
576 //=============================================================================
578 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
579 SMESH::SMESH_Hypothesis_ptr anHyp)
580 throw(SALOME::SALOME_Exception)
582 Unexpect aCatch(SALOME_SalomeException);
584 _preMeshInfo->ForgetOrLoad();
586 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
588 SMESH::SMESH_Mesh_var mesh( _this() );
589 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
591 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
592 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
594 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
596 // Update Python script
597 //if(_impl->HasShapeToMesh())
599 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
600 << aSubShapeObject << ", " << anHyp << " )";
603 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
606 return ConvertHypothesisStatus(status);
609 //=============================================================================
613 //=============================================================================
615 SMESH_Hypothesis::Hypothesis_Status
616 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
617 SMESH::SMESH_Hypothesis_ptr anHyp)
619 if(MYDEBUG) MESSAGE("addHypothesis");
621 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
622 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
624 if (CORBA::is_nil( anHyp ))
625 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
627 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
630 TopoDS_Shape myLocSubShape;
631 //use PseudoShape in case if mesh has no shape
633 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
635 myLocSubShape = _impl->GetShapeToMesh();
637 const int hypId = anHyp->GetId();
638 status = _impl->AddHypothesis(myLocSubShape, hypId);
639 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
640 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
642 // assure there is a corresponding submesh
643 if ( !_impl->IsMainShape( myLocSubShape )) {
644 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
645 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
646 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
650 catch(SALOME_Exception & S_ex)
652 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
657 //=============================================================================
661 //=============================================================================
663 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
664 SMESH::SMESH_Hypothesis_ptr anHyp)
665 throw(SALOME::SALOME_Exception)
667 Unexpect aCatch(SALOME_SalomeException);
669 _preMeshInfo->ForgetOrLoad();
671 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
672 SMESH::SMESH_Mesh_var mesh = _this();
674 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
676 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
677 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
679 // Update Python script
680 if(_impl->HasShapeToMesh())
681 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
682 << aSubShapeObject << ", " << anHyp << " )";
684 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
687 return ConvertHypothesisStatus(status);
690 //=============================================================================
694 //=============================================================================
696 SMESH_Hypothesis::Hypothesis_Status
697 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
698 SMESH::SMESH_Hypothesis_ptr anHyp)
700 if(MYDEBUG) MESSAGE("removeHypothesis()");
702 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
703 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
705 if (CORBA::is_nil( anHyp ))
706 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
708 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
711 TopoDS_Shape myLocSubShape;
712 //use PseudoShape in case if mesh has no shape
713 if( _impl->HasShapeToMesh() )
714 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
716 myLocSubShape = _impl->GetShapeToMesh();
718 const int hypId = anHyp->GetId();
719 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
720 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
722 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
726 catch(SALOME_Exception & S_ex)
728 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
733 //=============================================================================
737 //=============================================================================
739 SMESH::ListOfHypothesis *
740 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
741 throw(SALOME::SALOME_Exception)
743 Unexpect aCatch(SALOME_SalomeException);
744 if (MYDEBUG) MESSAGE("GetHypothesisList");
745 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
746 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
748 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
751 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
752 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
753 myLocSubShape = _impl->GetShapeToMesh();
754 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
755 int i = 0, n = aLocalList.size();
758 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
759 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
760 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
762 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
763 if ( id_hypptr != _mapHypo.end() )
764 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
768 catch(SALOME_Exception & S_ex) {
769 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
772 return aList._retn();
775 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
777 Unexpect aCatch(SALOME_SalomeException);
778 if (MYDEBUG) MESSAGE("GetSubMeshes");
780 SMESH::submesh_array_var aList = new SMESH::submesh_array();
783 TPythonDump aPythonDump;
784 if ( !_mapSubMeshIor.empty() )
788 aList->length( _mapSubMeshIor.size() );
790 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
791 for ( ; it != _mapSubMeshIor.end(); it++ ) {
792 if ( CORBA::is_nil( it->second )) continue;
793 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
795 if (i > 1) aPythonDump << ", ";
796 aPythonDump << it->second;
800 catch(SALOME_Exception & S_ex) {
801 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
804 // Update Python script
805 if ( !_mapSubMeshIor.empty() )
806 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
808 return aList._retn();
811 //=============================================================================
815 //=============================================================================
817 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
818 const char* theName )
819 throw(SALOME::SALOME_Exception)
821 Unexpect aCatch(SALOME_SalomeException);
822 if (CORBA::is_nil(aSubShapeObject))
823 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
825 SMESH::SMESH_subMesh_var subMesh;
826 SMESH::SMESH_Mesh_var aMesh = _this();
828 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
830 //Get or Create the SMESH_subMesh object implementation
832 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
834 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
836 TopoDS_Iterator it( myLocSubShape );
838 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
840 subMesh = getSubMesh( subMeshId );
842 // create a new subMesh object servant if there is none for the shape
843 if ( subMesh->_is_nil() )
844 subMesh = createSubMesh( aSubShapeObject );
845 if ( _gen_i->CanPublishInStudy( subMesh ))
847 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
848 SALOMEDS::SObject_wrap aSO =
849 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
850 if ( !aSO->_is_nil()) {
851 // Update Python script
852 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
853 << aSubShapeObject << ", '" << theName << "' )";
857 catch(SALOME_Exception & S_ex) {
858 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
860 return subMesh._retn();
863 //=============================================================================
867 //=============================================================================
869 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
870 throw (SALOME::SALOME_Exception)
874 if ( theSubMesh->_is_nil() )
877 GEOM::GEOM_Object_var aSubShapeObject;
878 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
879 if ( !aStudy->_is_nil() ) {
880 // Remove submesh's SObject
881 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
882 if ( !anSO->_is_nil() ) {
883 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
884 SALOMEDS::SObject_wrap anObj, aRef;
885 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
886 anObj->ReferencedObject( aRef.inout() ))
888 CORBA::Object_var obj = aRef->GetObject();
889 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
891 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
892 // aSubShapeObject = theSubMesh->GetSubShape();
894 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
895 builder->RemoveObjectWithChildren( anSO );
897 // Update Python script
898 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
902 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
904 _preMeshInfo->ForgetOrLoad();
906 SMESH_CATCH( SMESH::throwCorbaException );
909 //=============================================================================
913 //=============================================================================
915 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
916 const char* theName )
917 throw(SALOME::SALOME_Exception)
919 Unexpect aCatch(SALOME_SalomeException);
921 _preMeshInfo->FullLoadFromFile();
923 SMESH::SMESH_Group_var aNewGroup =
924 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
926 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
928 SMESH::SMESH_Mesh_var mesh = _this();
929 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
930 SALOMEDS::SObject_wrap aSO =
931 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
932 if ( !aSO->_is_nil())
933 // Update Python script
934 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
935 << theElemType << ", '" << theName << "' )";
937 return aNewGroup._retn();
940 //=============================================================================
944 //=============================================================================
945 SMESH::SMESH_GroupOnGeom_ptr
946 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
948 GEOM::GEOM_Object_ptr theGeomObj)
949 throw(SALOME::SALOME_Exception)
951 Unexpect aCatch(SALOME_SalomeException);
953 _preMeshInfo->FullLoadFromFile();
955 SMESH::SMESH_GroupOnGeom_var aNewGroup;
957 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
958 if ( !aShape.IsNull() )
961 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
963 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
965 SMESH::SMESH_Mesh_var mesh = _this();
966 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
967 SALOMEDS::SObject_wrap aSO =
968 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
969 if ( !aSO->_is_nil())
970 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
971 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
975 return aNewGroup._retn();
978 //================================================================================
980 * \brief Creates a group whose contents is defined by filter
981 * \param theElemType - group type
982 * \param theName - group name
983 * \param theFilter - the filter
984 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
986 //================================================================================
988 SMESH::SMESH_GroupOnFilter_ptr
989 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
991 SMESH::Filter_ptr theFilter )
992 throw (SALOME::SALOME_Exception)
994 Unexpect aCatch(SALOME_SalomeException);
996 _preMeshInfo->FullLoadFromFile();
998 if ( CORBA::is_nil( theFilter ))
999 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1001 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1003 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1005 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1006 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1009 if ( !aNewGroup->_is_nil() )
1010 aNewGroup->SetFilter( theFilter );
1012 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1014 SMESH::SMESH_Mesh_var mesh = _this();
1015 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1016 SALOMEDS::SObject_wrap aSO =
1017 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1019 if ( !aSO->_is_nil())
1020 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1021 << theElemType << ", '" << theName << "', " << theFilter << " )";
1023 return aNewGroup._retn();
1026 //=============================================================================
1030 //=============================================================================
1032 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1033 throw (SALOME::SALOME_Exception)
1035 if ( theGroup->_is_nil() )
1040 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1044 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1045 if ( !aStudy->_is_nil() )
1047 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1048 if ( !aGroupSO->_is_nil() )
1050 // Update Python script
1051 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1053 // Remove group's SObject
1054 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1055 builder->RemoveObjectWithChildren( aGroupSO );
1059 // Remove the group from SMESH data structures
1060 removeGroup( aGroup->GetLocalID() );
1062 SMESH_CATCH( SMESH::throwCorbaException );
1065 //=============================================================================
1067 * Remove group with its contents
1069 //=============================================================================
1071 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1072 throw (SALOME::SALOME_Exception)
1076 _preMeshInfo->FullLoadFromFile();
1078 if ( theGroup->_is_nil() )
1082 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1083 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1084 while ( elemIt->more() )
1085 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1087 TPythonDump pyDump; // Supress dump from RemoveGroup()
1089 // Update Python script (theGroup must be alive for this)
1090 pyDump << SMESH::SMESH_Mesh_var(_this())
1091 << ".RemoveGroupWithContents( " << theGroup << " )";
1094 RemoveGroup( theGroup );
1096 SMESH_CATCH( SMESH::throwCorbaException );
1099 //================================================================================
1101 * \brief Get the list of groups existing in the mesh
1102 * \retval SMESH::ListOfGroups * - list of groups
1104 //================================================================================
1106 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1108 Unexpect aCatch(SALOME_SalomeException);
1109 if (MYDEBUG) MESSAGE("GetGroups");
1111 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1114 TPythonDump aPythonDump;
1115 if ( !_mapGroups.empty() )
1117 aPythonDump << "[ ";
1119 aList->length( _mapGroups.size() );
1121 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1122 for ( ; it != _mapGroups.end(); it++ ) {
1123 if ( CORBA::is_nil( it->second )) continue;
1124 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1126 if (i > 1) aPythonDump << ", ";
1127 aPythonDump << it->second;
1131 catch(SALOME_Exception & S_ex) {
1132 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1134 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1136 return aList._retn();
1139 //=============================================================================
1141 * Get number of groups existing in the mesh
1143 //=============================================================================
1145 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1147 Unexpect aCatch(SALOME_SalomeException);
1148 return _mapGroups.size();
1151 //=============================================================================
1153 * New group including all mesh elements present in initial groups is created.
1155 //=============================================================================
1157 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1158 SMESH::SMESH_GroupBase_ptr theGroup2,
1159 const char* theName )
1160 throw (SALOME::SALOME_Exception)
1162 SMESH::SMESH_Group_var aResGrp;
1166 _preMeshInfo->FullLoadFromFile();
1168 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1169 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1171 if ( theGroup1->GetType() != theGroup2->GetType() )
1172 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1177 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1178 if ( aResGrp->_is_nil() )
1179 return SMESH::SMESH_Group::_nil();
1181 aResGrp->AddFrom( theGroup1 );
1182 aResGrp->AddFrom( theGroup2 );
1184 // Update Python script
1185 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1186 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1188 SMESH_CATCH( SMESH::throwCorbaException );
1190 return aResGrp._retn();
1193 //=============================================================================
1195 * \brief New group including all mesh elements present in initial groups is created.
1196 * \param theGroups list of groups
1197 * \param theName name of group to be created
1198 * \return pointer to the new group
1200 //=============================================================================
1202 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1203 const char* theName )
1204 throw (SALOME::SALOME_Exception)
1206 SMESH::SMESH_Group_var aResGrp;
1209 _preMeshInfo->FullLoadFromFile();
1212 return SMESH::SMESH_Group::_nil();
1217 SMESH::ElementType aType = SMESH::ALL;
1218 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1220 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1221 if ( CORBA::is_nil( aGrp ) )
1223 if ( aType == SMESH::ALL )
1224 aType = aGrp->GetType();
1225 else if ( aType != aGrp->GetType() )
1226 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1229 if ( aType == SMESH::ALL )
1230 return SMESH::SMESH_Group::_nil();
1235 aResGrp = CreateGroup( aType, theName );
1236 if ( aResGrp->_is_nil() )
1237 return SMESH::SMESH_Group::_nil();
1239 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1240 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1242 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1243 if ( !CORBA::is_nil( aGrp ) )
1245 aResGrp->AddFrom( aGrp );
1246 if ( g > 0 ) pyDump << ", ";
1250 pyDump << " ], '" << theName << "' )";
1252 SMESH_CATCH( SMESH::throwCorbaException );
1254 return aResGrp._retn();
1257 //=============================================================================
1259 * New group is created. All mesh elements that are
1260 * present in both initial groups are added to the new one.
1262 //=============================================================================
1264 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1265 SMESH::SMESH_GroupBase_ptr theGroup2,
1266 const char* theName )
1267 throw (SALOME::SALOME_Exception)
1269 SMESH::SMESH_Group_var aResGrp;
1274 _preMeshInfo->FullLoadFromFile();
1276 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1277 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1279 if ( theGroup1->GetType() != theGroup2->GetType() )
1280 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1284 // Create Intersection
1285 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1286 if ( aResGrp->_is_nil() )
1287 return aResGrp._retn();
1289 SMESHDS_GroupBase* groupDS1 = 0;
1290 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1291 groupDS1 = grp_i->GetGroupDS();
1293 SMESHDS_GroupBase* groupDS2 = 0;
1294 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1295 groupDS2 = grp_i->GetGroupDS();
1297 SMESHDS_Group* resGroupDS = 0;
1298 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1299 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1301 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1303 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1304 while ( elemIt1->more() )
1306 const SMDS_MeshElement* e = elemIt1->next();
1307 if ( groupDS2->Contains( e ))
1308 resGroupDS->SMDSGroup().Add( e );
1311 // Update Python script
1312 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1313 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1315 SMESH_CATCH( SMESH::throwCorbaException );
1317 return aResGrp._retn();
1320 //=============================================================================
1322 \brief Intersect list of groups. New group is created. All mesh elements that
1323 are present in all initial groups simultaneously are added to the new one.
1324 \param theGroups list of groups
1325 \param theName name of group to be created
1326 \return pointer on the group
1328 //=============================================================================
1329 SMESH::SMESH_Group_ptr
1330 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1331 const char* theName )
1332 throw (SALOME::SALOME_Exception)
1334 SMESH::SMESH_Group_var aResGrp;
1339 _preMeshInfo->FullLoadFromFile();
1342 return SMESH::SMESH_Group::_nil();
1344 // check types and get SMESHDS_GroupBase's
1345 SMESH::ElementType aType = SMESH::ALL;
1346 vector< SMESHDS_GroupBase* > groupVec;
1347 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1349 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1350 if ( CORBA::is_nil( aGrp ) )
1352 if ( aType == SMESH::ALL )
1353 aType = aGrp->GetType();
1354 else if ( aType != aGrp->GetType() )
1355 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1358 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1359 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1361 if ( grpDS->IsEmpty() )
1366 groupVec.push_back( grpDS );
1369 if ( aType == SMESH::ALL ) // all groups are nil
1370 return SMESH::SMESH_Group::_nil();
1375 aResGrp = CreateGroup( aType, theName );
1377 SMESHDS_Group* resGroupDS = 0;
1378 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1379 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1380 if ( !resGroupDS || groupVec.empty() )
1381 return aResGrp._retn();
1384 size_t i, nb = groupVec.size();
1385 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1386 while ( elemIt1->more() )
1388 const SMDS_MeshElement* e = elemIt1->next();
1390 for ( i = 1; ( i < nb && inAll ); ++i )
1391 inAll = groupVec[i]->Contains( e );
1394 resGroupDS->SMDSGroup().Add( e );
1397 // Update Python script
1398 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1399 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1401 SMESH_CATCH( SMESH::throwCorbaException );
1403 return aResGrp._retn();
1406 //=============================================================================
1408 * New group is created. All mesh elements that are present in
1409 * a main group but is not present in a tool group are added to the new one
1411 //=============================================================================
1413 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1414 SMESH::SMESH_GroupBase_ptr theGroup2,
1415 const char* theName )
1416 throw (SALOME::SALOME_Exception)
1418 SMESH::SMESH_Group_var aResGrp;
1423 _preMeshInfo->FullLoadFromFile();
1425 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1426 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1428 if ( theGroup1->GetType() != theGroup2->GetType() )
1429 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1433 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1434 if ( aResGrp->_is_nil() )
1435 return aResGrp._retn();
1437 SMESHDS_GroupBase* groupDS1 = 0;
1438 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1439 groupDS1 = grp_i->GetGroupDS();
1441 SMESHDS_GroupBase* groupDS2 = 0;
1442 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1443 groupDS2 = grp_i->GetGroupDS();
1445 SMESHDS_Group* resGroupDS = 0;
1446 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1447 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1449 if ( groupDS1 && groupDS2 && resGroupDS )
1451 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1452 while ( elemIt1->more() )
1454 const SMDS_MeshElement* e = elemIt1->next();
1455 if ( !groupDS2->Contains( e ))
1456 resGroupDS->SMDSGroup().Add( e );
1459 // Update Python script
1460 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1461 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1463 SMESH_CATCH( SMESH::throwCorbaException );
1465 return aResGrp._retn();
1468 //=============================================================================
1470 \brief Cut lists of groups. New group is created. All mesh elements that are
1471 present in main groups but do not present in tool groups are added to the new one
1472 \param theMainGroups list of main groups
1473 \param theToolGroups list of tool groups
1474 \param theName name of group to be created
1475 \return pointer on the group
1477 //=============================================================================
1478 SMESH::SMESH_Group_ptr
1479 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1480 const SMESH::ListOfGroups& theToolGroups,
1481 const char* theName )
1482 throw (SALOME::SALOME_Exception)
1484 SMESH::SMESH_Group_var aResGrp;
1489 _preMeshInfo->FullLoadFromFile();
1492 return SMESH::SMESH_Group::_nil();
1494 // check types and get SMESHDS_GroupBase's
1495 SMESH::ElementType aType = SMESH::ALL;
1496 vector< SMESHDS_GroupBase* > toolGroupVec;
1497 vector< SMDS_ElemIteratorPtr > mainIterVec;
1499 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1501 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1502 if ( CORBA::is_nil( aGrp ) )
1504 if ( aType == SMESH::ALL )
1505 aType = aGrp->GetType();
1506 else if ( aType != aGrp->GetType() )
1507 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1509 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1510 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1511 if ( !grpDS->IsEmpty() )
1512 mainIterVec.push_back( grpDS->GetElements() );
1514 if ( aType == SMESH::ALL ) // all main groups are nil
1515 return SMESH::SMESH_Group::_nil();
1516 if ( mainIterVec.empty() ) // all main groups are empty
1517 return aResGrp._retn();
1519 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1521 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1522 if ( CORBA::is_nil( aGrp ) )
1524 if ( aType != aGrp->GetType() )
1525 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1527 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1528 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1529 toolGroupVec.push_back( grpDS );
1535 aResGrp = CreateGroup( aType, theName );
1537 SMESHDS_Group* resGroupDS = 0;
1538 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1539 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1541 return aResGrp._retn();
1544 size_t i, nb = toolGroupVec.size();
1545 SMDS_ElemIteratorPtr mainElemIt
1546 ( new SMDS_IteratorOnIterators
1547 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1548 while ( mainElemIt->more() )
1550 const SMDS_MeshElement* e = mainElemIt->next();
1552 for ( i = 0; ( i < nb && !isIn ); ++i )
1553 isIn = toolGroupVec[i]->Contains( e );
1556 resGroupDS->SMDSGroup().Add( e );
1559 // Update Python script
1560 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1561 << ".CutListOfGroups( " << theMainGroups
1562 << theToolGroups << ", '" << theName << "' )";
1564 SMESH_CATCH( SMESH::throwCorbaException );
1566 return aResGrp._retn();
1569 //=============================================================================
1571 \brief Create groups of entities from existing groups of superior dimensions
1573 1) extract all nodes from each group,
1574 2) combine all elements of specified dimension laying on these nodes.
1575 \param theGroups list of source groups
1576 \param theElemType dimension of elements
1577 \param theName name of new group
1578 \return pointer on new group
1582 //=============================================================================
1584 SMESH::SMESH_Group_ptr
1585 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1586 SMESH::ElementType theElemType,
1587 const char* theName )
1588 throw (SALOME::SALOME_Exception)
1590 SMESH::SMESH_Group_var aResGrp;
1594 _preMeshInfo->FullLoadFromFile();
1596 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1598 if ( !theName || !aMeshDS )
1599 return SMESH::SMESH_Group::_nil();
1601 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1607 aResGrp = CreateGroup( theElemType, theName );
1608 if ( aResGrp->_is_nil() )
1609 return SMESH::SMESH_Group::_nil();
1611 SMESHDS_GroupBase* groupBaseDS =
1612 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1613 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1615 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1617 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1618 if ( CORBA::is_nil( aGrp ) )
1621 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1622 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1624 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1626 while ( elIt->more() ) {
1627 const SMDS_MeshElement* el = elIt->next();
1628 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1629 while ( nIt->more() )
1630 resGroupCore.Add( nIt->next() );
1633 else // get elements of theElemType based on nodes of every element of group
1635 while ( elIt->more() )
1637 const SMDS_MeshElement* el = elIt->next(); // an element of group
1638 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1639 TIDSortedElemSet checkedElems;
1640 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1641 while ( nIt->more() )
1643 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1644 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1645 // check nodes of elements of theElemType around el
1646 while ( elOfTypeIt->more() )
1648 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1649 if ( !checkedElems.insert( elOfType ).second ) continue;
1651 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1652 bool allNodesOK = true;
1653 while ( nIt2->more() && allNodesOK )
1654 allNodesOK = elNodes.count( nIt2->next() );
1656 resGroupCore.Add( elOfType );
1663 // Update Python script
1664 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1665 << ".CreateDimGroup( "
1666 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1668 SMESH_CATCH( SMESH::throwCorbaException );
1670 return aResGrp._retn();
1673 //================================================================================
1675 * \brief Remember GEOM group data
1677 //================================================================================
1679 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1680 CORBA::Object_ptr theSmeshObj)
1682 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1685 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1686 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1687 if ( groupSO->_is_nil() )
1690 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1691 GEOM::GEOM_IGroupOperations_wrap groupOp =
1692 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1693 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1696 _geomGroupData.push_back( TGeomGroupData() );
1697 TGeomGroupData & groupData = _geomGroupData.back();
1699 CORBA::String_var entry = groupSO->GetID();
1700 groupData._groupEntry = entry.in();
1702 for ( int i = 0; i < ids->length(); ++i )
1703 groupData._indices.insert( ids[i] );
1705 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1708 //================================================================================
1710 * Remove GEOM group data relating to removed smesh object
1712 //================================================================================
1714 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1716 list<TGeomGroupData>::iterator
1717 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1718 for ( ; data != dataEnd; ++data ) {
1719 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1720 _geomGroupData.erase( data );
1726 //================================================================================
1728 * \brief Return new group contents if it has been changed and update group data
1730 //================================================================================
1732 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1734 TopoDS_Shape newShape;
1737 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1738 if ( study->_is_nil() ) return newShape; // means "not changed"
1739 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1740 if ( !groupSO->_is_nil() )
1742 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1743 if ( CORBA::is_nil( groupObj )) return newShape;
1744 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1746 // get indices of group items
1747 set<int> curIndices;
1748 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1749 GEOM::GEOM_IGroupOperations_wrap groupOp =
1750 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1751 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1752 for ( int i = 0; i < ids->length(); ++i )
1753 curIndices.insert( ids[i] );
1755 if ( groupData._indices == curIndices )
1756 return newShape; // group not changed
1759 groupData._indices = curIndices;
1761 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1762 if ( !geomClient ) return newShape;
1763 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1764 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1765 newShape = _gen_i->GeomObjectToShape( geomGroup );
1768 if ( newShape.IsNull() ) {
1769 // geom group becomes empty - return empty compound
1770 TopoDS_Compound compound;
1771 BRep_Builder().MakeCompound(compound);
1772 newShape = compound;
1779 //=============================================================================
1781 * \brief Storage of shape and index used in CheckGeomGroupModif()
1783 //=============================================================================
1784 struct TIndexedShape
1787 TopoDS_Shape _shape;
1788 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1791 //=============================================================================
1793 * \brief Update objects depending on changed geom groups
1795 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1796 * issue 0020210: Update of a smesh group after modification of the associated geom group
1798 //=============================================================================
1800 void SMESH_Mesh_i::CheckGeomGroupModif()
1802 if ( !_impl->HasShapeToMesh() ) return;
1804 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1805 if ( study->_is_nil() ) return;
1807 CORBA::Long nbEntities = NbNodes() + NbElements();
1809 // Check if group contents changed
1811 typedef map< string, TopoDS_Shape > TEntry2Geom;
1812 TEntry2Geom newGroupContents;
1814 list<TGeomGroupData>::iterator
1815 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1816 for ( ; data != dataEnd; ++data )
1818 pair< TEntry2Geom::iterator, bool > it_new =
1819 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1820 bool processedGroup = !it_new.second;
1821 TopoDS_Shape& newShape = it_new.first->second;
1822 if ( !processedGroup )
1823 newShape = newGroupShape( *data );
1824 if ( newShape.IsNull() )
1825 continue; // no changes
1828 _preMeshInfo->ForgetOrLoad();
1830 if ( processedGroup ) { // update group indices
1831 list<TGeomGroupData>::iterator data2 = data;
1832 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1833 data->_indices = data2->_indices;
1836 // Update SMESH objects according to new GEOM group contents
1838 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1839 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1841 int oldID = submesh->GetId();
1842 if ( !_mapSubMeshIor.count( oldID ))
1844 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1846 // update hypotheses
1847 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1848 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1849 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1851 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1852 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1854 // care of submeshes
1855 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1856 int newID = newSubmesh->GetId();
1857 if ( newID != oldID ) {
1858 _mapSubMesh [ newID ] = newSubmesh;
1859 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1860 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1861 _mapSubMesh. erase(oldID);
1862 _mapSubMesh_i. erase(oldID);
1863 _mapSubMeshIor.erase(oldID);
1864 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1869 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1870 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1871 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1873 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1875 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1876 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1877 ds->SetShape( newShape );
1882 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1883 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1885 // Remove groups and submeshes basing on removed sub-shapes
1887 TopTools_MapOfShape newShapeMap;
1888 TopoDS_Iterator shapeIt( newShape );
1889 for ( ; shapeIt.More(); shapeIt.Next() )
1890 newShapeMap.Add( shapeIt.Value() );
1892 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1893 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1895 if ( newShapeMap.Contains( shapeIt.Value() ))
1897 TopTools_IndexedMapOfShape oldShapeMap;
1898 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1899 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1901 const TopoDS_Shape& oldShape = oldShapeMap(i);
1902 int oldInd = meshDS->ShapeToIndex( oldShape );
1904 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1905 if ( i_smIor != _mapSubMeshIor.end() ) {
1906 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1909 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1910 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1912 // check if a group bases on oldInd shape
1913 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1914 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1915 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1916 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1918 RemoveGroup( i_grp->second ); // several groups can base on same shape
1919 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1924 // Reassign hypotheses and update groups after setting the new shape to mesh
1926 // collect anassigned hypotheses
1927 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1928 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1929 TShapeHypList assignedHyps;
1930 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1932 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1933 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1934 if ( !hyps.empty() ) {
1935 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1936 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1937 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1940 // collect shapes supporting groups
1941 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1942 TShapeTypeList groupData;
1943 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1944 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1945 for ( ; grIt != groups.end(); ++grIt )
1947 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1949 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1951 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1952 _impl->ShapeToMesh( newShape );
1954 // reassign hypotheses
1955 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1956 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1958 TIndexedShape& geom = indS_hyps->first;
1959 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1960 int oldID = geom._index;
1961 int newID = meshDS->ShapeToIndex( geom._shape );
1962 if ( oldID == 1 ) { // main shape
1964 geom._shape = newShape;
1968 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1969 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1970 // care of submeshes
1971 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1972 if ( newID != oldID ) {
1973 _mapSubMesh [ newID ] = newSubmesh;
1974 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1975 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1976 _mapSubMesh. erase(oldID);
1977 _mapSubMesh_i. erase(oldID);
1978 _mapSubMeshIor.erase(oldID);
1979 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1983 TShapeTypeList::iterator geomType = groupData.begin();
1984 for ( ; geomType != groupData.end(); ++geomType )
1986 const TIndexedShape& geom = geomType->first;
1987 int oldID = geom._index;
1988 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1991 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1992 CORBA::String_var name = groupSO->GetName();
1994 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1996 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1997 group_i->changeLocalId( newID );
2000 break; // everything has been updated
2003 } // loop on group data
2007 CORBA::Long newNbEntities = NbNodes() + NbElements();
2008 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2009 if ( newNbEntities != nbEntities )
2011 // Add all SObjects with icons to soToUpdateIcons
2012 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2014 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2015 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2016 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2018 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2019 i_gr != _mapGroups.end(); ++i_gr ) // groups
2020 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2023 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2024 for ( ; so != soToUpdateIcons.end(); ++so )
2025 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2028 //=============================================================================
2030 * \brief Create standalone group from a group on geometry or filter
2032 //=============================================================================
2034 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2035 throw (SALOME::SALOME_Exception)
2037 SMESH::SMESH_Group_var aGroup;
2042 _preMeshInfo->FullLoadFromFile();
2044 if ( theGroup->_is_nil() )
2045 return aGroup._retn();
2047 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2049 return aGroup._retn();
2051 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2053 const int anId = aGroupToRem->GetLocalID();
2054 if ( !_impl->ConvertToStandalone( anId ) )
2055 return aGroup._retn();
2056 removeGeomGroupData( theGroup );
2058 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2060 // remove old instance of group from own map
2061 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2062 _mapGroups.erase( anId );
2064 SALOMEDS::StudyBuilder_var builder;
2065 SALOMEDS::SObject_wrap aGroupSO;
2066 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2067 if ( !aStudy->_is_nil() ) {
2068 builder = aStudy->NewBuilder();
2069 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2070 if ( !aGroupSO->_is_nil() )
2072 // remove reference to geometry
2073 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2074 for ( ; chItr->More(); chItr->Next() )
2075 // Remove group's child SObject
2076 builder->RemoveObject( chItr->Value() );
2078 // Update Python script
2079 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2080 << ".ConvertToStandalone( " << aGroupSO << " )";
2082 // change icon of Group on Filter
2085 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2086 const int isEmpty = ( elemTypes->length() == 0 );
2089 SALOMEDS::GenericAttribute_wrap anAttr =
2090 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2091 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2092 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2098 // remember new group in own map
2099 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2100 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2102 // register CORBA object for persistence
2103 _gen_i->RegisterObject( aGroup );
2105 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2106 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2107 //aGroup->Register();
2108 aGroupToRem->UnRegister();
2110 SMESH_CATCH( SMESH::throwCorbaException );
2112 return aGroup._retn();
2115 //=============================================================================
2119 //=============================================================================
2121 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2123 if(MYDEBUG) MESSAGE( "createSubMesh" );
2124 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2125 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2126 const int subMeshId = mySubMesh->GetId();
2128 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2129 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2131 _mapSubMesh [subMeshId] = mySubMesh;
2132 _mapSubMesh_i [subMeshId] = subMeshServant;
2133 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2135 subMeshServant->Register();
2137 // register CORBA object for persistence
2138 int nextId = _gen_i->RegisterObject( subMesh );
2139 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2140 else { nextId = 0; } // avoid "unused variable" warning
2142 // to track changes of GEOM groups
2143 addGeomGroupData( theSubShapeObject, subMesh );
2145 return subMesh._retn();
2148 //=======================================================================
2149 //function : getSubMesh
2151 //=======================================================================
2153 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2155 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2156 if ( it == _mapSubMeshIor.end() )
2157 return SMESH::SMESH_subMesh::_nil();
2159 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2162 //=============================================================================
2166 //=============================================================================
2168 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2169 GEOM::GEOM_Object_ptr theSubShapeObject )
2171 bool isHypChanged = false;
2172 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2173 return isHypChanged;
2175 const int subMeshId = theSubMesh->GetId();
2177 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2179 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2181 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2184 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2185 isHypChanged = !hyps.empty();
2186 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2187 for ( ; hyp != hyps.end(); ++hyp )
2188 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2195 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2196 isHypChanged = ( aHypList->length() > 0 );
2197 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2198 removeHypothesis( theSubShapeObject, aHypList[i] );
2201 catch( const SALOME::SALOME_Exception& ) {
2202 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2204 removeGeomGroupData( theSubShapeObject );
2208 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2209 if ( id_smi != _mapSubMesh_i.end() )
2210 id_smi->second->UnRegister();
2212 // remove a CORBA object
2213 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2214 if ( id_smptr != _mapSubMeshIor.end() )
2215 SMESH::SMESH_subMesh_var( id_smptr->second );
2217 _mapSubMesh.erase(subMeshId);
2218 _mapSubMesh_i.erase(subMeshId);
2219 _mapSubMeshIor.erase(subMeshId);
2221 return isHypChanged;
2224 //=============================================================================
2228 //=============================================================================
2230 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2231 const char* theName,
2232 const TopoDS_Shape& theShape,
2233 const SMESH_PredicatePtr& thePredicate )
2235 std::string newName;
2236 if ( !theName || strlen( theName ) == 0 )
2238 std::set< std::string > presentNames;
2239 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2240 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2242 CORBA::String_var name = i_gr->second->GetName();
2243 presentNames.insert( name.in() );
2246 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2247 } while ( !presentNames.insert( newName ).second );
2248 theName = newName.c_str();
2251 SMESH::SMESH_GroupBase_var aGroup;
2252 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2254 SMESH_GroupBase_i* aGroupImpl;
2255 if ( !theShape.IsNull() )
2256 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2257 else if ( thePredicate )
2258 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2260 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2262 aGroup = aGroupImpl->_this();
2263 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2264 aGroupImpl->Register();
2266 // register CORBA object for persistence
2267 int nextId = _gen_i->RegisterObject( aGroup );
2268 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2269 else { nextId = 0; } // avoid "unused variable" warning in release mode
2271 // to track changes of GEOM groups
2272 if ( !theShape.IsNull() ) {
2273 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2274 addGeomGroupData( geom, aGroup );
2277 return aGroup._retn();
2280 //=============================================================================
2282 * SMESH_Mesh_i::removeGroup
2284 * Should be called by ~SMESH_Group_i()
2286 //=============================================================================
2288 void SMESH_Mesh_i::removeGroup( const int theId )
2290 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2291 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2292 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2293 _mapGroups.erase( theId );
2294 removeGeomGroupData( group );
2295 if ( !_impl->RemoveGroup( theId ))
2297 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2298 RemoveGroup( group );
2300 group->UnRegister();
2304 //=============================================================================
2308 //=============================================================================
2310 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2311 throw(SALOME::SALOME_Exception)
2313 SMESH::log_array_var aLog;
2317 _preMeshInfo->FullLoadFromFile();
2319 list < SMESHDS_Command * >logDS = _impl->GetLog();
2320 aLog = new SMESH::log_array;
2322 int lg = logDS.size();
2325 list < SMESHDS_Command * >::iterator its = logDS.begin();
2326 while(its != logDS.end()){
2327 SMESHDS_Command *com = *its;
2328 int comType = com->GetType();
2330 int lgcom = com->GetNumber();
2332 const list < int >&intList = com->GetIndexes();
2333 int inum = intList.size();
2335 list < int >::const_iterator ii = intList.begin();
2336 const list < double >&coordList = com->GetCoords();
2337 int rnum = coordList.size();
2339 list < double >::const_iterator ir = coordList.begin();
2340 aLog[indexLog].commandType = comType;
2341 aLog[indexLog].number = lgcom;
2342 aLog[indexLog].coords.length(rnum);
2343 aLog[indexLog].indexes.length(inum);
2344 for(int i = 0; i < rnum; i++){
2345 aLog[indexLog].coords[i] = *ir;
2346 //MESSAGE(" "<<i<<" "<<ir.Value());
2349 for(int i = 0; i < inum; i++){
2350 aLog[indexLog].indexes[i] = *ii;
2351 //MESSAGE(" "<<i<<" "<<ii.Value());
2360 SMESH_CATCH( SMESH::throwCorbaException );
2362 return aLog._retn();
2366 //=============================================================================
2370 //=============================================================================
2372 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2376 SMESH_CATCH( SMESH::throwCorbaException );
2379 //=============================================================================
2383 //=============================================================================
2385 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2390 //=============================================================================
2394 //=============================================================================
2396 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2401 //=============================================================================
2404 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2405 // issue 0020918: groups removal is caused by hyp modification
2406 // issue 0021208: to forget not loaded mesh data at hyp modification
2407 struct TCallUp_i : public SMESH_Mesh::TCallUp
2409 SMESH_Mesh_i* _mesh;
2410 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2411 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2412 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2413 virtual void Load () { _mesh->Load(); }
2417 //================================================================================
2419 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2421 //================================================================================
2423 void SMESH_Mesh_i::onHypothesisModified()
2426 _preMeshInfo->ForgetOrLoad();
2429 //=============================================================================
2433 //=============================================================================
2435 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2437 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2440 _impl->SetCallUp( new TCallUp_i(this));
2443 //=============================================================================
2447 //=============================================================================
2449 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2451 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2455 //=============================================================================
2457 * Return mesh editor
2459 //=============================================================================
2461 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2462 throw (SALOME::SALOME_Exception)
2464 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2468 _preMeshInfo->FullLoadFromFile();
2470 // Create MeshEditor
2472 _editor = new SMESH_MeshEditor_i( this, false );
2473 aMeshEdVar = _editor->_this();
2475 // Update Python script
2476 TPythonDump() << _editor << " = "
2477 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2479 SMESH_CATCH( SMESH::throwCorbaException );
2481 return aMeshEdVar._retn();
2484 //=============================================================================
2486 * Return mesh edition previewer
2488 //=============================================================================
2490 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2491 throw (SALOME::SALOME_Exception)
2493 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2497 _preMeshInfo->FullLoadFromFile();
2499 if ( !_previewEditor )
2500 _previewEditor = new SMESH_MeshEditor_i( this, true );
2501 aMeshEdVar = _previewEditor->_this();
2503 SMESH_CATCH( SMESH::throwCorbaException );
2505 return aMeshEdVar._retn();
2508 //================================================================================
2510 * \brief Return true if the mesh has been edited since a last total re-compute
2511 * and those modifications may prevent successful partial re-compute
2513 //================================================================================
2515 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2517 Unexpect aCatch(SALOME_SalomeException);
2518 return _impl->HasModificationsToDiscard();
2521 //================================================================================
2523 * \brief Returns a random unique color
2525 //================================================================================
2527 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2529 const int MAX_ATTEMPTS = 100;
2531 double tolerance = 0.5;
2532 SALOMEDS::Color col;
2536 // generate random color
2537 double red = (double)rand() / RAND_MAX;
2538 double green = (double)rand() / RAND_MAX;
2539 double blue = (double)rand() / RAND_MAX;
2540 // check existence in the list of the existing colors
2541 bool matched = false;
2542 std::list<SALOMEDS::Color>::const_iterator it;
2543 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2544 SALOMEDS::Color color = *it;
2545 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2546 matched = tol < tolerance;
2548 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2549 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2557 //=============================================================================
2559 * Sets auto-color mode. If it is on, groups get unique random colors
2561 //=============================================================================
2563 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2565 Unexpect aCatch(SALOME_SalomeException);
2566 _impl->SetAutoColor(theAutoColor);
2568 TPythonDump pyDump; // not to dump group->SetColor() from below code
2569 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2571 std::list<SALOMEDS::Color> aReservedColors;
2572 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2573 for ( ; it != _mapGroups.end(); it++ ) {
2574 if ( CORBA::is_nil( it->second )) continue;
2575 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2576 it->second->SetColor( aColor );
2577 aReservedColors.push_back( aColor );
2581 //=============================================================================
2583 * Returns true if auto-color mode is on
2585 //=============================================================================
2587 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2589 Unexpect aCatch(SALOME_SalomeException);
2590 return _impl->GetAutoColor();
2593 //=============================================================================
2595 * Checks if there are groups with equal names
2597 //=============================================================================
2599 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2601 return _impl->HasDuplicatedGroupNamesMED();
2604 //================================================================================
2606 * \brief Care of a file before exporting mesh into it
2608 //================================================================================
2610 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2612 TCollection_AsciiString aFullName ((char*)file);
2613 OSD_Path aPath (aFullName);
2614 OSD_File aFile (aPath);
2615 if (aFile.Exists()) {
2616 // existing filesystem node
2617 if (aFile.KindOfFile() == OSD_FILE) {
2618 if (aFile.IsWriteable()) {
2623 if (aFile.Failed()) {
2624 TCollection_AsciiString msg ("File ");
2625 msg += aFullName + " cannot be replaced.";
2626 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2629 TCollection_AsciiString msg ("File ");
2630 msg += aFullName + " cannot be overwritten.";
2631 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2634 TCollection_AsciiString msg ("Location ");
2635 msg += aFullName + " is not a file.";
2636 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2639 // nonexisting file; check if it can be created
2641 aFile.Build(OSD_WriteOnly, OSD_Protection());
2642 if (aFile.Failed()) {
2643 TCollection_AsciiString msg ("You cannot create the file ");
2644 msg += aFullName + ". Check the directory existance and access rights.";
2645 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2653 //================================================================================
2655 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2656 * \param file - file name
2657 * \param overwrite - to erase the file or not
2658 * \retval string - mesh name
2660 //================================================================================
2662 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2663 CORBA::Boolean overwrite)
2666 PrepareForWriting(file, overwrite);
2667 string aMeshName = "Mesh";
2668 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2669 if ( !aStudy->_is_nil() ) {
2670 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2671 if ( !aMeshSO->_is_nil() ) {
2672 CORBA::String_var name = aMeshSO->GetName();
2674 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2675 if ( !aStudy->GetProperties()->IsLocked() )
2677 SALOMEDS::GenericAttribute_wrap anAttr;
2678 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2679 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2680 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2681 ASSERT(!aFileName->_is_nil());
2682 aFileName->SetValue(file);
2683 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2684 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2685 ASSERT(!aFileType->_is_nil());
2686 aFileType->SetValue("FICHIERMED");
2690 // Update Python script
2691 // set name of mesh before export
2692 TPythonDump() << _gen_i << ".SetName("
2693 << SMESH::SMESH_Mesh_var(_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 CORBA::Boolean autoDimension)
2712 throw(SALOME::SALOME_Exception)
2716 _preMeshInfo->FullLoadFromFile();
2718 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2719 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2720 << file << "', " << auto_groups << ", "
2721 << theVersion << ", " << overwrite << ", "
2722 << autoDimension << " )";
2724 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2726 SMESH_CATCH( SMESH::throwCorbaException );
2729 //================================================================================
2731 * \brief Export a mesh to a med file
2733 //================================================================================
2735 void SMESH_Mesh_i::ExportToMED (const char* file,
2736 CORBA::Boolean auto_groups,
2737 SMESH::MED_VERSION theVersion)
2738 throw(SALOME::SALOME_Exception)
2740 ExportToMEDX(file,auto_groups,theVersion,true);
2743 //================================================================================
2745 * \brief Export a mesh to a med file
2747 //================================================================================
2749 void SMESH_Mesh_i::ExportMED (const char* file,
2750 CORBA::Boolean auto_groups)
2751 throw(SALOME::SALOME_Exception)
2753 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2756 //================================================================================
2758 * \brief Export a mesh to a SAUV file
2760 //================================================================================
2762 void SMESH_Mesh_i::ExportSAUV (const char* file,
2763 CORBA::Boolean auto_groups)
2764 throw(SALOME::SALOME_Exception)
2766 Unexpect aCatch(SALOME_SalomeException);
2768 _preMeshInfo->FullLoadFromFile();
2770 string aMeshName = prepareMeshNameAndGroups(file, true);
2771 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2772 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2773 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2777 //================================================================================
2779 * \brief Export a mesh to a DAT file
2781 //================================================================================
2783 void SMESH_Mesh_i::ExportDAT (const char *file)
2784 throw(SALOME::SALOME_Exception)
2786 Unexpect aCatch(SALOME_SalomeException);
2788 _preMeshInfo->FullLoadFromFile();
2790 // Update Python script
2791 // check names of groups
2793 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2796 PrepareForWriting(file);
2797 _impl->ExportDAT(file);
2800 //================================================================================
2802 * \brief Export a mesh to an UNV file
2804 //================================================================================
2806 void SMESH_Mesh_i::ExportUNV (const char *file)
2807 throw(SALOME::SALOME_Exception)
2809 Unexpect aCatch(SALOME_SalomeException);
2811 _preMeshInfo->FullLoadFromFile();
2813 // Update Python script
2814 // check names of groups
2816 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2819 PrepareForWriting(file);
2820 _impl->ExportUNV(file);
2823 //================================================================================
2825 * \brief Export a mesh to an STL file
2827 //================================================================================
2829 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2830 throw(SALOME::SALOME_Exception)
2832 Unexpect aCatch(SALOME_SalomeException);
2834 _preMeshInfo->FullLoadFromFile();
2836 // Update Python script
2837 // check names of groups
2839 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2840 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2843 PrepareForWriting(file);
2844 _impl->ExportSTL(file, isascii);
2847 //================================================================================
2849 * \brief Export a part of mesh to a med file
2851 //================================================================================
2853 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2855 CORBA::Boolean auto_groups,
2856 ::SMESH::MED_VERSION version,
2857 ::CORBA::Boolean overwrite,
2858 ::CORBA::Boolean autoDimension)
2859 throw (SALOME::SALOME_Exception)
2861 Unexpect aCatch(SALOME_SalomeException);
2864 if ( SMESH_Mesh_i * mesh = SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
2866 mesh->ExportToMEDX( file, auto_groups, version, autoDimension );
2871 _preMeshInfo->FullLoadFromFile();
2873 PrepareForWriting(file, overwrite);
2875 string aMeshName = "Mesh";
2876 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2877 if ( !aStudy->_is_nil() ) {
2878 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2879 if ( !SO->_is_nil() ) {
2880 CORBA::String_var name = SO->GetName();
2884 SMESH_MeshPartDS partDS( meshPart );
2885 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS, autoDimension );
2887 pyDump << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToMED( "
2888 << meshPart << ", r'" << file << "', "
2889 << auto_groups << ", " << version << ", " << overwrite << ", "
2890 << autoDimension << " )";
2893 //================================================================================
2895 * \brief Export a part of mesh to a DAT file
2897 //================================================================================
2899 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2901 throw (SALOME::SALOME_Exception)
2903 Unexpect aCatch(SALOME_SalomeException);
2905 _preMeshInfo->FullLoadFromFile();
2907 PrepareForWriting(file);
2909 SMESH_MeshPartDS partDS( meshPart );
2910 _impl->ExportDAT(file,&partDS);
2912 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2913 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2915 //================================================================================
2917 * \brief Export a part of mesh to an UNV file
2919 //================================================================================
2921 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2923 throw (SALOME::SALOME_Exception)
2925 Unexpect aCatch(SALOME_SalomeException);
2927 _preMeshInfo->FullLoadFromFile();
2929 PrepareForWriting(file);
2931 SMESH_MeshPartDS partDS( meshPart );
2932 _impl->ExportUNV(file, &partDS);
2934 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2935 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2937 //================================================================================
2939 * \brief Export a part of mesh to an STL file
2941 //================================================================================
2943 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2945 ::CORBA::Boolean isascii)
2946 throw (SALOME::SALOME_Exception)
2948 Unexpect aCatch(SALOME_SalomeException);
2950 _preMeshInfo->FullLoadFromFile();
2952 PrepareForWriting(file);
2954 SMESH_MeshPartDS partDS( meshPart );
2955 _impl->ExportSTL(file, isascii, &partDS);
2957 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
2958 << meshPart<< ", r'" << file << "', " << isascii << ")";
2961 //================================================================================
2963 * \brief Export a part of mesh to an STL file
2965 //================================================================================
2967 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2969 CORBA::Boolean overwrite)
2970 throw (SALOME::SALOME_Exception)
2973 Unexpect aCatch(SALOME_SalomeException);
2975 _preMeshInfo->FullLoadFromFile();
2977 PrepareForWriting(file,overwrite);
2979 SMESH_MeshPartDS partDS( meshPart );
2980 _impl->ExportCGNS(file, &partDS);
2982 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
2983 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2985 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2989 //================================================================================
2991 * \brief Export a part of mesh to a GMF file
2993 //================================================================================
2995 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2997 bool withRequiredGroups)
2998 throw (SALOME::SALOME_Exception)
3000 Unexpect aCatch(SALOME_SalomeException);
3002 _preMeshInfo->FullLoadFromFile();
3004 PrepareForWriting(file,/*overwrite=*/true);
3006 SMESH_MeshPartDS partDS( meshPart );
3007 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3009 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3010 << meshPart<< ", r'"
3012 << withRequiredGroups << ")";
3015 //=============================================================================
3017 * Return computation progress [0.,1]
3019 //=============================================================================
3021 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3025 return _impl->GetComputeProgress();
3027 SMESH_CATCH( SMESH::doNothing );
3031 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3033 Unexpect aCatch(SALOME_SalomeException);
3035 return _preMeshInfo->NbNodes();
3037 return _impl->NbNodes();
3040 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3042 Unexpect aCatch(SALOME_SalomeException);
3044 return _preMeshInfo->NbElements();
3046 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3049 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3051 Unexpect aCatch(SALOME_SalomeException);
3053 return _preMeshInfo->Nb0DElements();
3055 return _impl->Nb0DElements();
3058 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3060 Unexpect aCatch(SALOME_SalomeException);
3062 return _preMeshInfo->NbBalls();
3064 return _impl->NbBalls();
3067 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3069 Unexpect aCatch(SALOME_SalomeException);
3071 return _preMeshInfo->NbEdges();
3073 return _impl->NbEdges();
3076 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3077 throw(SALOME::SALOME_Exception)
3079 Unexpect aCatch(SALOME_SalomeException);
3081 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3083 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3086 //=============================================================================
3088 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3090 Unexpect aCatch(SALOME_SalomeException);
3092 return _preMeshInfo->NbFaces();
3094 return _impl->NbFaces();
3097 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3099 Unexpect aCatch(SALOME_SalomeException);
3101 return _preMeshInfo->NbTriangles();
3103 return _impl->NbTriangles();
3106 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3108 Unexpect aCatch(SALOME_SalomeException);
3110 return _preMeshInfo->NbBiQuadTriangles();
3112 return _impl->NbBiQuadTriangles();
3115 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3117 Unexpect aCatch(SALOME_SalomeException);
3119 return _preMeshInfo->NbQuadrangles();
3121 return _impl->NbQuadrangles();
3124 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3126 Unexpect aCatch(SALOME_SalomeException);
3128 return _preMeshInfo->NbBiQuadQuadrangles();
3130 return _impl->NbBiQuadQuadrangles();
3133 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3135 Unexpect aCatch(SALOME_SalomeException);
3137 return _preMeshInfo->NbPolygons();
3139 return _impl->NbPolygons();
3142 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3143 throw(SALOME::SALOME_Exception)
3145 Unexpect aCatch(SALOME_SalomeException);
3147 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3149 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3152 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3153 throw(SALOME::SALOME_Exception)
3155 Unexpect aCatch(SALOME_SalomeException);
3157 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3159 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3162 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3163 throw(SALOME::SALOME_Exception)
3165 Unexpect aCatch(SALOME_SalomeException);
3167 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3169 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3172 //=============================================================================
3174 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3176 Unexpect aCatch(SALOME_SalomeException);
3178 return _preMeshInfo->NbVolumes();
3180 return _impl->NbVolumes();
3183 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3185 Unexpect aCatch(SALOME_SalomeException);
3187 return _preMeshInfo->NbTetras();
3189 return _impl->NbTetras();
3192 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3194 Unexpect aCatch(SALOME_SalomeException);
3196 return _preMeshInfo->NbHexas();
3198 return _impl->NbHexas();
3201 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3203 Unexpect aCatch(SALOME_SalomeException);
3205 return _preMeshInfo->NbTriQuadHexas();
3207 return _impl->NbTriQuadraticHexas();
3210 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3212 Unexpect aCatch(SALOME_SalomeException);
3214 return _preMeshInfo->NbPyramids();
3216 return _impl->NbPyramids();
3219 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3221 Unexpect aCatch(SALOME_SalomeException);
3223 return _preMeshInfo->NbPrisms();
3225 return _impl->NbPrisms();
3228 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3230 Unexpect aCatch(SALOME_SalomeException);
3232 return _preMeshInfo->NbHexPrisms();
3234 return _impl->NbHexagonalPrisms();
3237 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3239 Unexpect aCatch(SALOME_SalomeException);
3241 return _preMeshInfo->NbPolyhedrons();
3243 return _impl->NbPolyhedrons();
3246 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3247 throw(SALOME::SALOME_Exception)
3249 Unexpect aCatch(SALOME_SalomeException);
3251 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3253 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3256 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3257 throw(SALOME::SALOME_Exception)
3259 Unexpect aCatch(SALOME_SalomeException);
3261 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3263 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3266 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3267 throw(SALOME::SALOME_Exception)
3269 Unexpect aCatch(SALOME_SalomeException);
3271 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3273 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3276 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3277 throw(SALOME::SALOME_Exception)
3279 Unexpect aCatch(SALOME_SalomeException);
3281 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3283 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3286 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3287 throw(SALOME::SALOME_Exception)
3289 Unexpect aCatch(SALOME_SalomeException);
3291 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3293 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3296 //=============================================================================
3298 * Returns nb of published sub-meshes
3300 //=============================================================================
3302 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3304 Unexpect aCatch(SALOME_SalomeException);
3305 return _mapSubMesh_i.size();
3308 //=============================================================================
3310 * Dumps mesh into a string
3312 //=============================================================================
3314 char* SMESH_Mesh_i::Dump()
3318 return CORBA::string_dup( os.str().c_str() );
3321 //=============================================================================
3323 * Method of SMESH_IDSource interface
3325 //=============================================================================
3327 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3329 return GetElementsId();
3332 //=============================================================================
3334 * Returns ids of all elements
3336 //=============================================================================
3338 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3339 throw (SALOME::SALOME_Exception)
3341 Unexpect aCatch(SALOME_SalomeException);
3343 _preMeshInfo->FullLoadFromFile();
3345 SMESH::long_array_var aResult = new SMESH::long_array();
3346 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3348 if ( aSMESHDS_Mesh == NULL )
3349 return aResult._retn();
3351 long nbElements = NbElements();
3352 aResult->length( nbElements );
3353 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3354 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3355 aResult[i] = anIt->next()->GetID();
3357 return aResult._retn();
3361 //=============================================================================
3363 * Returns ids of all elements of given type
3365 //=============================================================================
3367 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3368 throw (SALOME::SALOME_Exception)
3370 Unexpect aCatch(SALOME_SalomeException);
3372 _preMeshInfo->FullLoadFromFile();
3374 SMESH::long_array_var aResult = new SMESH::long_array();
3375 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3377 if ( aSMESHDS_Mesh == NULL )
3378 return aResult._retn();
3380 long nbElements = NbElements();
3382 // No sense in returning ids of elements along with ids of nodes:
3383 // when theElemType == SMESH::ALL, return node ids only if
3384 // there are no elements
3385 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3386 return GetNodesId();
3388 aResult->length( nbElements );
3392 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3393 while ( i < nbElements && anIt->more() )
3394 aResult[i++] = anIt->next()->GetID();
3396 aResult->length( i );
3398 return aResult._retn();
3401 //=============================================================================
3403 * Returns ids of all nodes
3405 //=============================================================================
3407 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3408 throw (SALOME::SALOME_Exception)
3410 Unexpect aCatch(SALOME_SalomeException);
3412 _preMeshInfo->FullLoadFromFile();
3414 SMESH::long_array_var aResult = new SMESH::long_array();
3415 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3417 if ( aSMESHDS_Mesh == NULL )
3418 return aResult._retn();
3420 long nbNodes = NbNodes();
3421 aResult->length( nbNodes );
3422 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3423 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3424 aResult[i] = anIt->next()->GetID();
3426 return aResult._retn();
3429 //=============================================================================
3433 //=============================================================================
3435 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3436 throw (SALOME::SALOME_Exception)
3438 SMESH::ElementType type;
3442 _preMeshInfo->FullLoadFromFile();
3444 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3446 SMESH_CATCH( SMESH::throwCorbaException );
3451 //=============================================================================
3455 //=============================================================================
3457 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3458 throw (SALOME::SALOME_Exception)
3461 _preMeshInfo->FullLoadFromFile();
3463 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3465 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3467 return ( SMESH::EntityType ) e->GetEntityType();
3470 //=============================================================================
3474 //=============================================================================
3476 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3477 throw (SALOME::SALOME_Exception)
3480 _preMeshInfo->FullLoadFromFile();
3482 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3484 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3486 return ( SMESH::GeometryType ) e->GetGeomType();
3489 //=============================================================================
3491 * Returns ID of elements for given submesh
3493 //=============================================================================
3494 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3495 throw (SALOME::SALOME_Exception)
3497 SMESH::long_array_var aResult = new SMESH::long_array();
3501 _preMeshInfo->FullLoadFromFile();
3503 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3504 if(!SM) return aResult._retn();
3506 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3507 if(!SDSM) return aResult._retn();
3509 aResult->length(SDSM->NbElements());
3511 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3513 while ( eIt->more() ) {
3514 aResult[i++] = eIt->next()->GetID();
3517 SMESH_CATCH( SMESH::throwCorbaException );
3519 return aResult._retn();
3522 //=============================================================================
3524 * Returns ID of nodes for given submesh
3525 * If param all==true - returns all nodes, else -
3526 * returns only nodes on shapes.
3528 //=============================================================================
3530 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3532 throw (SALOME::SALOME_Exception)
3534 SMESH::long_array_var aResult = new SMESH::long_array();
3538 _preMeshInfo->FullLoadFromFile();
3540 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3541 if(!SM) return aResult._retn();
3543 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3544 if(!SDSM) return aResult._retn();
3547 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3548 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3549 while ( nIt->more() ) {
3550 const SMDS_MeshNode* elem = nIt->next();
3551 theElems.insert( elem->GetID() );
3554 else { // all nodes of submesh elements
3555 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3556 while ( eIt->more() ) {
3557 const SMDS_MeshElement* anElem = eIt->next();
3558 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3559 while ( nIt->more() ) {
3560 const SMDS_MeshElement* elem = nIt->next();
3561 theElems.insert( elem->GetID() );
3566 aResult->length(theElems.size());
3567 set<int>::iterator itElem;
3569 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3570 aResult[i++] = *itElem;
3572 SMESH_CATCH( SMESH::throwCorbaException );
3574 return aResult._retn();
3577 //=============================================================================
3579 * Returns type of elements for given submesh
3581 //=============================================================================
3583 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3584 throw (SALOME::SALOME_Exception)
3586 SMESH::ElementType type;
3590 _preMeshInfo->FullLoadFromFile();
3592 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3593 if(!SM) return SMESH::ALL;
3595 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3596 if(!SDSM) return SMESH::ALL;
3598 if(SDSM->NbElements()==0)
3599 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3601 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3602 const SMDS_MeshElement* anElem = eIt->next();
3604 type = ( SMESH::ElementType ) anElem->GetType();
3606 SMESH_CATCH( SMESH::throwCorbaException );
3612 //=============================================================================
3614 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3616 //=============================================================================
3618 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3621 _preMeshInfo->FullLoadFromFile();
3623 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3625 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3630 //=============================================================================
3632 * Get XYZ coordinates of node as list of double
3633 * If there is not node for given ID - returns empty list
3635 //=============================================================================
3637 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3640 _preMeshInfo->FullLoadFromFile();
3642 SMESH::double_array_var aResult = new SMESH::double_array();
3643 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3644 if ( aSMESHDS_Mesh == NULL )
3645 return aResult._retn();
3648 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3650 return aResult._retn();
3654 aResult[0] = aNode->X();
3655 aResult[1] = aNode->Y();
3656 aResult[2] = aNode->Z();
3657 return aResult._retn();
3661 //=============================================================================
3663 * For given node returns list of IDs of inverse elements
3664 * If there is not node for given ID - returns empty list
3666 //=============================================================================
3668 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3671 _preMeshInfo->FullLoadFromFile();
3673 SMESH::long_array_var aResult = new SMESH::long_array();
3674 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3675 if ( aSMESHDS_Mesh == NULL )
3676 return aResult._retn();
3679 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3681 return aResult._retn();
3683 // find inverse elements
3684 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3685 TColStd_SequenceOfInteger IDs;
3686 while(eIt->more()) {
3687 const SMDS_MeshElement* elem = eIt->next();
3688 IDs.Append(elem->GetID());
3690 if(IDs.Length()>0) {
3691 aResult->length(IDs.Length());
3693 for(; i<=IDs.Length(); i++) {
3694 aResult[i-1] = IDs.Value(i);
3697 return aResult._retn();
3700 //=============================================================================
3702 * \brief Return position of a node on shape
3704 //=============================================================================
3706 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3709 _preMeshInfo->FullLoadFromFile();
3711 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3712 aNodePosition->shapeID = 0;
3713 aNodePosition->shapeType = GEOM::SHAPE;
3715 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3716 if ( !mesh ) return aNodePosition;
3718 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3720 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3722 aNodePosition->shapeID = aNode->getshapeId();
3723 switch ( pos->GetTypeOfPosition() ) {
3725 aNodePosition->shapeType = GEOM::EDGE;
3726 aNodePosition->params.length(1);
3727 aNodePosition->params[0] =
3728 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3731 aNodePosition->shapeType = GEOM::FACE;
3732 aNodePosition->params.length(2);
3733 aNodePosition->params[0] =
3734 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3735 aNodePosition->params[1] =
3736 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3738 case SMDS_TOP_VERTEX:
3739 aNodePosition->shapeType = GEOM::VERTEX;
3741 case SMDS_TOP_3DSPACE:
3742 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3743 aNodePosition->shapeType = GEOM::SOLID;
3744 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3745 aNodePosition->shapeType = GEOM::SHELL;
3751 return aNodePosition;
3754 //=============================================================================
3756 * \brief Return position of an element on shape
3758 //=============================================================================
3760 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
3763 _preMeshInfo->FullLoadFromFile();
3765 SMESH::ElementPosition anElementPosition;
3766 anElementPosition.shapeID = 0;
3767 anElementPosition.shapeType = GEOM::SHAPE;
3769 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3770 if ( !mesh ) return anElementPosition;
3772 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
3774 anElementPosition.shapeID = anElem->getshapeId();
3775 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
3776 if ( !aSp.IsNull() ) {
3777 switch ( aSp.ShapeType() ) {
3779 anElementPosition.shapeType = GEOM::EDGE;
3782 anElementPosition.shapeType = GEOM::FACE;
3785 anElementPosition.shapeType = GEOM::VERTEX;
3788 anElementPosition.shapeType = GEOM::SOLID;
3791 anElementPosition.shapeType = GEOM::SHELL;
3797 return anElementPosition;
3800 //=============================================================================
3802 * If given element is node returns IDs of shape from position
3803 * If there is not node for given ID - returns -1
3805 //=============================================================================
3807 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3810 _preMeshInfo->FullLoadFromFile();
3812 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3813 if ( aSMESHDS_Mesh == NULL )
3817 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3819 return aNode->getshapeId();
3826 //=============================================================================
3828 * For given element returns ID of result shape after
3829 * ::FindShape() from SMESH_MeshEditor
3830 * If there is not element for given ID - returns -1
3832 //=============================================================================
3834 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3837 _preMeshInfo->FullLoadFromFile();
3839 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3840 if ( aSMESHDS_Mesh == NULL )
3843 // try to find element
3844 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3848 ::SMESH_MeshEditor aMeshEditor(_impl);
3849 int index = aMeshEditor.FindShape( elem );
3857 //=============================================================================
3859 * Returns number of nodes for given element
3860 * If there is not element for given ID - returns -1
3862 //=============================================================================
3864 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3867 _preMeshInfo->FullLoadFromFile();
3869 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3870 if ( aSMESHDS_Mesh == NULL ) return -1;
3871 // try to find element
3872 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3873 if(!elem) return -1;
3874 return elem->NbNodes();
3878 //=============================================================================
3880 * Returns ID of node by given index for given element
3881 * If there is not element for given ID - returns -1
3882 * If there is not node for given index - returns -2
3884 //=============================================================================
3886 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3889 _preMeshInfo->FullLoadFromFile();
3891 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3892 if ( aSMESHDS_Mesh == NULL ) return -1;
3893 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3894 if(!elem) return -1;
3895 if( index>=elem->NbNodes() || index<0 ) return -1;
3896 return elem->GetNode(index)->GetID();
3899 //=============================================================================
3901 * Returns IDs of nodes of given element
3903 //=============================================================================
3905 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3908 _preMeshInfo->FullLoadFromFile();
3910 SMESH::long_array_var aResult = new SMESH::long_array();
3911 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3913 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3915 aResult->length( elem->NbNodes() );
3916 for ( int i = 0; i < elem->NbNodes(); ++i )
3917 aResult[ i ] = elem->GetNode( i )->GetID();
3920 return aResult._retn();
3923 //=============================================================================
3925 * Returns true if given node is medium node
3926 * in given quadratic element
3928 //=============================================================================
3930 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3933 _preMeshInfo->FullLoadFromFile();
3935 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3936 if ( aSMESHDS_Mesh == NULL ) return false;
3938 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3939 if(!aNode) return false;
3940 // try to find element
3941 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3942 if(!elem) return false;
3944 return elem->IsMediumNode(aNode);
3948 //=============================================================================
3950 * Returns true if given node is medium node
3951 * in one of quadratic elements
3953 //=============================================================================
3955 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3956 SMESH::ElementType theElemType)
3959 _preMeshInfo->FullLoadFromFile();
3961 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3962 if ( aSMESHDS_Mesh == NULL ) return false;
3965 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3966 if(!aNode) return false;
3968 SMESH_MesherHelper aHelper( *(_impl) );
3970 SMDSAbs_ElementType aType;
3971 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3972 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3973 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3974 else aType = SMDSAbs_All;
3976 return aHelper.IsMedium(aNode,aType);
3980 //=============================================================================
3982 * Returns number of edges for given element
3984 //=============================================================================
3986 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3989 _preMeshInfo->FullLoadFromFile();
3991 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3992 if ( aSMESHDS_Mesh == NULL ) return -1;
3993 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3994 if(!elem) return -1;
3995 return elem->NbEdges();
3999 //=============================================================================
4001 * Returns number of faces for given element
4003 //=============================================================================
4005 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4008 _preMeshInfo->FullLoadFromFile();
4010 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4011 if ( aSMESHDS_Mesh == NULL ) return -1;
4012 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4013 if(!elem) return -1;
4014 return elem->NbFaces();
4017 //=======================================================================
4018 //function : GetElemFaceNodes
4019 //purpose : Returns nodes of given face (counted from zero) for given element.
4020 //=======================================================================
4022 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4023 CORBA::Short faceIndex)
4026 _preMeshInfo->FullLoadFromFile();
4028 SMESH::long_array_var aResult = new SMESH::long_array();
4029 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4031 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4033 SMDS_VolumeTool vtool( elem );
4034 if ( faceIndex < vtool.NbFaces() )
4036 aResult->length( vtool.NbFaceNodes( faceIndex ));
4037 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4038 for ( int i = 0; i < aResult->length(); ++i )
4039 aResult[ i ] = nn[ i ]->GetID();
4043 return aResult._retn();
4046 //=======================================================================
4047 //function : GetElemFaceNodes
4048 //purpose : Returns three components of normal of given mesh face.
4049 //=======================================================================
4051 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4052 CORBA::Boolean normalized)
4055 _preMeshInfo->FullLoadFromFile();
4057 SMESH::double_array_var aResult = new SMESH::double_array();
4059 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4062 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4064 aResult->length( 3 );
4065 aResult[ 0 ] = normal.X();
4066 aResult[ 1 ] = normal.Y();
4067 aResult[ 2 ] = normal.Z();
4070 return aResult._retn();
4073 //=======================================================================
4074 //function : FindElementByNodes
4075 //purpose : Returns an element based on all given nodes.
4076 //=======================================================================
4078 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4081 _preMeshInfo->FullLoadFromFile();
4083 CORBA::Long elemID(0);
4084 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4086 vector< const SMDS_MeshNode * > nn( nodes.length() );
4087 for ( int i = 0; i < nodes.length(); ++i )
4088 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4091 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4092 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4093 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4094 _impl->NbVolumes( ORDER_QUADRATIC )))
4095 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4097 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4102 //=============================================================================
4104 * Returns true if given element is polygon
4106 //=============================================================================
4108 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4111 _preMeshInfo->FullLoadFromFile();
4113 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4114 if ( aSMESHDS_Mesh == NULL ) return false;
4115 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4116 if(!elem) return false;
4117 return elem->IsPoly();
4121 //=============================================================================
4123 * Returns true if given element is quadratic
4125 //=============================================================================
4127 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4130 _preMeshInfo->FullLoadFromFile();
4132 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4133 if ( aSMESHDS_Mesh == NULL ) return false;
4134 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4135 if(!elem) return false;
4136 return elem->IsQuadratic();
4139 //=============================================================================
4141 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4143 //=============================================================================
4145 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4148 _preMeshInfo->FullLoadFromFile();
4150 if ( const SMDS_BallElement* ball =
4151 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4152 return ball->GetDiameter();
4157 //=============================================================================
4159 * Returns bary center for given element
4161 //=============================================================================
4163 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4166 _preMeshInfo->FullLoadFromFile();
4168 SMESH::double_array_var aResult = new SMESH::double_array();
4169 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4170 if ( aSMESHDS_Mesh == NULL )
4171 return aResult._retn();
4173 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4175 return aResult._retn();
4177 if(elem->GetType()==SMDSAbs_Volume) {
4178 SMDS_VolumeTool aTool;
4179 if(aTool.Set(elem)) {
4181 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4186 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4188 double x=0., y=0., z=0.;
4189 for(; anIt->more(); ) {
4191 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4205 return aResult._retn();
4208 //================================================================================
4210 * \brief Create a group of elements preventing computation of a sub-shape
4212 //================================================================================
4214 SMESH::ListOfGroups*
4215 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4216 const char* theGroupName )
4217 throw ( SALOME::SALOME_Exception )
4219 Unexpect aCatch(SALOME_SalomeException);
4221 if ( !theGroupName || strlen( theGroupName) == 0 )
4222 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4224 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4226 // submesh by subshape id
4227 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4228 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4231 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4232 if ( error && !error->myBadElements.empty())
4234 // sort bad elements by type
4235 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4236 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4237 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4238 for ( ; elemIt != elemEnd; ++elemIt )
4240 const SMDS_MeshElement* elem = *elemIt;
4241 if ( !elem ) continue;
4243 if ( elem->GetID() < 1 )
4245 // elem is a temporary element, make a real element
4246 vector< const SMDS_MeshNode* > nodes;
4247 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4248 while ( nIt->more() && elem )
4250 nodes.push_back( nIt->next() );
4251 if ( nodes.back()->GetID() < 1 )
4252 elem = 0; // a temporary element on temporary nodes
4256 ::SMESH_MeshEditor editor( _impl );
4257 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4261 elemsByType[ elem->GetType() ].push_back( elem );
4264 // how many groups to create?
4266 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4267 nbTypes += int( !elemsByType[ i ].empty() );
4268 groups->length( nbTypes );
4271 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4273 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4274 if ( elems.empty() ) continue;
4276 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4277 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4279 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4280 SMESH::SMESH_Mesh_var mesh = _this();
4281 SALOMEDS::SObject_wrap aSO =
4282 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4283 GEOM::GEOM_Object::_nil(), theGroupName);
4284 aSO->_is_nil(); // avoid "unused variable" warning
4286 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4287 if ( !grp_i ) continue;
4289 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4290 for ( size_t iE = 0; iE < elems.size(); ++iE )
4291 grpDS->SMDSGroup().Add( elems[ iE ]);
4296 return groups._retn();
4299 //=============================================================================
4301 * Create and publish group servants if any groups were imported or created anyhow
4303 //=============================================================================
4305 void SMESH_Mesh_i::CreateGroupServants()
4307 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4308 SMESH::SMESH_Mesh_var aMesh = _this();
4311 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4312 while ( groupIt->more() )
4314 ::SMESH_Group* group = groupIt->next();
4315 int anId = group->GetGroupDS()->GetID();
4317 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4318 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4320 addedIDs.insert( anId );
4322 SMESH_GroupBase_i* aGroupImpl;
4324 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4325 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4327 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4328 shape = groupOnGeom->GetShape();
4331 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4334 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4335 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4336 aGroupImpl->Register();
4338 // register CORBA object for persistence
4339 int nextId = _gen_i->RegisterObject( groupVar );
4340 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4341 else { nextId = 0; } // avoid "unused variable" warning in release mode
4343 // publishing the groups in the study
4344 if ( !aStudy->_is_nil() ) {
4345 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4346 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4349 if ( !addedIDs.empty() )
4352 set<int>::iterator id = addedIDs.begin();
4353 for ( ; id != addedIDs.end(); ++id )
4355 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4356 int i = std::distance( _mapGroups.begin(), it );
4357 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4362 //=============================================================================
4364 * \brief Return groups cantained in _mapGroups by their IDs
4366 //=============================================================================
4368 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4370 int nbGroups = groupIDs.size();
4371 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4372 aList->length( nbGroups );
4374 list<int>::const_iterator ids = groupIDs.begin();
4375 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4377 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4378 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4379 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4381 aList->length( nbGroups );
4382 return aList._retn();
4385 //=============================================================================
4387 * \brief Return information about imported file
4389 //=============================================================================
4391 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4393 SMESH::MedFileInfo_var res( _medFileInfo );
4394 if ( !res.operator->() ) {
4395 res = new SMESH::MedFileInfo;
4397 res->fileSize = res->major = res->minor = res->release = -1;
4402 //=============================================================================
4404 * \brief Pass names of mesh groups from study to mesh DS
4406 //=============================================================================
4408 void SMESH_Mesh_i::checkGroupNames()
4410 int nbGrp = NbGroups();
4414 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4415 if ( aStudy->_is_nil() )
4416 return; // nothing to do
4418 SMESH::ListOfGroups* grpList = 0;
4419 // avoid dump of "GetGroups"
4421 // store python dump into a local variable inside local scope
4422 SMESH::TPythonDump pDump; // do not delete this line of code
4423 grpList = GetGroups();
4426 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4427 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4430 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4431 if ( aGrpSO->_is_nil() )
4433 // correct name of the mesh group if necessary
4434 const char* guiName = aGrpSO->GetName();
4435 if ( strcmp(guiName, aGrp->GetName()) )
4436 aGrp->SetName( guiName );
4440 //=============================================================================
4442 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4444 //=============================================================================
4445 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4447 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4451 //=============================================================================
4453 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4455 //=============================================================================
4457 char* SMESH_Mesh_i::GetParameters()
4459 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4462 //=============================================================================
4464 * \brief Returns list of notebook variables used for last Mesh operation
4466 //=============================================================================
4467 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4469 SMESH::string_array_var aResult = new SMESH::string_array();
4470 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4472 CORBA::String_var aParameters = GetParameters();
4473 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4474 if ( !aStudy->_is_nil()) {
4475 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4476 if(aSections->length() > 0) {
4477 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4478 aResult->length(aVars.length());
4479 for(int i = 0;i < aVars.length();i++)
4480 aResult[i] = CORBA::string_dup( aVars[i]);
4484 return aResult._retn();
4487 //=======================================================================
4488 //function : GetTypes
4489 //purpose : Returns types of elements it contains
4490 //=======================================================================
4492 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4495 return _preMeshInfo->GetTypes();
4497 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4501 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4502 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4503 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4504 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4505 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4506 types->length( nbTypes );
4508 return types._retn();
4511 //=======================================================================
4512 //function : GetMesh
4513 //purpose : Returns self
4514 //=======================================================================
4516 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4518 return SMESH::SMESH_Mesh::_duplicate( _this() );
4521 //=======================================================================
4522 //function : IsMeshInfoCorrect
4523 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4524 // * happen if mesh data is not yet fully loaded from the file of study.
4525 //=======================================================================
4527 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4529 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4532 //=============================================================================
4534 * \brief Returns number of mesh elements per each \a EntityType
4536 //=============================================================================
4538 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4541 return _preMeshInfo->GetMeshInfo();
4543 SMESH::long_array_var aRes = new SMESH::long_array();
4544 aRes->length(SMESH::Entity_Last);
4545 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4547 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4549 return aRes._retn();
4550 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4551 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4552 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4553 return aRes._retn();
4556 //=============================================================================
4558 * \brief Returns number of mesh elements per each \a ElementType
4560 //=============================================================================
4562 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
4564 SMESH::long_array_var aRes = new SMESH::long_array();
4565 aRes->length(SMESH::NB_ELEMENT_TYPES);
4566 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4569 const SMDS_MeshInfo* meshInfo = 0;
4571 meshInfo = _preMeshInfo;
4572 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
4573 meshInfo = & meshDS->GetMeshInfo();
4576 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
4577 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
4579 return aRes._retn();
4582 //=============================================================================
4584 * Collect statistic of mesh elements given by iterator
4586 //=============================================================================
4588 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4589 SMESH::long_array& theInfo)
4591 if (!theItr) return;
4592 while (theItr->more())
4593 theInfo[ theItr->next()->GetEntityType() ]++;
4596 //=============================================================================
4597 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
4598 * SMESH::ElementType type) */
4600 using namespace SMESH::Controls;
4601 //-----------------------------------------------------------------------------
4602 struct PredicateIterator : public SMDS_ElemIterator
4604 SMDS_ElemIteratorPtr _elemIter;
4605 PredicatePtr _predicate;
4606 const SMDS_MeshElement* _elem;
4608 PredicateIterator( SMDS_ElemIteratorPtr iterator,
4609 PredicatePtr predicate):
4610 _elemIter(iterator), _predicate(predicate)
4618 virtual const SMDS_MeshElement* next()
4620 const SMDS_MeshElement* res = _elem;
4622 while ( _elemIter->more() && !_elem )
4624 _elem = _elemIter->next();
4625 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
4632 //-----------------------------------------------------------------------------
4633 struct IDSourceIterator : public SMDS_ElemIterator
4635 const CORBA::Long* _idPtr;
4636 const CORBA::Long* _idEndPtr;
4637 SMESH::long_array_var _idArray;
4638 const SMDS_Mesh* _mesh;
4639 const SMDSAbs_ElementType _type;
4640 const SMDS_MeshElement* _elem;
4642 IDSourceIterator( const SMDS_Mesh* mesh,
4643 const CORBA::Long* ids,
4645 SMDSAbs_ElementType type):
4646 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
4648 if ( _idPtr && nbIds && _mesh )
4651 IDSourceIterator( const SMDS_Mesh* mesh,
4652 SMESH::long_array* idArray,
4653 SMDSAbs_ElementType type):
4654 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
4656 if ( idArray && _mesh )
4658 _idPtr = &_idArray[0];
4659 _idEndPtr = _idPtr + _idArray->length();
4667 virtual const SMDS_MeshElement* next()
4669 const SMDS_MeshElement* res = _elem;
4671 while ( _idPtr < _idEndPtr && !_elem )
4673 if ( _type == SMDSAbs_Node )
4675 _elem = _mesh->FindNode( *_idPtr++ );
4677 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
4678 _elem->GetType() != _type )
4686 //-----------------------------------------------------------------------------
4688 struct NodeOfElemIterator : public SMDS_ElemIterator
4690 TColStd_MapOfInteger _checkedNodeIDs;
4691 SMDS_ElemIteratorPtr _elemIter;
4692 SMDS_ElemIteratorPtr _nodeIter;
4693 const SMDS_MeshElement* _node;
4695 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
4697 if ( _elemIter && _elemIter->more() )
4699 _nodeIter = _elemIter->next()->nodesIterator();
4707 virtual const SMDS_MeshElement* next()
4709 const SMDS_MeshElement* res = _node;
4711 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
4713 if ( _nodeIter->more() )
4715 _node = _nodeIter->next();
4716 if ( !_checkedNodeIDs.Add( _node->GetID() ))
4721 _nodeIter = _elemIter->next()->nodesIterator();
4729 //=============================================================================
4731 * Return iterator on elements of given type in given object
4733 //=============================================================================
4735 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
4736 SMESH::ElementType theType)
4738 SMDS_ElemIteratorPtr elemIt;
4739 bool typeOK = false;
4740 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
4742 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
4743 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
4744 if ( !mesh_i ) return elemIt;
4745 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
4747 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
4749 elemIt = meshDS->elementsIterator( elemType );
4752 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
4754 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
4757 elemIt = sm->GetElements();
4758 if ( elemType != SMDSAbs_Node )
4760 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
4761 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
4765 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
4767 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
4768 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
4770 elemIt = groupDS->GetElements();
4771 typeOK = ( groupDS->GetType() == elemType );
4774 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
4776 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
4778 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
4779 if ( pred_i && pred_i->GetPredicate() )
4781 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
4782 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
4783 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
4784 typeOK = ( filterType == elemType );
4790 SMESH::array_of_ElementType_var types = theObject->GetTypes();
4791 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
4792 if ( isNodes && elemType != SMDSAbs_Node )
4794 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
4797 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
4798 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
4802 SMESH::long_array_var ids = theObject->GetIDs();
4803 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
4805 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
4808 if ( elemIt && elemIt->more() && !typeOK )
4810 if ( elemType == SMDSAbs_Node )
4812 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
4816 elemIt = SMDS_ElemIteratorPtr();
4822 //=============================================================================
4823 namespace // Finding concurrent hypotheses
4824 //=============================================================================
4828 * \brief mapping of mesh dimension into shape type
4830 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4832 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4834 case 0: aType = TopAbs_VERTEX; break;
4835 case 1: aType = TopAbs_EDGE; break;
4836 case 2: aType = TopAbs_FACE; break;
4838 default:aType = TopAbs_SOLID; break;
4843 //-----------------------------------------------------------------------------
4845 * \brief Internal structure used to find concurent submeshes
4847 * It represents a pair < submesh, concurent dimension >, where
4848 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4849 * with another submesh. In other words, it is dimension of a hypothesis assigned
4856 int _dim; //!< a dimension the algo can build (concurrent dimension)
4857 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4858 TopTools_MapOfShape _shapeMap;
4859 SMESH_subMesh* _subMesh;
4860 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4862 //-----------------------------------------------------------------------------
4863 // Return the algorithm
4864 const SMESH_Algo* GetAlgo() const
4865 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4867 //-----------------------------------------------------------------------------
4869 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4871 const TopoDS_Shape& theShape)
4873 _subMesh = (SMESH_subMesh*)theSubMesh;
4874 SetShape( theDim, theShape );
4877 //-----------------------------------------------------------------------------
4879 void SetShape(const int theDim,
4880 const TopoDS_Shape& theShape)
4883 _ownDim = SMESH_Gen::GetShapeDim(theShape);
4884 if (_dim >= _ownDim)
4885 _shapeMap.Add( theShape );
4887 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4888 for( ; anExp.More(); anExp.Next() )
4889 _shapeMap.Add( anExp.Current() );
4893 //-----------------------------------------------------------------------------
4894 //! Check sharing of sub-shapes
4895 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4896 const TopTools_MapOfShape& theToFind,
4897 const TopAbs_ShapeEnum theType)
4899 bool isShared = false;
4900 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4901 for (; !isShared && anItr.More(); anItr.Next() )
4903 const TopoDS_Shape aSubSh = anItr.Key();
4904 // check for case when concurrent dimensions are same
4905 isShared = theToFind.Contains( aSubSh );
4906 // check for sub-shape with concurrent dimension
4907 TopExp_Explorer anExp( aSubSh, theType );
4908 for ( ; !isShared && anExp.More(); anExp.Next() )
4909 isShared = theToFind.Contains( anExp.Current() );
4914 //-----------------------------------------------------------------------------
4915 //! check algorithms
4916 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4917 const SMESHDS_Hypothesis* theA2)
4919 if ( !theA1 || !theA2 ||
4920 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4921 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4922 return false; // one of the hypothesis is not algorithm
4923 // check algorithm names (should be equal)
4924 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4928 //-----------------------------------------------------------------------------
4929 //! Check if sub-shape hypotheses are concurrent
4930 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4932 if ( _subMesh == theOther->_subMesh )
4933 return false; // same sub-shape - should not be
4935 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4936 // any of the two submeshes is not on COMPOUND shape )
4937 // -> no concurrency
4938 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4939 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4940 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4941 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4942 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4945 // bool checkSubShape = ( _dim >= theOther->_dim )
4946 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4947 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4948 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4949 if ( !checkSubShape )
4952 // check algorithms to be same
4953 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4954 return true; // different algorithms -> concurrency !
4956 // check hypothesises for concurrence (skip first as algorithm)
4958 // pointers should be same, because it is referened from mesh hypothesis partition
4959 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4960 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4961 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4962 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4964 // the submeshes are concurrent if their algorithms has different parameters
4965 return nbSame != theOther->_hypotheses.size() - 1;
4968 // Return true if algorithm of this SMESH_DimHyp is used if no
4969 // sub-mesh order is imposed by the user
4970 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4972 // NeedDiscreteBoundary() algo has a higher priority
4973 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4974 theOther->GetAlgo()->NeedDiscreteBoundary() )
4975 return !this->GetAlgo()->NeedDiscreteBoundary();
4977 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4980 }; // end of SMESH_DimHyp
4981 //-----------------------------------------------------------------------------
4983 typedef list<const SMESH_DimHyp*> TDimHypList;
4985 //-----------------------------------------------------------------------------
4987 void addDimHypInstance(const int theDim,
4988 const TopoDS_Shape& theShape,
4989 const SMESH_Algo* theAlgo,
4990 const SMESH_subMesh* theSubMesh,
4991 const list <const SMESHDS_Hypothesis*>& theHypList,
4992 TDimHypList* theDimHypListArr )
4994 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4995 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4996 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4997 dimHyp->_hypotheses.push_front(theAlgo);
4998 listOfdimHyp.push_back( dimHyp );
5001 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5002 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5003 theHypList.begin(), theHypList.end() );
5006 //-----------------------------------------------------------------------------
5007 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5008 TDimHypList& theListOfConcurr)
5010 if ( theListOfConcurr.empty() )
5012 theListOfConcurr.push_back( theDimHyp );
5016 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5017 while ( hypIt != theListOfConcurr.end() &&
5018 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5020 theListOfConcurr.insert( hypIt, theDimHyp );
5024 //-----------------------------------------------------------------------------
5025 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5026 const TDimHypList& theListOfDimHyp,
5027 TDimHypList& theListOfConcurrHyp,
5028 set<int>& theSetOfConcurrId )
5030 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5031 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5033 const SMESH_DimHyp* curDimHyp = *rIt;
5034 if ( curDimHyp == theDimHyp )
5035 break; // meet own dimHyp pointer in same dimension
5037 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5038 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5040 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5045 //-----------------------------------------------------------------------------
5046 void unionLists(TListOfInt& theListOfId,
5047 TListOfListOfInt& theListOfListOfId,
5050 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5051 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5053 continue; //skip already treated lists
5054 // check if other list has any same submesh object
5055 TListOfInt& otherListOfId = *it;
5056 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5057 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5060 // union two lists (from source into target)
5061 TListOfInt::iterator it2 = otherListOfId.begin();
5062 for ( ; it2 != otherListOfId.end(); it2++ ) {
5063 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5064 theListOfId.push_back(*it2);
5066 // clear source list
5067 otherListOfId.clear();
5070 //-----------------------------------------------------------------------------
5072 //! free memory allocated for dimension-hypothesis objects
5073 void removeDimHyps( TDimHypList* theArrOfList )
5075 for (int i = 0; i < 4; i++ ) {
5076 TDimHypList& listOfdimHyp = theArrOfList[i];
5077 TDimHypList::const_iterator it = listOfdimHyp.begin();
5078 for ( ; it != listOfdimHyp.end(); it++ )
5083 //-----------------------------------------------------------------------------
5085 * \brief find common submeshes with given submesh
5086 * \param theSubMeshList list of already collected submesh to check
5087 * \param theSubMesh given submesh to intersect with other
5088 * \param theCommonSubMeshes collected common submeshes
5090 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5091 const SMESH_subMesh* theSubMesh,
5092 set<const SMESH_subMesh*>& theCommon )
5096 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5097 for ( ; it != theSubMeshList.end(); it++ )
5098 theSubMesh->FindIntersection( *it, theCommon );
5099 theSubMeshList.push_back( theSubMesh );
5100 //theCommon.insert( theSubMesh );
5105 //=============================================================================
5107 * \brief Return submesh objects list in meshing order
5109 //=============================================================================
5111 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5113 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5115 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5117 return aResult._retn();
5119 ::SMESH_Mesh& mesh = GetImpl();
5120 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
5121 if ( !anOrder.size() ) {
5123 // collect submeshes and detect concurrent algorithms and hypothesises
5124 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5126 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5127 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5128 ::SMESH_subMesh* sm = (*i_sm).second;
5130 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5132 // list of assigned hypothesises
5133 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5134 // Find out dimensions where the submesh can be concurrent.
5135 // We define the dimensions by algo of each of hypotheses in hypList
5136 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5137 for( ; hypIt != hypList.end(); hypIt++ ) {
5138 SMESH_Algo* anAlgo = 0;
5139 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5140 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5141 // hyp it-self is algo
5142 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5144 // try to find algorithm with help of sub-shapes
5145 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5146 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5147 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5150 continue; // no algorithm assigned to a current submesh
5152 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5153 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5155 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5156 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5157 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5159 } // end iterations on submesh
5161 // iterate on created dimension-hypotheses and check for concurrents
5162 for ( int i = 0; i < 4; i++ ) {
5163 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5164 // check for concurrents in own and other dimensions (step-by-step)
5165 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5166 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5167 const SMESH_DimHyp* dimHyp = *dhIt;
5168 TDimHypList listOfConcurr;
5169 set<int> setOfConcurrIds;
5170 // looking for concurrents and collect into own list
5171 for ( int j = i; j < 4; j++ )
5172 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5173 // check if any concurrents found
5174 if ( listOfConcurr.size() > 0 ) {
5175 // add own submesh to list of concurrent
5176 addInOrderOfPriority( dimHyp, listOfConcurr );
5177 list<int> listOfConcurrIds;
5178 TDimHypList::iterator hypIt = listOfConcurr.begin();
5179 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5180 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5181 anOrder.push_back( listOfConcurrIds );
5186 removeDimHyps(dimHypListArr);
5188 // now, minimise the number of concurrent groups
5189 // Here we assume that lists of submeshes can have same submesh
5190 // in case of multi-dimension algorithms, as result
5191 // list with common submesh has to be united into one list
5193 TListOfListOfInt::iterator listIt = anOrder.begin();
5194 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5195 unionLists( *listIt, anOrder, listIndx + 1 );
5197 // convert submesh ids into interface instances
5198 // and dump command into python
5199 convertMeshOrder( anOrder, aResult, false );
5201 return aResult._retn();
5204 //=============================================================================
5206 * \brief Set submesh object order
5207 * \param theSubMeshArray submesh array order
5209 //=============================================================================
5211 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5214 _preMeshInfo->ForgetOrLoad();
5217 ::SMESH_Mesh& mesh = GetImpl();
5219 TPythonDump aPythonDump; // prevent dump of called methods
5220 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5222 TListOfListOfInt subMeshOrder;
5223 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5225 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5226 TListOfInt subMeshIds;
5227 aPythonDump << "[ ";
5228 // Collect subMeshes which should be clear
5229 // do it list-by-list, because modification of submesh order
5230 // take effect between concurrent submeshes only
5231 set<const SMESH_subMesh*> subMeshToClear;
5232 list<const SMESH_subMesh*> subMeshList;
5233 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5235 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5237 aPythonDump << ", ";
5238 aPythonDump << subMesh;
5239 subMeshIds.push_back( subMesh->GetId() );
5240 // detect common parts of submeshes
5241 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5242 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5244 aPythonDump << " ]";
5245 subMeshOrder.push_back( subMeshIds );
5247 // clear collected submeshes
5248 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5249 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5250 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5251 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5253 aPythonDump << " ])";
5255 mesh.SetMeshOrder( subMeshOrder );
5261 //=============================================================================
5263 * \brief Convert submesh ids into submesh interfaces
5265 //=============================================================================
5267 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5268 SMESH::submesh_array_array& theResOrder,
5269 const bool theIsDump)
5271 int nbSet = theIdsOrder.size();
5272 TPythonDump aPythonDump; // prevent dump of called methods
5274 aPythonDump << "[ ";
5275 theResOrder.length(nbSet);
5276 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5278 for( ; it != theIdsOrder.end(); it++ ) {
5279 // translate submesh identificators into submesh objects
5280 // takeing into account real number of concurrent lists
5281 const TListOfInt& aSubOrder = (*it);
5282 if (!aSubOrder.size())
5285 aPythonDump << "[ ";
5286 // convert shape indeces into interfaces
5287 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5288 aResSubSet->length(aSubOrder.size());
5289 TListOfInt::const_iterator subIt = aSubOrder.begin();
5290 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
5291 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5293 SMESH::SMESH_subMesh_var subMesh =
5294 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5297 aPythonDump << ", ";
5298 aPythonDump << subMesh;
5300 aResSubSet[ j++ ] = subMesh;
5303 aPythonDump << " ]";
5304 theResOrder[ listIndx++ ] = aResSubSet;
5306 // correct number of lists
5307 theResOrder.length( listIndx );
5310 // finilise python dump
5311 aPythonDump << " ]";
5312 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5316 //================================================================================
5318 // Implementation of SMESH_MeshPartDS
5320 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5321 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5323 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5324 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5326 _meshDS = mesh_i->GetImpl().GetMeshDS();
5328 SetPersistentId( _meshDS->GetPersistentId() );
5330 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5332 // <meshPart> is the whole mesh
5333 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5335 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5336 myGroupSet = _meshDS->GetGroups();
5341 SMESH::long_array_var anIDs = meshPart->GetIDs();
5342 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5343 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5345 for (int i=0; i < anIDs->length(); i++)
5346 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5347 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5352 for (int i=0; i < anIDs->length(); i++)
5353 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5354 if ( _elements[ e->GetType() ].insert( e ).second )
5357 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5358 while ( nIt->more() )
5360 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5361 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5368 _meshDS = 0; // to enforce iteration on _elements and _nodes
5371 // -------------------------------------------------------------------------------------
5372 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5373 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5376 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5377 for ( ; partIt != meshPart.end(); ++partIt )
5378 if ( const SMDS_MeshElement * e = *partIt )
5379 if ( _elements[ e->GetType() ].insert( e ).second )
5382 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5383 while ( nIt->more() )
5385 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5386 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5392 // -------------------------------------------------------------------------------------
5393 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5395 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5397 typedef SMDS_SetIterator
5398 <const SMDS_MeshElement*,
5399 TIDSortedElemSet::const_iterator,
5400 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5401 SMDS_MeshElement::GeomFilter
5404 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5406 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5407 _elements[type].end(),
5408 SMDS_MeshElement::GeomFilter( geomType )));
5410 // -------------------------------------------------------------------------------------
5411 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5413 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5415 typedef SMDS_SetIterator
5416 <const SMDS_MeshElement*,
5417 TIDSortedElemSet::const_iterator,
5418 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5419 SMDS_MeshElement::EntityFilter
5422 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5424 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5425 _elements[type].end(),
5426 SMDS_MeshElement::EntityFilter( entity )));
5428 // -------------------------------------------------------------------------------------
5429 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5431 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5432 if ( type == SMDSAbs_All && !_meshDS )
5434 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5436 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5437 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5439 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5441 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5442 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5444 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5445 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5447 // -------------------------------------------------------------------------------------
5448 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5449 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5451 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5452 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5453 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5455 // -------------------------------------------------------------------------------------
5456 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5457 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5458 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5459 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5460 #undef _GET_ITER_DEFINE
5462 // END Implementation of SMESH_MeshPartDS
5464 //================================================================================