1 // Copyright (C) 2007-2015 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, or (at your option) any later version.
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_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cashed shapes if no more meshes remain; (the cash is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
236 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 if ( aShapeObj->_is_nil() )
239 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
240 // find GEOM_Object by entry (IPAL52735)
241 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
242 for ( ; data != _geomGroupData.end(); ++data )
243 if ( data->_smeshObject->_is_equivalent( _this() ))
245 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
246 if ( study->_is_nil() ) break;
247 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
248 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
249 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
255 catch(SALOME_Exception & S_ex) {
256 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
258 return aShapeObj._retn();
261 //================================================================================
263 * \brief Return false if the mesh is not yet fully loaded from the study file
265 //================================================================================
267 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
269 Unexpect aCatch(SALOME_SalomeException);
270 return !_preMeshInfo;
273 //================================================================================
275 * \brief Load full mesh data from the study file
277 //================================================================================
279 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
281 Unexpect aCatch(SALOME_SalomeException);
283 _preMeshInfo->FullLoadFromFile();
286 //================================================================================
288 * \brief Remove all nodes and elements
290 //================================================================================
292 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
294 Unexpect aCatch(SALOME_SalomeException);
296 _preMeshInfo->ForgetAllData();
300 //CheckGeomGroupModif(); // issue 20145
302 catch(SALOME_Exception & S_ex) {
303 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 _impl->GetMeshDS()->Modified();
307 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
310 //================================================================================
312 * \brief Remove all nodes and elements for indicated shape
314 //================================================================================
316 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
317 throw (SALOME::SALOME_Exception)
319 Unexpect aCatch(SALOME_SalomeException);
321 _preMeshInfo->FullLoadFromFile();
324 _impl->ClearSubMesh( ShapeID );
326 catch(SALOME_Exception & S_ex) {
327 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
329 _impl->GetMeshDS()->Modified();
331 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
334 //=============================================================================
336 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
338 //=============================================================================
340 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
342 SMESH::DriverMED_ReadStatus res;
345 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
346 res = SMESH::DRS_OK; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
348 res = SMESH::DRS_EMPTY; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
350 res = SMESH::DRS_WARN_RENUMBER; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
352 res = SMESH::DRS_WARN_SKIP_ELEM; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
354 res = SMESH::DRS_WARN_DESCENDING; break;
355 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
357 res = SMESH::DRS_FAIL; break;
362 //=============================================================================
364 * Convert ::SMESH_ComputeError to SMESH::ComputeError
366 //=============================================================================
368 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
370 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
371 errVar->subShapeID = -1;
372 errVar->hasBadMesh = false;
374 if ( !errorPtr || errorPtr->IsOK() )
376 errVar->code = SMESH::COMPERR_OK;
380 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
381 errVar->comment = errorPtr->myComment.c_str();
383 return errVar._retn();
386 //=============================================================================
390 * Imports mesh data from MED file
392 //=============================================================================
394 SMESH::DriverMED_ReadStatus
395 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
396 throw ( SALOME::SALOME_Exception )
398 Unexpect aCatch(SALOME_SalomeException);
401 status = _impl->MEDToMesh( theFileName, theMeshName );
403 catch( SALOME_Exception& S_ex ) {
404 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
407 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
410 CreateGroupServants();
412 int major, minor, release;
413 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
414 major = minor = release = -1;
415 _medFileInfo = new SMESH::MedFileInfo();
416 _medFileInfo->fileName = theFileName;
417 _medFileInfo->fileSize = 0;
418 _medFileInfo->major = major;
419 _medFileInfo->minor = minor;
420 _medFileInfo->release = release;
421 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
423 return ConvertDriverMEDReadStatus(status);
426 //================================================================================
428 * \brief Imports mesh data from the CGNS file
430 //================================================================================
432 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
433 const int theMeshIndex,
434 std::string& theMeshName )
435 throw ( SALOME::SALOME_Exception )
437 Unexpect aCatch(SALOME_SalomeException);
440 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
442 catch( SALOME_Exception& S_ex ) {
443 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
446 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
449 CreateGroupServants();
451 return ConvertDriverMEDReadStatus(status);
454 //================================================================================
456 * \brief Return string representation of a MED file version comprising nbDigits
458 //================================================================================
460 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
462 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
464 return CORBA::string_dup( ver.c_str() );
467 //=============================================================================
471 * Imports mesh data from MED file
473 //=============================================================================
475 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
476 throw ( SALOME::SALOME_Exception )
480 // Read mesh with name = <theMeshName> into SMESH_Mesh
481 _impl->UNVToMesh( theFileName );
483 CreateGroupServants();
485 SMESH_CATCH( SMESH::throwCorbaException );
490 //=============================================================================
494 * Imports mesh data from STL file
496 //=============================================================================
497 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
498 throw ( SALOME::SALOME_Exception )
502 // Read mesh with name = <theMeshName> into SMESH_Mesh
503 _impl->STLToMesh( theFileName );
505 SMESH_CATCH( SMESH::throwCorbaException );
510 //================================================================================
512 * \brief Function used in SMESH_CATCH by ImportGMFFile()
514 //================================================================================
518 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
520 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
524 //================================================================================
526 * \brief Imports data from a GMF file and returns an error description
528 //================================================================================
530 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
531 bool theMakeRequiredGroups )
532 throw (SALOME::SALOME_Exception)
534 SMESH_ComputeErrorPtr error;
537 #define SMESH_CAUGHT error =
540 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
542 SMESH_CATCH( exceptionToComputeError );
546 CreateGroupServants();
548 return ConvertComputeError( error );
551 //=============================================================================
555 //=============================================================================
557 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
559 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
560 (SMESH_Hypothesis::Hypothesis_Status theStatus)
563 RETURNCASE( HYP_OK );
564 RETURNCASE( HYP_MISSING );
565 RETURNCASE( HYP_CONCURENT );
566 RETURNCASE( HYP_BAD_PARAMETER );
567 RETURNCASE( HYP_HIDDEN_ALGO );
568 RETURNCASE( HYP_HIDING_ALGO );
569 RETURNCASE( HYP_UNKNOWN_FATAL );
570 RETURNCASE( HYP_INCOMPATIBLE );
571 RETURNCASE( HYP_NOTCONFORM );
572 RETURNCASE( HYP_ALREADY_EXIST );
573 RETURNCASE( HYP_BAD_DIM );
574 RETURNCASE( HYP_BAD_SUBSHAPE );
575 RETURNCASE( HYP_BAD_GEOMETRY );
576 RETURNCASE( HYP_NEED_SHAPE );
577 RETURNCASE( HYP_INCOMPAT_HYPS );
580 return SMESH::HYP_UNKNOWN_FATAL;
583 //=============================================================================
587 * calls internal addHypothesis() and then adds a reference to <anHyp> under
588 * the SObject actually having a reference to <aSubShape>.
589 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
591 //=============================================================================
593 SMESH::Hypothesis_Status
594 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
595 SMESH::SMESH_Hypothesis_ptr anHyp,
596 CORBA::String_out anErrorText)
597 throw(SALOME::SALOME_Exception)
599 Unexpect aCatch(SALOME_SalomeException);
601 _preMeshInfo->ForgetOrLoad();
604 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
605 anErrorText = error.c_str();
607 SMESH::SMESH_Mesh_var mesh( _this() );
608 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
610 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
611 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
613 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
615 // Update Python script
616 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
617 << aSubShape << ", " << anHyp << " )";
619 return ConvertHypothesisStatus(status);
622 //=============================================================================
626 //=============================================================================
628 SMESH_Hypothesis::Hypothesis_Status
629 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
630 SMESH::SMESH_Hypothesis_ptr anHyp,
631 std::string* anErrorText)
633 if(MYDEBUG) MESSAGE("addHypothesis");
635 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
636 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
638 if (CORBA::is_nil( anHyp ))
639 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
641 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
644 TopoDS_Shape myLocSubShape;
645 //use PseudoShape in case if mesh has no shape
647 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
649 myLocSubShape = _impl->GetShapeToMesh();
651 const int hypId = anHyp->GetId();
653 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
654 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
656 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
658 // assure there is a corresponding submesh
659 if ( !_impl->IsMainShape( myLocSubShape )) {
660 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
661 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
662 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
665 else if ( anErrorText )
667 *anErrorText = error;
670 catch(SALOME_Exception & S_ex)
672 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
677 //=============================================================================
681 //=============================================================================
683 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
684 SMESH::SMESH_Hypothesis_ptr anHyp)
685 throw(SALOME::SALOME_Exception)
687 Unexpect aCatch(SALOME_SalomeException);
689 _preMeshInfo->ForgetOrLoad();
691 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
692 SMESH::SMESH_Mesh_var mesh = _this();
694 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
696 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
697 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
699 // Update Python script
700 if(_impl->HasShapeToMesh())
701 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
702 << aSubShape << ", " << anHyp << " )";
704 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
707 return ConvertHypothesisStatus(status);
710 //=============================================================================
714 //=============================================================================
716 SMESH_Hypothesis::Hypothesis_Status
717 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
718 SMESH::SMESH_Hypothesis_ptr anHyp)
720 if(MYDEBUG) MESSAGE("removeHypothesis()");
722 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
723 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
725 if (CORBA::is_nil( anHyp ))
726 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
728 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
731 TopoDS_Shape myLocSubShape;
732 //use PseudoShape in case if mesh has no shape
733 if( _impl->HasShapeToMesh() )
734 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
736 myLocSubShape = _impl->GetShapeToMesh();
738 const int hypId = anHyp->GetId();
739 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
740 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
742 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
746 catch(SALOME_Exception & S_ex)
748 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
753 //=============================================================================
757 //=============================================================================
759 SMESH::ListOfHypothesis *
760 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
761 throw(SALOME::SALOME_Exception)
763 Unexpect aCatch(SALOME_SalomeException);
764 if (MYDEBUG) MESSAGE("GetHypothesisList");
765 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
766 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
768 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
771 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
772 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
773 myLocSubShape = _impl->GetShapeToMesh();
774 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
775 int i = 0, n = aLocalList.size();
778 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
779 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
780 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
782 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
783 if ( id_hypptr != _mapHypo.end() )
784 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
788 catch(SALOME_Exception & S_ex) {
789 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
792 return aList._retn();
795 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
797 Unexpect aCatch(SALOME_SalomeException);
798 if (MYDEBUG) MESSAGE("GetSubMeshes");
800 SMESH::submesh_array_var aList = new SMESH::submesh_array();
803 TPythonDump aPythonDump;
804 if ( !_mapSubMeshIor.empty() )
808 aList->length( _mapSubMeshIor.size() );
810 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
811 for ( ; it != _mapSubMeshIor.end(); it++ ) {
812 if ( CORBA::is_nil( it->second )) continue;
813 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
815 if (i > 1) aPythonDump << ", ";
816 aPythonDump << it->second;
820 catch(SALOME_Exception & S_ex) {
821 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
824 // Update Python script
825 if ( !_mapSubMeshIor.empty() )
826 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
828 return aList._retn();
831 //=============================================================================
835 //=============================================================================
837 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
838 const char* theName )
839 throw(SALOME::SALOME_Exception)
841 Unexpect aCatch(SALOME_SalomeException);
842 if (CORBA::is_nil(aSubShape))
843 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
845 SMESH::SMESH_subMesh_var subMesh;
846 SMESH::SMESH_Mesh_var aMesh = _this();
848 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
850 //Get or Create the SMESH_subMesh object implementation
852 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
854 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
856 TopoDS_Iterator it( myLocSubShape );
858 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
860 subMesh = getSubMesh( subMeshId );
862 // create a new subMesh object servant if there is none for the shape
863 if ( subMesh->_is_nil() )
864 subMesh = createSubMesh( aSubShape );
865 if ( _gen_i->CanPublishInStudy( subMesh ))
867 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
868 SALOMEDS::SObject_wrap aSO =
869 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
870 if ( !aSO->_is_nil()) {
871 // Update Python script
872 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
873 << aSubShape << ", '" << theName << "' )";
877 catch(SALOME_Exception & S_ex) {
878 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
880 return subMesh._retn();
883 //=============================================================================
887 //=============================================================================
889 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
890 throw (SALOME::SALOME_Exception)
894 if ( theSubMesh->_is_nil() )
897 GEOM::GEOM_Object_var aSubShape;
898 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
899 if ( !aStudy->_is_nil() ) {
900 // Remove submesh's SObject
901 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
902 if ( !anSO->_is_nil() ) {
903 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
904 SALOMEDS::SObject_wrap anObj, aRef;
905 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
906 anObj->ReferencedObject( aRef.inout() ))
908 CORBA::Object_var obj = aRef->GetObject();
909 aSubShape = GEOM::GEOM_Object::_narrow( obj );
911 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
912 // aSubShape = theSubMesh->GetSubShape();
914 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
915 builder->RemoveObjectWithChildren( anSO );
917 // Update Python script
918 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
922 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
924 _preMeshInfo->ForgetOrLoad();
926 SMESH_CATCH( SMESH::throwCorbaException );
929 //=============================================================================
933 //=============================================================================
935 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
936 const char* theName )
937 throw(SALOME::SALOME_Exception)
939 Unexpect aCatch(SALOME_SalomeException);
941 _preMeshInfo->FullLoadFromFile();
943 SMESH::SMESH_Group_var aNewGroup =
944 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
946 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
948 SMESH::SMESH_Mesh_var mesh = _this();
949 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
950 SALOMEDS::SObject_wrap aSO =
951 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
952 if ( !aSO->_is_nil())
953 // Update Python script
954 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
955 << theElemType << ", '" << theName << "' )";
957 return aNewGroup._retn();
960 //=============================================================================
964 //=============================================================================
965 SMESH::SMESH_GroupOnGeom_ptr
966 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
968 GEOM::GEOM_Object_ptr theGeomObj)
969 throw(SALOME::SALOME_Exception)
971 Unexpect aCatch(SALOME_SalomeException);
973 _preMeshInfo->FullLoadFromFile();
975 SMESH::SMESH_GroupOnGeom_var aNewGroup;
977 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
978 if ( !aShape.IsNull() )
981 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
983 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
985 SMESH::SMESH_Mesh_var mesh = _this();
986 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
987 SALOMEDS::SObject_wrap aSO =
988 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
989 if ( !aSO->_is_nil())
990 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
991 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
995 return aNewGroup._retn();
998 //================================================================================
1000 * \brief Creates a group whose contents is defined by filter
1001 * \param theElemType - group type
1002 * \param theName - group name
1003 * \param theFilter - the filter
1004 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1006 //================================================================================
1008 SMESH::SMESH_GroupOnFilter_ptr
1009 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1010 const char* theName,
1011 SMESH::Filter_ptr theFilter )
1012 throw (SALOME::SALOME_Exception)
1014 Unexpect aCatch(SALOME_SalomeException);
1016 _preMeshInfo->FullLoadFromFile();
1018 if ( CORBA::is_nil( theFilter ))
1019 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1021 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1023 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1025 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1026 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1029 if ( !aNewGroup->_is_nil() )
1030 aNewGroup->SetFilter( theFilter );
1032 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1034 SMESH::SMESH_Mesh_var mesh = _this();
1035 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1036 SALOMEDS::SObject_wrap aSO =
1037 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1039 if ( !aSO->_is_nil())
1040 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1041 << theElemType << ", '" << theName << "', " << theFilter << " )";
1043 return aNewGroup._retn();
1046 //=============================================================================
1050 //=============================================================================
1052 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1053 throw (SALOME::SALOME_Exception)
1055 if ( theGroup->_is_nil() )
1060 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1064 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1065 if ( !aStudy->_is_nil() )
1067 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1068 if ( !aGroupSO->_is_nil() )
1070 // Update Python script
1071 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1073 // Remove group's SObject
1074 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1075 builder->RemoveObjectWithChildren( aGroupSO );
1078 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1080 // Remove the group from SMESH data structures
1081 removeGroup( aGroup->GetLocalID() );
1083 SMESH_CATCH( SMESH::throwCorbaException );
1086 //=============================================================================
1088 * Remove group with its contents
1090 //=============================================================================
1092 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1093 throw (SALOME::SALOME_Exception)
1097 _preMeshInfo->FullLoadFromFile();
1099 if ( theGroup->_is_nil() )
1102 vector<int> nodeIds; // to remove nodes becoming free
1103 if ( !theGroup->IsEmpty() )
1105 CORBA::Long elemID = theGroup->GetID( 1 );
1106 int nbElemNodes = GetElemNbNodes( elemID );
1107 if ( nbElemNodes > 0 )
1108 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1112 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1113 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1114 while ( elemIt->more() )
1116 const SMDS_MeshElement* e = elemIt->next();
1118 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1119 while ( nIt->more() )
1120 nodeIds.push_back( nIt->next()->GetID() );
1122 _impl->GetMeshDS()->RemoveElement( e );
1125 // Remove free nodes
1126 if ( theGroup->GetType() != SMESH::NODE )
1127 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1128 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1129 if ( n->NbInverseElements() == 0 )
1130 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1132 TPythonDump pyDump; // Supress dump from RemoveGroup()
1134 // Update Python script (theGroup must be alive for this)
1135 pyDump << SMESH::SMESH_Mesh_var(_this())
1136 << ".RemoveGroupWithContents( " << theGroup << " )";
1139 RemoveGroup( theGroup );
1141 SMESH_CATCH( SMESH::throwCorbaException );
1144 //================================================================================
1146 * \brief Get the list of groups existing in the mesh
1147 * \retval SMESH::ListOfGroups * - list of groups
1149 //================================================================================
1151 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1153 Unexpect aCatch(SALOME_SalomeException);
1154 if (MYDEBUG) MESSAGE("GetGroups");
1156 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1159 TPythonDump aPythonDump;
1160 if ( !_mapGroups.empty() )
1162 aPythonDump << "[ ";
1164 aList->length( _mapGroups.size() );
1166 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1167 for ( ; it != _mapGroups.end(); it++ ) {
1168 if ( CORBA::is_nil( it->second )) continue;
1169 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1171 if (i > 1) aPythonDump << ", ";
1172 aPythonDump << it->second;
1176 catch(SALOME_Exception & S_ex) {
1177 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1179 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1181 return aList._retn();
1184 //=============================================================================
1186 * Get number of groups existing in the mesh
1188 //=============================================================================
1190 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1192 Unexpect aCatch(SALOME_SalomeException);
1193 return _mapGroups.size();
1196 //=============================================================================
1198 * New group including all mesh elements present in initial groups is created.
1200 //=============================================================================
1202 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1203 SMESH::SMESH_GroupBase_ptr theGroup2,
1204 const char* theName )
1205 throw (SALOME::SALOME_Exception)
1207 SMESH::SMESH_Group_var aResGrp;
1211 _preMeshInfo->FullLoadFromFile();
1213 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1214 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1216 if ( theGroup1->GetType() != theGroup2->GetType() )
1217 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1222 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1223 if ( aResGrp->_is_nil() )
1224 return SMESH::SMESH_Group::_nil();
1226 aResGrp->AddFrom( theGroup1 );
1227 aResGrp->AddFrom( theGroup2 );
1229 // Update Python script
1230 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1231 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1233 SMESH_CATCH( SMESH::throwCorbaException );
1235 return aResGrp._retn();
1238 //=============================================================================
1240 * \brief New group including all mesh elements present in initial groups is created.
1241 * \param theGroups list of groups
1242 * \param theName name of group to be created
1243 * \return pointer to the new group
1245 //=============================================================================
1247 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1248 const char* theName )
1249 throw (SALOME::SALOME_Exception)
1251 SMESH::SMESH_Group_var aResGrp;
1254 _preMeshInfo->FullLoadFromFile();
1257 return SMESH::SMESH_Group::_nil();
1262 SMESH::ElementType aType = SMESH::ALL;
1263 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1265 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1266 if ( CORBA::is_nil( aGrp ) )
1268 if ( aType == SMESH::ALL )
1269 aType = aGrp->GetType();
1270 else if ( aType != aGrp->GetType() )
1271 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1274 if ( aType == SMESH::ALL )
1275 return SMESH::SMESH_Group::_nil();
1280 aResGrp = CreateGroup( aType, theName );
1281 if ( aResGrp->_is_nil() )
1282 return SMESH::SMESH_Group::_nil();
1284 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1285 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1287 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1288 if ( !CORBA::is_nil( aGrp ) )
1290 aResGrp->AddFrom( aGrp );
1291 if ( g > 0 ) pyDump << ", ";
1295 pyDump << " ], '" << theName << "' )";
1297 SMESH_CATCH( SMESH::throwCorbaException );
1299 return aResGrp._retn();
1302 //=============================================================================
1304 * New group is created. All mesh elements that are
1305 * present in both initial groups are added to the new one.
1307 //=============================================================================
1309 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1310 SMESH::SMESH_GroupBase_ptr theGroup2,
1311 const char* theName )
1312 throw (SALOME::SALOME_Exception)
1314 SMESH::SMESH_Group_var aResGrp;
1319 _preMeshInfo->FullLoadFromFile();
1321 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1322 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1324 if ( theGroup1->GetType() != theGroup2->GetType() )
1325 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1329 // Create Intersection
1330 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1331 if ( aResGrp->_is_nil() )
1332 return aResGrp._retn();
1334 SMESHDS_GroupBase* groupDS1 = 0;
1335 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1336 groupDS1 = grp_i->GetGroupDS();
1338 SMESHDS_GroupBase* groupDS2 = 0;
1339 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1340 groupDS2 = grp_i->GetGroupDS();
1342 SMESHDS_Group* resGroupDS = 0;
1343 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1344 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1346 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1348 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1349 while ( elemIt1->more() )
1351 const SMDS_MeshElement* e = elemIt1->next();
1352 if ( groupDS2->Contains( e ))
1353 resGroupDS->SMDSGroup().Add( e );
1356 // Update Python script
1357 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1358 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1360 SMESH_CATCH( SMESH::throwCorbaException );
1362 return aResGrp._retn();
1365 //=============================================================================
1367 \brief Intersect list of groups. New group is created. All mesh elements that
1368 are present in all initial groups simultaneously are added to the new one.
1369 \param theGroups list of groups
1370 \param theName name of group to be created
1371 \return pointer on the group
1373 //=============================================================================
1374 SMESH::SMESH_Group_ptr
1375 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1376 const char* theName )
1377 throw (SALOME::SALOME_Exception)
1379 SMESH::SMESH_Group_var aResGrp;
1384 _preMeshInfo->FullLoadFromFile();
1387 return SMESH::SMESH_Group::_nil();
1389 // check types and get SMESHDS_GroupBase's
1390 SMESH::ElementType aType = SMESH::ALL;
1391 vector< SMESHDS_GroupBase* > groupVec;
1392 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1394 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1395 if ( CORBA::is_nil( aGrp ) )
1397 if ( aType == SMESH::ALL )
1398 aType = aGrp->GetType();
1399 else if ( aType != aGrp->GetType() )
1400 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1403 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1404 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1406 if ( grpDS->IsEmpty() )
1411 groupVec.push_back( grpDS );
1414 if ( aType == SMESH::ALL ) // all groups are nil
1415 return SMESH::SMESH_Group::_nil();
1420 aResGrp = CreateGroup( aType, theName );
1422 SMESHDS_Group* resGroupDS = 0;
1423 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1424 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1425 if ( !resGroupDS || groupVec.empty() )
1426 return aResGrp._retn();
1429 size_t i, nb = groupVec.size();
1430 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1431 while ( elemIt1->more() )
1433 const SMDS_MeshElement* e = elemIt1->next();
1435 for ( i = 1; ( i < nb && inAll ); ++i )
1436 inAll = groupVec[i]->Contains( e );
1439 resGroupDS->SMDSGroup().Add( e );
1442 // Update Python script
1443 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1444 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1446 SMESH_CATCH( SMESH::throwCorbaException );
1448 return aResGrp._retn();
1451 //=============================================================================
1453 * New group is created. All mesh elements that are present in
1454 * a main group but is not present in a tool group are added to the new one
1456 //=============================================================================
1458 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1459 SMESH::SMESH_GroupBase_ptr theGroup2,
1460 const char* theName )
1461 throw (SALOME::SALOME_Exception)
1463 SMESH::SMESH_Group_var aResGrp;
1468 _preMeshInfo->FullLoadFromFile();
1470 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1471 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1473 if ( theGroup1->GetType() != theGroup2->GetType() )
1474 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1478 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1479 if ( aResGrp->_is_nil() )
1480 return aResGrp._retn();
1482 SMESHDS_GroupBase* groupDS1 = 0;
1483 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1484 groupDS1 = grp_i->GetGroupDS();
1486 SMESHDS_GroupBase* groupDS2 = 0;
1487 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1488 groupDS2 = grp_i->GetGroupDS();
1490 SMESHDS_Group* resGroupDS = 0;
1491 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1492 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1494 if ( groupDS1 && groupDS2 && resGroupDS )
1496 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1497 while ( elemIt1->more() )
1499 const SMDS_MeshElement* e = elemIt1->next();
1500 if ( !groupDS2->Contains( e ))
1501 resGroupDS->SMDSGroup().Add( e );
1504 // Update Python script
1505 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1506 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1508 SMESH_CATCH( SMESH::throwCorbaException );
1510 return aResGrp._retn();
1513 //=============================================================================
1515 \brief Cut lists of groups. New group is created. All mesh elements that are
1516 present in main groups but do not present in tool groups are added to the new one
1517 \param theMainGroups list of main groups
1518 \param theToolGroups list of tool groups
1519 \param theName name of group to be created
1520 \return pointer on the group
1522 //=============================================================================
1523 SMESH::SMESH_Group_ptr
1524 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1525 const SMESH::ListOfGroups& theToolGroups,
1526 const char* theName )
1527 throw (SALOME::SALOME_Exception)
1529 SMESH::SMESH_Group_var aResGrp;
1534 _preMeshInfo->FullLoadFromFile();
1537 return SMESH::SMESH_Group::_nil();
1539 // check types and get SMESHDS_GroupBase's
1540 SMESH::ElementType aType = SMESH::ALL;
1541 vector< SMESHDS_GroupBase* > toolGroupVec;
1542 vector< SMDS_ElemIteratorPtr > mainIterVec;
1544 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1546 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1547 if ( CORBA::is_nil( aGrp ) )
1549 if ( aType == SMESH::ALL )
1550 aType = aGrp->GetType();
1551 else if ( aType != aGrp->GetType() )
1552 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1554 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1555 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1556 if ( !grpDS->IsEmpty() )
1557 mainIterVec.push_back( grpDS->GetElements() );
1559 if ( aType == SMESH::ALL ) // all main groups are nil
1560 return SMESH::SMESH_Group::_nil();
1561 if ( mainIterVec.empty() ) // all main groups are empty
1562 return aResGrp._retn();
1564 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1566 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1567 if ( CORBA::is_nil( aGrp ) )
1569 if ( aType != aGrp->GetType() )
1570 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1572 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1573 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1574 toolGroupVec.push_back( grpDS );
1580 aResGrp = CreateGroup( aType, theName );
1582 SMESHDS_Group* resGroupDS = 0;
1583 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1584 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1586 return aResGrp._retn();
1589 size_t i, nb = toolGroupVec.size();
1590 SMDS_ElemIteratorPtr mainElemIt
1591 ( new SMDS_IteratorOnIterators
1592 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1593 while ( mainElemIt->more() )
1595 const SMDS_MeshElement* e = mainElemIt->next();
1597 for ( i = 0; ( i < nb && !isIn ); ++i )
1598 isIn = toolGroupVec[i]->Contains( e );
1601 resGroupDS->SMDSGroup().Add( e );
1604 // Update Python script
1605 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1606 << ".CutListOfGroups( " << theMainGroups << ", "
1607 << theToolGroups << ", '" << theName << "' )";
1609 SMESH_CATCH( SMESH::throwCorbaException );
1611 return aResGrp._retn();
1614 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1616 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1617 bool & toStopChecking )
1619 toStopChecking = ( nbCommon < nbChecked );
1620 return nbCommon == nbNodes;
1622 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1623 bool & toStopChecking )
1625 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1626 return nbCommon == nbCorners;
1628 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1629 bool & toStopChecking )
1631 return nbCommon > 0;
1633 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1634 bool & toStopChecking )
1636 return nbCommon >= (nbNodes+1) / 2;
1640 //=============================================================================
1642 * Create a group of entities basing on nodes of other groups.
1643 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1644 * \param [in] anElemType - a type of elements to include to the new group.
1645 * \param [in] theName - a name of the new group.
1646 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1647 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1648 * new group provided that it is based on nodes of an element of \a aListOfGroups
1649 * \return SMESH_Group - the created group
1651 // IMP 19939, bug 22010, IMP 22635
1652 //=============================================================================
1654 SMESH::SMESH_Group_ptr
1655 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1656 SMESH::ElementType theElemType,
1657 const char* theName,
1658 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1659 CORBA::Boolean theUnderlyingOnly)
1660 throw (SALOME::SALOME_Exception)
1662 SMESH::SMESH_Group_var aResGrp;
1666 _preMeshInfo->FullLoadFromFile();
1668 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1670 if ( !theName || !aMeshDS )
1671 return SMESH::SMESH_Group::_nil();
1673 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1675 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1676 SMESH_Comment nbCoNoStr( "SMESH.");
1677 switch ( theNbCommonNodes ) {
1678 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1679 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1680 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1681 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1682 default: return aResGrp._retn();
1684 int nbChecked, nbCommon, nbNodes, nbCorners;
1690 aResGrp = CreateGroup( theElemType, theName );
1691 if ( aResGrp->_is_nil() )
1692 return SMESH::SMESH_Group::_nil();
1694 SMESHDS_GroupBase* groupBaseDS =
1695 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1696 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1698 vector<bool> isNodeInGroups;
1700 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1702 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1703 if ( CORBA::is_nil( aGrp ) )
1705 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1706 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1709 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1710 if ( !elIt ) continue;
1712 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1714 while ( elIt->more() ) {
1715 const SMDS_MeshElement* el = elIt->next();
1716 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1717 while ( nIt->more() )
1718 resGroupCore.Add( nIt->next() );
1721 // get elements of theElemType based on nodes of every element of group
1722 else if ( theUnderlyingOnly )
1724 while ( elIt->more() )
1726 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1727 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1728 TIDSortedElemSet checkedElems;
1729 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1730 while ( nIt->more() )
1732 const SMDS_MeshNode* n = nIt->next();
1733 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1734 // check nodes of elements of theElemType around el
1735 while ( elOfTypeIt->more() )
1737 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1738 if ( !checkedElems.insert( elOfType ).second ) continue;
1739 nbNodes = elOfType->NbNodes();
1740 nbCorners = elOfType->NbCornerNodes();
1742 bool toStopChecking = false;
1743 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1744 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1745 if ( elNodes.count( nIt2->next() ) &&
1746 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1748 resGroupCore.Add( elOfType );
1755 // get all nodes of elements of groups
1758 while ( elIt->more() )
1760 const SMDS_MeshElement* el = elIt->next(); // an element of group
1761 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1762 while ( nIt->more() )
1764 const SMDS_MeshNode* n = nIt->next();
1765 if ( n->GetID() >= isNodeInGroups.size() )
1766 isNodeInGroups.resize( n->GetID() + 1, false );
1767 isNodeInGroups[ n->GetID() ] = true;
1773 // Get elements of theElemType based on a certain number of nodes of elements of groups
1774 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1776 const SMDS_MeshNode* n;
1777 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1778 const int isNodeInGroupsSize = isNodeInGroups.size();
1779 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1781 if ( !isNodeInGroups[ iN ] ||
1782 !( n = aMeshDS->FindNode( iN )))
1785 // check nodes of elements of theElemType around n
1786 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1787 while ( elOfTypeIt->more() )
1789 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1790 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1795 nbNodes = elOfType->NbNodes();
1796 nbCorners = elOfType->NbCornerNodes();
1798 bool toStopChecking = false;
1799 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1800 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1802 const int nID = nIt->next()->GetID();
1803 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1804 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1806 resGroupCore.Add( elOfType );
1814 // Update Python script
1815 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1816 << ".CreateDimGroup( "
1817 << theGroups << ", " << theElemType << ", '" << theName << "', "
1818 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1820 SMESH_CATCH( SMESH::throwCorbaException );
1822 return aResGrp._retn();
1825 //================================================================================
1827 * \brief Remember GEOM group data
1829 //================================================================================
1831 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1832 CORBA::Object_ptr theSmeshObj)
1834 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1837 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1838 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1839 if ( groupSO->_is_nil() )
1842 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1843 GEOM::GEOM_IGroupOperations_wrap groupOp =
1844 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1845 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1848 _geomGroupData.push_back( TGeomGroupData() );
1849 TGeomGroupData & groupData = _geomGroupData.back();
1851 CORBA::String_var entry = groupSO->GetID();
1852 groupData._groupEntry = entry.in();
1854 for ( int i = 0; i < ids->length(); ++i )
1855 groupData._indices.insert( ids[i] );
1857 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1858 // shape index in SMESHDS
1859 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1860 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1863 //================================================================================
1865 * Remove GEOM group data relating to removed smesh object
1867 //================================================================================
1869 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1871 list<TGeomGroupData>::iterator
1872 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1873 for ( ; data != dataEnd; ++data ) {
1874 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1875 _geomGroupData.erase( data );
1881 //================================================================================
1883 * \brief Return new group contents if it has been changed and update group data
1885 //================================================================================
1887 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1889 TopoDS_Shape newShape;
1892 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1893 if ( study->_is_nil() ) return newShape; // means "not changed"
1894 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1895 if ( !groupSO->_is_nil() )
1897 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1898 if ( CORBA::is_nil( groupObj )) return newShape;
1899 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1901 // get indices of group items
1902 set<int> curIndices;
1903 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1904 GEOM::GEOM_IGroupOperations_wrap groupOp =
1905 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1906 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1907 for ( int i = 0; i < ids->length(); ++i )
1908 curIndices.insert( ids[i] );
1910 if ( groupData._indices == curIndices )
1911 return newShape; // group not changed
1914 groupData._indices = curIndices;
1916 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1917 if ( !geomClient ) return newShape;
1918 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1919 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1920 newShape = _gen_i->GeomObjectToShape( geomGroup );
1923 if ( newShape.IsNull() ) {
1924 // geom group becomes empty - return empty compound
1925 TopoDS_Compound compound;
1926 BRep_Builder().MakeCompound(compound);
1927 newShape = compound;
1934 //-----------------------------------------------------------------------------
1936 * \brief Storage of shape and index used in CheckGeomGroupModif()
1938 struct TIndexedShape
1941 TopoDS_Shape _shape;
1942 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1944 //-----------------------------------------------------------------------------
1946 * \brief Data to re-create a group on geometry
1948 struct TGroupOnGeomData
1952 SMDSAbs_ElementType _type;
1954 Quantity_Color _color;
1958 //=============================================================================
1960 * \brief Update data if geometry changes
1964 //=============================================================================
1966 void SMESH_Mesh_i::CheckGeomModif()
1968 if ( !_impl->HasShapeToMesh() ) return;
1970 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1971 if ( study->_is_nil() ) return;
1973 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1974 //if ( mainGO->_is_nil() ) return;
1976 // Update after group modification
1978 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1979 called by other mesh (IPAL52735) */
1980 mainGO->GetType() == GEOM_GROUP ||
1981 mainGO->GetTick() == _mainShapeTick )
1983 CheckGeomGroupModif();
1987 // Update after shape transformation like Translate
1989 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1990 if ( !geomClient ) return;
1991 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1992 if ( geomGen->_is_nil() ) return;
1994 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1995 geomClient->RemoveShapeFromBuffer( ior.in() );
1997 // Update data taking into account that
1998 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2001 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2002 if ( newShape.IsNull() )
2005 _mainShapeTick = mainGO->GetTick();
2007 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2009 // store data of groups on geometry
2010 vector< TGroupOnGeomData > groupsData;
2011 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2012 groupsData.reserve( groups.size() );
2013 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2014 for ( ; g != groups.end(); ++g )
2015 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2017 TGroupOnGeomData data;
2018 data._oldID = group->GetID();
2019 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2020 data._type = group->GetType();
2021 data._name = group->GetStoreName();
2022 data._color = group->GetColor();
2023 groupsData.push_back( data );
2025 // store assigned hypotheses
2026 vector< pair< int, THypList > > ids2Hyps;
2027 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2028 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2030 const TopoDS_Shape& s = s2hyps.Key();
2031 const THypList& hyps = s2hyps.ChangeValue();
2032 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2035 // change shape to mesh
2036 int oldNbSubShapes = meshDS->MaxShapeIndex();
2037 _impl->ShapeToMesh( TopoDS_Shape() );
2038 _impl->ShapeToMesh( newShape );
2040 // re-add shapes of geom groups
2041 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2042 for ( ; data != _geomGroupData.end(); ++data )
2044 TopoDS_Shape newShape = newGroupShape( *data );
2045 if ( !newShape.IsNull() )
2047 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2049 TopoDS_Compound compound;
2050 BRep_Builder().MakeCompound( compound );
2051 BRep_Builder().Add( compound, newShape );
2052 newShape = compound;
2054 _impl->GetSubMesh( newShape );
2057 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2058 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2059 SALOME::INTERNAL_ERROR );
2061 // re-assign hypotheses
2062 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2064 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2065 const THypList& hyps = ids2Hyps[i].second;
2066 THypList::const_iterator h = hyps.begin();
2067 for ( ; h != hyps.end(); ++h )
2068 _impl->AddHypothesis( s, (*h)->GetID() );
2072 for ( size_t i = 0; i < groupsData.size(); ++i )
2074 const TGroupOnGeomData& data = groupsData[i];
2076 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2077 if ( i2g == _mapGroups.end() ) continue;
2079 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2080 if ( !gr_i ) continue;
2083 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2084 meshDS->IndexToShape( data._shapeID ));
2087 _mapGroups.erase( i2g );
2091 g->GetGroupDS()->SetColor( data._color );
2092 gr_i->changeLocalId( id );
2093 _mapGroups[ id ] = i2g->second;
2094 if ( data._oldID != id )
2095 _mapGroups.erase( i2g );
2099 // update _mapSubMesh
2100 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2101 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2102 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2106 //=============================================================================
2108 * \brief Update objects depending on changed geom groups
2110 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2111 * issue 0020210: Update of a smesh group after modification of the associated geom group
2113 //=============================================================================
2115 void SMESH_Mesh_i::CheckGeomGroupModif()
2117 if ( !_impl->HasShapeToMesh() ) return;
2119 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2120 if ( study->_is_nil() ) return;
2122 CORBA::Long nbEntities = NbNodes() + NbElements();
2124 // Check if group contents changed
2126 typedef map< string, TopoDS_Shape > TEntry2Geom;
2127 TEntry2Geom newGroupContents;
2129 list<TGeomGroupData>::iterator
2130 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2131 for ( ; data != dataEnd; ++data )
2133 pair< TEntry2Geom::iterator, bool > it_new =
2134 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2135 bool processedGroup = !it_new.second;
2136 TopoDS_Shape& newShape = it_new.first->second;
2137 if ( !processedGroup )
2138 newShape = newGroupShape( *data );
2139 if ( newShape.IsNull() )
2140 continue; // no changes
2143 _preMeshInfo->ForgetOrLoad();
2145 if ( processedGroup ) { // update group indices
2146 list<TGeomGroupData>::iterator data2 = data;
2147 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2148 data->_indices = data2->_indices;
2151 // Update SMESH objects according to new GEOM group contents
2153 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2154 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2156 int oldID = submesh->GetId();
2157 if ( !_mapSubMeshIor.count( oldID ))
2159 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2161 // update hypotheses
2162 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2163 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2164 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2166 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2167 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2169 // care of submeshes
2170 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2171 int newID = newSubmesh->GetId();
2172 if ( newID != oldID ) {
2173 _mapSubMesh [ newID ] = newSubmesh;
2174 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2175 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2176 _mapSubMesh. erase(oldID);
2177 _mapSubMesh_i. erase(oldID);
2178 _mapSubMeshIor.erase(oldID);
2179 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2184 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2185 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2186 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2188 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2190 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2191 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2192 ds->SetShape( newShape );
2197 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2198 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2200 // Remove groups and submeshes basing on removed sub-shapes
2202 TopTools_MapOfShape newShapeMap;
2203 TopoDS_Iterator shapeIt( newShape );
2204 for ( ; shapeIt.More(); shapeIt.Next() )
2205 newShapeMap.Add( shapeIt.Value() );
2207 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2208 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2210 if ( newShapeMap.Contains( shapeIt.Value() ))
2212 TopTools_IndexedMapOfShape oldShapeMap;
2213 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2214 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2216 const TopoDS_Shape& oldShape = oldShapeMap(i);
2217 int oldInd = meshDS->ShapeToIndex( oldShape );
2219 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2220 if ( i_smIor != _mapSubMeshIor.end() ) {
2221 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2224 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2225 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2227 // check if a group bases on oldInd shape
2228 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2229 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2230 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2231 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2233 RemoveGroup( i_grp->second ); // several groups can base on same shape
2234 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2239 // Reassign hypotheses and update groups after setting the new shape to mesh
2241 // collect anassigned hypotheses
2242 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2243 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2244 TShapeHypList assignedHyps;
2245 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2247 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2248 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2249 if ( !hyps.empty() ) {
2250 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2251 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2252 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2255 // collect shapes supporting groups
2256 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2257 TShapeTypeList groupData;
2258 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2259 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2260 for ( ; grIt != groups.end(); ++grIt )
2262 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2264 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2266 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2268 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2269 _impl->ShapeToMesh( newShape );
2271 // reassign hypotheses
2272 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2273 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2275 TIndexedShape& geom = indS_hyps->first;
2276 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2277 int oldID = geom._index;
2278 int newID = meshDS->ShapeToIndex( geom._shape );
2279 if ( oldID == 1 ) { // main shape
2281 geom._shape = newShape;
2285 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2286 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2287 // care of sub-meshes
2288 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2289 if ( newID != oldID ) {
2290 _mapSubMesh [ newID ] = newSubmesh;
2291 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2292 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2293 _mapSubMesh. erase(oldID);
2294 _mapSubMesh_i. erase(oldID);
2295 _mapSubMeshIor.erase(oldID);
2296 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2300 TShapeTypeList::iterator geomType = groupData.begin();
2301 for ( ; geomType != groupData.end(); ++geomType )
2303 const TIndexedShape& geom = geomType->first;
2304 int oldID = geom._index;
2305 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2308 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2309 CORBA::String_var name = groupSO->GetName();
2311 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2313 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2314 group_i->changeLocalId( newID );
2317 break; // everything has been updated
2320 } // loop on group data
2324 CORBA::Long newNbEntities = NbNodes() + NbElements();
2325 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2326 if ( newNbEntities != nbEntities )
2328 // Add all SObjects with icons to soToUpdateIcons
2329 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2331 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2332 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2333 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2335 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2336 i_gr != _mapGroups.end(); ++i_gr ) // groups
2337 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2340 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2341 for ( ; so != soToUpdateIcons.end(); ++so )
2342 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2345 //=============================================================================
2347 * \brief Create standalone group from a group on geometry or filter
2349 //=============================================================================
2351 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2352 throw (SALOME::SALOME_Exception)
2354 SMESH::SMESH_Group_var aGroup;
2359 _preMeshInfo->FullLoadFromFile();
2361 if ( theGroup->_is_nil() )
2362 return aGroup._retn();
2364 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2366 return aGroup._retn();
2368 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2370 const int anId = aGroupToRem->GetLocalID();
2371 if ( !_impl->ConvertToStandalone( anId ) )
2372 return aGroup._retn();
2373 removeGeomGroupData( theGroup );
2375 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2377 // remove old instance of group from own map
2378 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2379 _mapGroups.erase( anId );
2381 SALOMEDS::StudyBuilder_var builder;
2382 SALOMEDS::SObject_wrap aGroupSO;
2383 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2384 if ( !aStudy->_is_nil() ) {
2385 builder = aStudy->NewBuilder();
2386 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2387 if ( !aGroupSO->_is_nil() )
2389 // remove reference to geometry
2390 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2391 for ( ; chItr->More(); chItr->Next() )
2392 // Remove group's child SObject
2393 builder->RemoveObject( chItr->Value() );
2395 // Update Python script
2396 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2397 << ".ConvertToStandalone( " << aGroupSO << " )";
2399 // change icon of Group on Filter
2402 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2403 const int isEmpty = ( elemTypes->length() == 0 );
2406 SALOMEDS::GenericAttribute_wrap anAttr =
2407 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2408 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2409 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2415 // remember new group in own map
2416 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2417 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2419 // register CORBA object for persistence
2420 _gen_i->RegisterObject( aGroup );
2422 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2423 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2424 //aGroup->Register();
2425 aGroupToRem->UnRegister();
2427 SMESH_CATCH( SMESH::throwCorbaException );
2429 return aGroup._retn();
2432 //=============================================================================
2436 //=============================================================================
2438 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2440 if(MYDEBUG) MESSAGE( "createSubMesh" );
2441 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2442 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2443 const int subMeshId = mySubMesh->GetId();
2445 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2446 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2448 _mapSubMesh [subMeshId] = mySubMesh;
2449 _mapSubMesh_i [subMeshId] = subMeshServant;
2450 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2452 subMeshServant->Register();
2454 // register CORBA object for persistence
2455 int nextId = _gen_i->RegisterObject( subMesh );
2456 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2457 else { nextId = 0; } // avoid "unused variable" warning
2459 // to track changes of GEOM groups
2460 addGeomGroupData( theSubShapeObject, subMesh );
2462 return subMesh._retn();
2465 //=======================================================================
2466 //function : getSubMesh
2468 //=======================================================================
2470 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2472 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2473 if ( it == _mapSubMeshIor.end() )
2474 return SMESH::SMESH_subMesh::_nil();
2476 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2479 //=============================================================================
2483 //=============================================================================
2485 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2486 GEOM::GEOM_Object_ptr theSubShapeObject )
2488 bool isHypChanged = false;
2489 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2490 return isHypChanged;
2492 const int subMeshId = theSubMesh->GetId();
2494 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2496 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2498 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2501 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2502 isHypChanged = !hyps.empty();
2503 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2504 for ( ; hyp != hyps.end(); ++hyp )
2505 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2512 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2513 isHypChanged = ( aHypList->length() > 0 );
2514 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2515 removeHypothesis( theSubShapeObject, aHypList[i] );
2518 catch( const SALOME::SALOME_Exception& ) {
2519 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2521 removeGeomGroupData( theSubShapeObject );
2525 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2526 if ( id_smi != _mapSubMesh_i.end() )
2527 id_smi->second->UnRegister();
2529 // remove a CORBA object
2530 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2531 if ( id_smptr != _mapSubMeshIor.end() )
2532 SMESH::SMESH_subMesh_var( id_smptr->second );
2534 _mapSubMesh.erase(subMeshId);
2535 _mapSubMesh_i.erase(subMeshId);
2536 _mapSubMeshIor.erase(subMeshId);
2538 return isHypChanged;
2541 //=============================================================================
2545 //=============================================================================
2547 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2548 const char* theName,
2549 const TopoDS_Shape& theShape,
2550 const SMESH_PredicatePtr& thePredicate )
2552 std::string newName;
2553 if ( !theName || strlen( theName ) == 0 )
2555 std::set< std::string > presentNames;
2556 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2557 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2559 CORBA::String_var name = i_gr->second->GetName();
2560 presentNames.insert( name.in() );
2563 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2564 } while ( !presentNames.insert( newName ).second );
2565 theName = newName.c_str();
2568 SMESH::SMESH_GroupBase_var aGroup;
2569 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2571 SMESH_GroupBase_i* aGroupImpl;
2572 if ( !theShape.IsNull() )
2573 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2574 else if ( thePredicate )
2575 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2577 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2579 aGroup = aGroupImpl->_this();
2580 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2581 aGroupImpl->Register();
2583 // register CORBA object for persistence
2584 int nextId = _gen_i->RegisterObject( aGroup );
2585 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2586 else { nextId = 0; } // avoid "unused variable" warning in release mode
2588 // to track changes of GEOM groups
2589 if ( !theShape.IsNull() ) {
2590 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2591 addGeomGroupData( geom, aGroup );
2594 return aGroup._retn();
2597 //=============================================================================
2599 * SMESH_Mesh_i::removeGroup
2601 * Should be called by ~SMESH_Group_i()
2603 //=============================================================================
2605 void SMESH_Mesh_i::removeGroup( const int theId )
2607 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2608 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2609 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2610 _mapGroups.erase( theId );
2611 removeGeomGroupData( group );
2612 if ( !_impl->RemoveGroup( theId ))
2614 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2615 RemoveGroup( group );
2617 group->UnRegister();
2621 //=============================================================================
2625 //=============================================================================
2627 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2628 throw(SALOME::SALOME_Exception)
2630 SMESH::log_array_var aLog;
2634 _preMeshInfo->FullLoadFromFile();
2636 list < SMESHDS_Command * >logDS = _impl->GetLog();
2637 aLog = new SMESH::log_array;
2639 int lg = logDS.size();
2642 list < SMESHDS_Command * >::iterator its = logDS.begin();
2643 while(its != logDS.end()){
2644 SMESHDS_Command *com = *its;
2645 int comType = com->GetType();
2647 int lgcom = com->GetNumber();
2649 const list < int >&intList = com->GetIndexes();
2650 int inum = intList.size();
2652 list < int >::const_iterator ii = intList.begin();
2653 const list < double >&coordList = com->GetCoords();
2654 int rnum = coordList.size();
2656 list < double >::const_iterator ir = coordList.begin();
2657 aLog[indexLog].commandType = comType;
2658 aLog[indexLog].number = lgcom;
2659 aLog[indexLog].coords.length(rnum);
2660 aLog[indexLog].indexes.length(inum);
2661 for(int i = 0; i < rnum; i++){
2662 aLog[indexLog].coords[i] = *ir;
2663 //MESSAGE(" "<<i<<" "<<ir.Value());
2666 for(int i = 0; i < inum; i++){
2667 aLog[indexLog].indexes[i] = *ii;
2668 //MESSAGE(" "<<i<<" "<<ii.Value());
2677 SMESH_CATCH( SMESH::throwCorbaException );
2679 return aLog._retn();
2683 //=============================================================================
2687 //=============================================================================
2689 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2693 SMESH_CATCH( SMESH::throwCorbaException );
2696 //=============================================================================
2700 //=============================================================================
2702 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2707 //=============================================================================
2711 //=============================================================================
2713 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2718 //=============================================================================
2721 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2722 // issue 0020918: groups removal is caused by hyp modification
2723 // issue 0021208: to forget not loaded mesh data at hyp modification
2724 struct TCallUp_i : public SMESH_Mesh::TCallUp
2726 SMESH_Mesh_i* _mesh;
2727 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2728 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2729 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2730 virtual void Load () { _mesh->Load(); }
2734 //================================================================================
2736 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2738 //================================================================================
2740 void SMESH_Mesh_i::onHypothesisModified()
2743 _preMeshInfo->ForgetOrLoad();
2746 //=============================================================================
2750 //=============================================================================
2752 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2754 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2757 _impl->SetCallUp( new TCallUp_i(this));
2760 //=============================================================================
2764 //=============================================================================
2766 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2768 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2772 //=============================================================================
2774 * Return mesh editor
2776 //=============================================================================
2778 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2779 throw (SALOME::SALOME_Exception)
2781 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2785 _preMeshInfo->FullLoadFromFile();
2787 // Create MeshEditor
2789 _editor = new SMESH_MeshEditor_i( this, false );
2790 aMeshEdVar = _editor->_this();
2792 // Update Python script
2793 TPythonDump() << _editor << " = "
2794 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2796 SMESH_CATCH( SMESH::throwCorbaException );
2798 return aMeshEdVar._retn();
2801 //=============================================================================
2803 * Return mesh edition previewer
2805 //=============================================================================
2807 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2808 throw (SALOME::SALOME_Exception)
2810 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2814 _preMeshInfo->FullLoadFromFile();
2816 if ( !_previewEditor )
2817 _previewEditor = new SMESH_MeshEditor_i( this, true );
2818 aMeshEdVar = _previewEditor->_this();
2820 SMESH_CATCH( SMESH::throwCorbaException );
2822 return aMeshEdVar._retn();
2825 //================================================================================
2827 * \brief Return true if the mesh has been edited since a last total re-compute
2828 * and those modifications may prevent successful partial re-compute
2830 //================================================================================
2832 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2834 Unexpect aCatch(SALOME_SalomeException);
2835 return _impl->HasModificationsToDiscard();
2838 //================================================================================
2840 * \brief Returns a random unique color
2842 //================================================================================
2844 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2846 const int MAX_ATTEMPTS = 100;
2848 double tolerance = 0.5;
2849 SALOMEDS::Color col;
2853 // generate random color
2854 double red = (double)rand() / RAND_MAX;
2855 double green = (double)rand() / RAND_MAX;
2856 double blue = (double)rand() / RAND_MAX;
2857 // check existence in the list of the existing colors
2858 bool matched = false;
2859 std::list<SALOMEDS::Color>::const_iterator it;
2860 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2861 SALOMEDS::Color color = *it;
2862 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2863 matched = tol < tolerance;
2865 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2866 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2874 //=============================================================================
2876 * Sets auto-color mode. If it is on, groups get unique random colors
2878 //=============================================================================
2880 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2882 Unexpect aCatch(SALOME_SalomeException);
2883 _impl->SetAutoColor(theAutoColor);
2885 TPythonDump pyDump; // not to dump group->SetColor() from below code
2886 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2888 std::list<SALOMEDS::Color> aReservedColors;
2889 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2890 for ( ; it != _mapGroups.end(); it++ ) {
2891 if ( CORBA::is_nil( it->second )) continue;
2892 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2893 it->second->SetColor( aColor );
2894 aReservedColors.push_back( aColor );
2898 //=============================================================================
2900 * Returns true if auto-color mode is on
2902 //=============================================================================
2904 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2906 Unexpect aCatch(SALOME_SalomeException);
2907 return _impl->GetAutoColor();
2910 //=============================================================================
2912 * Checks if there are groups with equal names
2914 //=============================================================================
2916 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2918 return _impl->HasDuplicatedGroupNamesMED();
2921 //================================================================================
2923 * \brief Care of a file before exporting mesh into it
2925 //================================================================================
2927 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2929 SMESH_File aFile( file );
2931 if (aFile.exists()) {
2932 // existing filesystem node
2933 if ( !aFile.isDirectory() ) {
2934 if ( aFile.openForWriting() ) {
2935 if ( overwrite && ! aFile.remove()) {
2936 msg << "Can't replace " << aFile.getName();
2939 msg << "Can't write into " << aFile.getName();
2942 msg << "Location " << aFile.getName() << " is not a file";
2946 // nonexisting file; check if it can be created
2947 if ( !aFile.openForWriting() ) {
2948 msg << "You cannot create the file "
2950 << ". Check the directory existance and access rights";
2958 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2962 //================================================================================
2964 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2965 * \param file - file name
2966 * \param overwrite - to erase the file or not
2967 * \retval string - mesh name
2969 //================================================================================
2971 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2972 CORBA::Boolean overwrite)
2975 PrepareForWriting(file, overwrite);
2976 string aMeshName = "Mesh";
2977 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2978 if ( !aStudy->_is_nil() ) {
2979 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2980 if ( !aMeshSO->_is_nil() ) {
2981 CORBA::String_var name = aMeshSO->GetName();
2983 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2984 if ( !aStudy->GetProperties()->IsLocked() )
2986 SALOMEDS::GenericAttribute_wrap anAttr;
2987 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2988 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2989 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2990 ASSERT(!aFileName->_is_nil());
2991 aFileName->SetValue(file);
2992 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2993 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2994 ASSERT(!aFileType->_is_nil());
2995 aFileType->SetValue("FICHIERMED");
2999 // Update Python script
3000 // set name of mesh before export
3001 TPythonDump() << _gen_i << ".SetName("
3002 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3004 // check names of groups
3010 //================================================================================
3012 * \brief Export to med file
3014 //================================================================================
3016 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3017 CORBA::Boolean auto_groups,
3018 SMESH::MED_VERSION theVersion,
3019 CORBA::Boolean overwrite,
3020 CORBA::Boolean autoDimension)
3021 throw(SALOME::SALOME_Exception)
3025 _preMeshInfo->FullLoadFromFile();
3027 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3028 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3030 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3031 << file << "', " << auto_groups << ", "
3032 << theVersion << ", " << overwrite << ", "
3033 << autoDimension << " )";
3035 SMESH_CATCH( SMESH::throwCorbaException );
3038 //================================================================================
3040 * \brief Export a mesh to a med file
3042 //================================================================================
3044 void SMESH_Mesh_i::ExportToMED (const char* file,
3045 CORBA::Boolean auto_groups,
3046 SMESH::MED_VERSION theVersion)
3047 throw(SALOME::SALOME_Exception)
3049 ExportToMEDX(file,auto_groups,theVersion,true);
3052 //================================================================================
3054 * \brief Export a mesh to a med file
3056 //================================================================================
3058 void SMESH_Mesh_i::ExportMED (const char* file,
3059 CORBA::Boolean auto_groups)
3060 throw(SALOME::SALOME_Exception)
3062 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3065 //================================================================================
3067 * \brief Export a mesh to a SAUV file
3069 //================================================================================
3071 void SMESH_Mesh_i::ExportSAUV (const char* file,
3072 CORBA::Boolean auto_groups)
3073 throw(SALOME::SALOME_Exception)
3075 Unexpect aCatch(SALOME_SalomeException);
3077 _preMeshInfo->FullLoadFromFile();
3079 string aMeshName = prepareMeshNameAndGroups(file, true);
3080 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3081 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3082 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3086 //================================================================================
3088 * \brief Export a mesh to a DAT file
3090 //================================================================================
3092 void SMESH_Mesh_i::ExportDAT (const char *file)
3093 throw(SALOME::SALOME_Exception)
3095 Unexpect aCatch(SALOME_SalomeException);
3097 _preMeshInfo->FullLoadFromFile();
3099 // Update Python script
3100 // check names of groups
3102 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3105 PrepareForWriting(file);
3106 _impl->ExportDAT(file);
3109 //================================================================================
3111 * \brief Export a mesh to an UNV file
3113 //================================================================================
3115 void SMESH_Mesh_i::ExportUNV (const char *file)
3116 throw(SALOME::SALOME_Exception)
3118 Unexpect aCatch(SALOME_SalomeException);
3120 _preMeshInfo->FullLoadFromFile();
3122 // Update Python script
3123 // check names of groups
3125 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3128 PrepareForWriting(file);
3129 _impl->ExportUNV(file);
3132 //================================================================================
3134 * \brief Export a mesh to an STL file
3136 //================================================================================
3138 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3139 throw(SALOME::SALOME_Exception)
3141 Unexpect aCatch(SALOME_SalomeException);
3143 _preMeshInfo->FullLoadFromFile();
3145 // Update Python script
3146 // check names of groups
3148 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3149 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3152 PrepareForWriting(file);
3153 _impl->ExportSTL(file, isascii);
3156 //================================================================================
3158 * \brief Export a part of mesh to a med file
3160 //================================================================================
3162 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3164 CORBA::Boolean auto_groups,
3165 SMESH::MED_VERSION version,
3166 CORBA::Boolean overwrite,
3167 CORBA::Boolean autoDimension,
3168 const GEOM::ListOfFields& fields,
3169 const char* geomAssocFields)
3170 throw (SALOME::SALOME_Exception)
3174 _preMeshInfo->FullLoadFromFile();
3177 bool have0dField = false;
3178 if ( fields.length() > 0 )
3180 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3181 if ( shapeToMesh->_is_nil() )
3182 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3184 for ( size_t i = 0; i < fields.length(); ++i )
3186 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3187 THROW_SALOME_CORBA_EXCEPTION
3188 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3189 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3190 if ( fieldShape->_is_nil() )
3191 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3192 if ( !fieldShape->IsSame( shapeToMesh ) )
3193 THROW_SALOME_CORBA_EXCEPTION
3194 ( "Field defined not on shape", SALOME::BAD_PARAM);
3195 if ( fields[i]->GetDimension() == 0 )
3198 if ( geomAssocFields )
3199 for ( int i = 0; geomAssocFields[i]; ++i )
3200 switch ( geomAssocFields[i] ) {
3201 case 'v':case 'e':case 'f':case 's': break;
3202 case 'V':case 'E':case 'F':case 'S': break;
3203 default: THROW_SALOME_CORBA_EXCEPTION
3204 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3208 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3212 string aMeshName = "Mesh";
3213 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3214 if ( CORBA::is_nil( meshPart ) ||
3215 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3217 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3218 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3219 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3220 meshDS = _impl->GetMeshDS();