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();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 catch(SALOME_Exception & S_ex) {
238 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
240 return aShapeObj._retn();
243 //================================================================================
245 * \brief Return false if the mesh is not yet fully loaded from the study file
247 //================================================================================
249 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
252 return !_preMeshInfo;
255 //================================================================================
257 * \brief Load full mesh data from the study file
259 //================================================================================
261 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->FullLoadFromFile();
268 //================================================================================
270 * \brief Remove all nodes and elements
272 //================================================================================
274 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->ForgetAllData();
282 //CheckGeomGroupModif(); // issue 20145
284 catch(SALOME_Exception & S_ex) {
285 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
287 _impl->GetMeshDS()->Modified();
289 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
292 //================================================================================
294 * \brief Remove all nodes and elements for indicated shape
296 //================================================================================
298 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
299 throw (SALOME::SALOME_Exception)
301 Unexpect aCatch(SALOME_SalomeException);
303 _preMeshInfo->FullLoadFromFile();
306 _impl->ClearSubMesh( ShapeID );
308 catch(SALOME_Exception & S_ex) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
311 _impl->GetMeshDS()->Modified();
313 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
316 //=============================================================================
318 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
320 //=============================================================================
322 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
324 SMESH::DriverMED_ReadStatus res;
327 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
328 res = SMESH::DRS_OK; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
330 res = SMESH::DRS_EMPTY; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
332 res = SMESH::DRS_WARN_RENUMBER; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
334 res = SMESH::DRS_WARN_SKIP_ELEM; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
336 res = SMESH::DRS_WARN_DESCENDING; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
339 res = SMESH::DRS_FAIL; break;
344 //=============================================================================
346 * Convert ::SMESH_ComputeError to SMESH::ComputeError
348 //=============================================================================
350 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
352 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
353 errVar->subShapeID = -1;
354 errVar->hasBadMesh = false;
356 if ( !errorPtr || errorPtr->IsOK() )
358 errVar->code = SMESH::COMPERR_OK;
362 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
363 errVar->comment = errorPtr->myComment.c_str();
365 return errVar._retn();
368 //=============================================================================
372 * Imports mesh data from MED file
374 //=============================================================================
376 SMESH::DriverMED_ReadStatus
377 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
378 throw ( SALOME::SALOME_Exception )
380 Unexpect aCatch(SALOME_SalomeException);
383 status = _impl->MEDToMesh( theFileName, theMeshName );
385 catch( SALOME_Exception& S_ex ) {
386 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
392 CreateGroupServants();
394 int major, minor, release;
395 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
396 major = minor = release = -1;
397 _medFileInfo = new SMESH::MedFileInfo();
398 _medFileInfo->fileName = theFileName;
399 _medFileInfo->fileSize = 0;
400 _medFileInfo->major = major;
401 _medFileInfo->minor = minor;
402 _medFileInfo->release = release;
403 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
405 return ConvertDriverMEDReadStatus(status);
408 //================================================================================
410 * \brief Imports mesh data from the CGNS file
412 //================================================================================
414 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
415 const int theMeshIndex,
416 std::string& theMeshName )
417 throw ( SALOME::SALOME_Exception )
419 Unexpect aCatch(SALOME_SalomeException);
422 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
424 catch( SALOME_Exception& S_ex ) {
425 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
428 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
431 CreateGroupServants();
433 return ConvertDriverMEDReadStatus(status);
436 //================================================================================
438 * \brief Return string representation of a MED file version comprising nbDigits
440 //================================================================================
442 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
444 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
446 return CORBA::string_dup( ver.c_str() );
449 //=============================================================================
453 * Imports mesh data from MED file
455 //=============================================================================
457 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
458 throw ( SALOME::SALOME_Exception )
462 // Read mesh with name = <theMeshName> into SMESH_Mesh
463 _impl->UNVToMesh( theFileName );
465 CreateGroupServants();
467 SMESH_CATCH( SMESH::throwCorbaException );
472 //=============================================================================
476 * Imports mesh data from STL file
478 //=============================================================================
479 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->STLToMesh( theFileName );
487 SMESH_CATCH( SMESH::throwCorbaException );
492 //================================================================================
494 * \brief Function used in SMESH_CATCH by ImportGMFFile()
496 //================================================================================
500 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
502 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
506 //================================================================================
508 * \brief Imports data from a GMF file and returns an error description
510 //================================================================================
512 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
513 bool theMakeRequiredGroups )
514 throw (SALOME::SALOME_Exception)
516 SMESH_ComputeErrorPtr error;
519 #define SMESH_CAUGHT error =
522 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
524 SMESH_CATCH( exceptionToComputeError );
528 CreateGroupServants();
530 return ConvertComputeError( error );
533 //=============================================================================
537 //=============================================================================
539 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
541 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
542 (SMESH_Hypothesis::Hypothesis_Status theStatus)
545 RETURNCASE( HYP_OK );
546 RETURNCASE( HYP_MISSING );
547 RETURNCASE( HYP_CONCURENT );
548 RETURNCASE( HYP_BAD_PARAMETER );
549 RETURNCASE( HYP_HIDDEN_ALGO );
550 RETURNCASE( HYP_HIDING_ALGO );
551 RETURNCASE( HYP_UNKNOWN_FATAL );
552 RETURNCASE( HYP_INCOMPATIBLE );
553 RETURNCASE( HYP_NOTCONFORM );
554 RETURNCASE( HYP_ALREADY_EXIST );
555 RETURNCASE( HYP_BAD_DIM );
556 RETURNCASE( HYP_BAD_SUBSHAPE );
557 RETURNCASE( HYP_BAD_GEOMETRY );
558 RETURNCASE( HYP_NEED_SHAPE );
559 RETURNCASE( HYP_INCOMPAT_HYPS );
562 return SMESH::HYP_UNKNOWN_FATAL;
565 //=============================================================================
569 * calls internal addHypothesis() and then adds a reference to <anHyp> under
570 * the SObject actually having a reference to <aSubShape>.
571 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
573 //=============================================================================
575 SMESH::Hypothesis_Status
576 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
577 SMESH::SMESH_Hypothesis_ptr anHyp,
578 CORBA::String_out anErrorText)
579 throw(SALOME::SALOME_Exception)
581 Unexpect aCatch(SALOME_SalomeException);
583 _preMeshInfo->ForgetOrLoad();
586 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
587 anErrorText = error.c_str();
589 SMESH::SMESH_Mesh_var mesh( _this() );
590 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
592 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
593 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
595 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
597 // Update Python script
598 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
599 << aSubShape << ", " << anHyp << " )";
601 return ConvertHypothesisStatus(status);
604 //=============================================================================
608 //=============================================================================
610 SMESH_Hypothesis::Hypothesis_Status
611 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
612 SMESH::SMESH_Hypothesis_ptr anHyp,
613 std::string* anErrorText)
615 if(MYDEBUG) MESSAGE("addHypothesis");
617 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
618 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
620 if (CORBA::is_nil( anHyp ))
621 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
623 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
626 TopoDS_Shape myLocSubShape;
627 //use PseudoShape in case if mesh has no shape
629 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
631 myLocSubShape = _impl->GetShapeToMesh();
633 const int hypId = anHyp->GetId();
635 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
636 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
638 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
640 // assure there is a corresponding submesh
641 if ( !_impl->IsMainShape( myLocSubShape )) {
642 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
643 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
644 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
647 else if ( anErrorText )
649 *anErrorText = error;
652 catch(SALOME_Exception & S_ex)
654 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
659 //=============================================================================
663 //=============================================================================
665 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
666 SMESH::SMESH_Hypothesis_ptr anHyp)
667 throw(SALOME::SALOME_Exception)
669 Unexpect aCatch(SALOME_SalomeException);
671 _preMeshInfo->ForgetOrLoad();
673 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
674 SMESH::SMESH_Mesh_var mesh = _this();
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
679 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
681 // Update Python script
682 if(_impl->HasShapeToMesh())
683 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
684 << aSubShape << ", " << anHyp << " )";
686 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
689 return ConvertHypothesisStatus(status);
692 //=============================================================================
696 //=============================================================================
698 SMESH_Hypothesis::Hypothesis_Status
699 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
700 SMESH::SMESH_Hypothesis_ptr anHyp)
702 if(MYDEBUG) MESSAGE("removeHypothesis()");
704 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
705 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
707 if (CORBA::is_nil( anHyp ))
708 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
710 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
713 TopoDS_Shape myLocSubShape;
714 //use PseudoShape in case if mesh has no shape
715 if( _impl->HasShapeToMesh() )
716 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
718 myLocSubShape = _impl->GetShapeToMesh();
720 const int hypId = anHyp->GetId();
721 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
728 catch(SALOME_Exception & S_ex)
730 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
735 //=============================================================================
739 //=============================================================================
741 SMESH::ListOfHypothesis *
742 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
743 throw(SALOME::SALOME_Exception)
745 Unexpect aCatch(SALOME_SalomeException);
746 if (MYDEBUG) MESSAGE("GetHypothesisList");
747 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
748 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
750 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
753 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
754 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
755 myLocSubShape = _impl->GetShapeToMesh();
756 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
757 int i = 0, n = aLocalList.size();
760 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
761 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
762 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
764 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
765 if ( id_hypptr != _mapHypo.end() )
766 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
770 catch(SALOME_Exception & S_ex) {
771 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
774 return aList._retn();
777 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
779 Unexpect aCatch(SALOME_SalomeException);
780 if (MYDEBUG) MESSAGE("GetSubMeshes");
782 SMESH::submesh_array_var aList = new SMESH::submesh_array();
785 TPythonDump aPythonDump;
786 if ( !_mapSubMeshIor.empty() )
790 aList->length( _mapSubMeshIor.size() );
792 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
793 for ( ; it != _mapSubMeshIor.end(); it++ ) {
794 if ( CORBA::is_nil( it->second )) continue;
795 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
797 if (i > 1) aPythonDump << ", ";
798 aPythonDump << it->second;
802 catch(SALOME_Exception & S_ex) {
803 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
806 // Update Python script
807 if ( !_mapSubMeshIor.empty() )
808 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
810 return aList._retn();
813 //=============================================================================
817 //=============================================================================
819 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
820 const char* theName )
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (CORBA::is_nil(aSubShape))
825 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
827 SMESH::SMESH_subMesh_var subMesh;
828 SMESH::SMESH_Mesh_var aMesh = _this();
830 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 //Get or Create the SMESH_subMesh object implementation
834 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
836 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
838 TopoDS_Iterator it( myLocSubShape );
840 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
842 subMesh = getSubMesh( subMeshId );
844 // create a new subMesh object servant if there is none for the shape
845 if ( subMesh->_is_nil() )
846 subMesh = createSubMesh( aSubShape );
847 if ( _gen_i->CanPublishInStudy( subMesh ))
849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
850 SALOMEDS::SObject_wrap aSO =
851 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
852 if ( !aSO->_is_nil()) {
853 // Update Python script
854 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
855 << aSubShape << ", '" << theName << "' )";
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862 return subMesh._retn();
865 //=============================================================================
869 //=============================================================================
871 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
872 throw (SALOME::SALOME_Exception)
876 if ( theSubMesh->_is_nil() )
879 GEOM::GEOM_Object_var aSubShape;
880 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
881 if ( !aStudy->_is_nil() ) {
882 // Remove submesh's SObject
883 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
884 if ( !anSO->_is_nil() ) {
885 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
886 SALOMEDS::SObject_wrap anObj, aRef;
887 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
888 anObj->ReferencedObject( aRef.inout() ))
890 CORBA::Object_var obj = aRef->GetObject();
891 aSubShape = GEOM::GEOM_Object::_narrow( obj );
893 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
894 // aSubShape = theSubMesh->GetSubShape();
896 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
897 builder->RemoveObjectWithChildren( anSO );
899 // Update Python script
900 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
904 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
906 _preMeshInfo->ForgetOrLoad();
908 SMESH_CATCH( SMESH::throwCorbaException );
911 //=============================================================================
915 //=============================================================================
917 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
918 const char* theName )
919 throw(SALOME::SALOME_Exception)
921 Unexpect aCatch(SALOME_SalomeException);
923 _preMeshInfo->FullLoadFromFile();
925 SMESH::SMESH_Group_var aNewGroup =
926 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
928 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
930 SMESH::SMESH_Mesh_var mesh = _this();
931 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
932 SALOMEDS::SObject_wrap aSO =
933 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
934 if ( !aSO->_is_nil())
935 // Update Python script
936 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
937 << theElemType << ", '" << theName << "' )";
939 return aNewGroup._retn();
942 //=============================================================================
946 //=============================================================================
947 SMESH::SMESH_GroupOnGeom_ptr
948 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
950 GEOM::GEOM_Object_ptr theGeomObj)
951 throw(SALOME::SALOME_Exception)
953 Unexpect aCatch(SALOME_SalomeException);
955 _preMeshInfo->FullLoadFromFile();
957 SMESH::SMESH_GroupOnGeom_var aNewGroup;
959 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
960 if ( !aShape.IsNull() )
963 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
965 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
967 SMESH::SMESH_Mesh_var mesh = _this();
968 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
969 SALOMEDS::SObject_wrap aSO =
970 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
971 if ( !aSO->_is_nil())
972 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
973 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
977 return aNewGroup._retn();
980 //================================================================================
982 * \brief Creates a group whose contents is defined by filter
983 * \param theElemType - group type
984 * \param theName - group name
985 * \param theFilter - the filter
986 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
988 //================================================================================
990 SMESH::SMESH_GroupOnFilter_ptr
991 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
993 SMESH::Filter_ptr theFilter )
994 throw (SALOME::SALOME_Exception)
996 Unexpect aCatch(SALOME_SalomeException);
998 _preMeshInfo->FullLoadFromFile();
1000 if ( CORBA::is_nil( theFilter ))
1001 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1003 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1005 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1007 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1008 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1011 if ( !aNewGroup->_is_nil() )
1012 aNewGroup->SetFilter( theFilter );
1014 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1016 SMESH::SMESH_Mesh_var mesh = _this();
1017 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1018 SALOMEDS::SObject_wrap aSO =
1019 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1021 if ( !aSO->_is_nil())
1022 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1023 << theElemType << ", '" << theName << "', " << theFilter << " )";
1025 return aNewGroup._retn();
1028 //=============================================================================
1032 //=============================================================================
1034 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1035 throw (SALOME::SALOME_Exception)
1037 if ( theGroup->_is_nil() )
1042 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1046 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1047 if ( !aStudy->_is_nil() )
1049 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1050 if ( !aGroupSO->_is_nil() )
1052 // Update Python script
1053 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1055 // Remove group's SObject
1056 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1057 builder->RemoveObjectWithChildren( aGroupSO );
1061 // Remove the group from SMESH data structures
1062 removeGroup( aGroup->GetLocalID() );
1064 SMESH_CATCH( SMESH::throwCorbaException );
1067 //=============================================================================
1069 * Remove group with its contents
1071 //=============================================================================
1073 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1074 throw (SALOME::SALOME_Exception)
1078 _preMeshInfo->FullLoadFromFile();
1080 if ( theGroup->_is_nil() )
1084 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1085 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1086 while ( elemIt->more() )
1087 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1089 TPythonDump pyDump; // Supress dump from RemoveGroup()
1091 // Update Python script (theGroup must be alive for this)
1092 pyDump << SMESH::SMESH_Mesh_var(_this())
1093 << ".RemoveGroupWithContents( " << theGroup << " )";
1096 RemoveGroup( theGroup );
1098 SMESH_CATCH( SMESH::throwCorbaException );
1101 //================================================================================
1103 * \brief Get the list of groups existing in the mesh
1104 * \retval SMESH::ListOfGroups * - list of groups
1106 //================================================================================
1108 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1110 Unexpect aCatch(SALOME_SalomeException);
1111 if (MYDEBUG) MESSAGE("GetGroups");
1113 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1116 TPythonDump aPythonDump;
1117 if ( !_mapGroups.empty() )
1119 aPythonDump << "[ ";
1121 aList->length( _mapGroups.size() );
1123 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1124 for ( ; it != _mapGroups.end(); it++ ) {
1125 if ( CORBA::is_nil( it->second )) continue;
1126 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1128 if (i > 1) aPythonDump << ", ";
1129 aPythonDump << it->second;
1133 catch(SALOME_Exception & S_ex) {
1134 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1136 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1138 return aList._retn();
1141 //=============================================================================
1143 * Get number of groups existing in the mesh
1145 //=============================================================================
1147 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1149 Unexpect aCatch(SALOME_SalomeException);
1150 return _mapGroups.size();
1153 //=============================================================================
1155 * New group including all mesh elements present in initial groups is created.
1157 //=============================================================================
1159 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1160 SMESH::SMESH_GroupBase_ptr theGroup2,
1161 const char* theName )
1162 throw (SALOME::SALOME_Exception)
1164 SMESH::SMESH_Group_var aResGrp;
1168 _preMeshInfo->FullLoadFromFile();
1170 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1171 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1173 if ( theGroup1->GetType() != theGroup2->GetType() )
1174 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1179 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1180 if ( aResGrp->_is_nil() )
1181 return SMESH::SMESH_Group::_nil();
1183 aResGrp->AddFrom( theGroup1 );
1184 aResGrp->AddFrom( theGroup2 );
1186 // Update Python script
1187 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1188 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1190 SMESH_CATCH( SMESH::throwCorbaException );
1192 return aResGrp._retn();
1195 //=============================================================================
1197 * \brief New group including all mesh elements present in initial groups is created.
1198 * \param theGroups list of groups
1199 * \param theName name of group to be created
1200 * \return pointer to the new group
1202 //=============================================================================
1204 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1205 const char* theName )
1206 throw (SALOME::SALOME_Exception)
1208 SMESH::SMESH_Group_var aResGrp;
1211 _preMeshInfo->FullLoadFromFile();
1214 return SMESH::SMESH_Group::_nil();
1219 SMESH::ElementType aType = SMESH::ALL;
1220 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1222 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1223 if ( CORBA::is_nil( aGrp ) )
1225 if ( aType == SMESH::ALL )
1226 aType = aGrp->GetType();
1227 else if ( aType != aGrp->GetType() )
1228 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1231 if ( aType == SMESH::ALL )
1232 return SMESH::SMESH_Group::_nil();
1237 aResGrp = CreateGroup( aType, theName );
1238 if ( aResGrp->_is_nil() )
1239 return SMESH::SMESH_Group::_nil();
1241 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1242 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1244 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1245 if ( !CORBA::is_nil( aGrp ) )
1247 aResGrp->AddFrom( aGrp );
1248 if ( g > 0 ) pyDump << ", ";
1252 pyDump << " ], '" << theName << "' )";
1254 SMESH_CATCH( SMESH::throwCorbaException );
1256 return aResGrp._retn();
1259 //=============================================================================
1261 * New group is created. All mesh elements that are
1262 * present in both initial groups are added to the new one.
1264 //=============================================================================
1266 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1267 SMESH::SMESH_GroupBase_ptr theGroup2,
1268 const char* theName )
1269 throw (SALOME::SALOME_Exception)
1271 SMESH::SMESH_Group_var aResGrp;
1276 _preMeshInfo->FullLoadFromFile();
1278 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1279 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1281 if ( theGroup1->GetType() != theGroup2->GetType() )
1282 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1286 // Create Intersection
1287 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1288 if ( aResGrp->_is_nil() )
1289 return aResGrp._retn();
1291 SMESHDS_GroupBase* groupDS1 = 0;
1292 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1293 groupDS1 = grp_i->GetGroupDS();
1295 SMESHDS_GroupBase* groupDS2 = 0;
1296 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1297 groupDS2 = grp_i->GetGroupDS();
1299 SMESHDS_Group* resGroupDS = 0;
1300 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1301 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1303 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1305 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1306 while ( elemIt1->more() )
1308 const SMDS_MeshElement* e = elemIt1->next();
1309 if ( groupDS2->Contains( e ))
1310 resGroupDS->SMDSGroup().Add( e );
1313 // Update Python script
1314 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1315 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1317 SMESH_CATCH( SMESH::throwCorbaException );
1319 return aResGrp._retn();
1322 //=============================================================================
1324 \brief Intersect list of groups. New group is created. All mesh elements that
1325 are present in all initial groups simultaneously are added to the new one.
1326 \param theGroups list of groups
1327 \param theName name of group to be created
1328 \return pointer on the group
1330 //=============================================================================
1331 SMESH::SMESH_Group_ptr
1332 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1333 const char* theName )
1334 throw (SALOME::SALOME_Exception)
1336 SMESH::SMESH_Group_var aResGrp;
1341 _preMeshInfo->FullLoadFromFile();
1344 return SMESH::SMESH_Group::_nil();
1346 // check types and get SMESHDS_GroupBase's
1347 SMESH::ElementType aType = SMESH::ALL;
1348 vector< SMESHDS_GroupBase* > groupVec;
1349 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1351 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1352 if ( CORBA::is_nil( aGrp ) )
1354 if ( aType == SMESH::ALL )
1355 aType = aGrp->GetType();
1356 else if ( aType != aGrp->GetType() )
1357 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1360 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1361 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1363 if ( grpDS->IsEmpty() )
1368 groupVec.push_back( grpDS );
1371 if ( aType == SMESH::ALL ) // all groups are nil
1372 return SMESH::SMESH_Group::_nil();
1377 aResGrp = CreateGroup( aType, theName );
1379 SMESHDS_Group* resGroupDS = 0;
1380 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1381 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1382 if ( !resGroupDS || groupVec.empty() )
1383 return aResGrp._retn();
1386 size_t i, nb = groupVec.size();
1387 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1388 while ( elemIt1->more() )
1390 const SMDS_MeshElement* e = elemIt1->next();
1392 for ( i = 1; ( i < nb && inAll ); ++i )
1393 inAll = groupVec[i]->Contains( e );
1396 resGroupDS->SMDSGroup().Add( e );
1399 // Update Python script
1400 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1401 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1403 SMESH_CATCH( SMESH::throwCorbaException );
1405 return aResGrp._retn();
1408 //=============================================================================
1410 * New group is created. All mesh elements that are present in
1411 * a main group but is not present in a tool group are added to the new one
1413 //=============================================================================
1415 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1416 SMESH::SMESH_GroupBase_ptr theGroup2,
1417 const char* theName )
1418 throw (SALOME::SALOME_Exception)
1420 SMESH::SMESH_Group_var aResGrp;
1425 _preMeshInfo->FullLoadFromFile();
1427 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1428 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1430 if ( theGroup1->GetType() != theGroup2->GetType() )
1431 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1435 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1436 if ( aResGrp->_is_nil() )
1437 return aResGrp._retn();
1439 SMESHDS_GroupBase* groupDS1 = 0;
1440 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1441 groupDS1 = grp_i->GetGroupDS();
1443 SMESHDS_GroupBase* groupDS2 = 0;
1444 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1445 groupDS2 = grp_i->GetGroupDS();
1447 SMESHDS_Group* resGroupDS = 0;
1448 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1449 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1451 if ( groupDS1 && groupDS2 && resGroupDS )
1453 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1454 while ( elemIt1->more() )
1456 const SMDS_MeshElement* e = elemIt1->next();
1457 if ( !groupDS2->Contains( e ))
1458 resGroupDS->SMDSGroup().Add( e );
1461 // Update Python script
1462 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1463 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1465 SMESH_CATCH( SMESH::throwCorbaException );
1467 return aResGrp._retn();
1470 //=============================================================================
1472 \brief Cut lists of groups. New group is created. All mesh elements that are
1473 present in main groups but do not present in tool groups are added to the new one
1474 \param theMainGroups list of main groups
1475 \param theToolGroups list of tool groups
1476 \param theName name of group to be created
1477 \return pointer on the group
1479 //=============================================================================
1480 SMESH::SMESH_Group_ptr
1481 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1482 const SMESH::ListOfGroups& theToolGroups,
1483 const char* theName )
1484 throw (SALOME::SALOME_Exception)
1486 SMESH::SMESH_Group_var aResGrp;
1491 _preMeshInfo->FullLoadFromFile();
1494 return SMESH::SMESH_Group::_nil();
1496 // check types and get SMESHDS_GroupBase's
1497 SMESH::ElementType aType = SMESH::ALL;
1498 vector< SMESHDS_GroupBase* > toolGroupVec;
1499 vector< SMDS_ElemIteratorPtr > mainIterVec;
1501 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1503 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1504 if ( CORBA::is_nil( aGrp ) )
1506 if ( aType == SMESH::ALL )
1507 aType = aGrp->GetType();
1508 else if ( aType != aGrp->GetType() )
1509 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1511 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1512 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1513 if ( !grpDS->IsEmpty() )
1514 mainIterVec.push_back( grpDS->GetElements() );
1516 if ( aType == SMESH::ALL ) // all main groups are nil
1517 return SMESH::SMESH_Group::_nil();
1518 if ( mainIterVec.empty() ) // all main groups are empty
1519 return aResGrp._retn();
1521 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1523 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1524 if ( CORBA::is_nil( aGrp ) )
1526 if ( aType != aGrp->GetType() )
1527 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1529 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1530 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1531 toolGroupVec.push_back( grpDS );
1537 aResGrp = CreateGroup( aType, theName );
1539 SMESHDS_Group* resGroupDS = 0;
1540 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1541 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1543 return aResGrp._retn();
1546 size_t i, nb = toolGroupVec.size();
1547 SMDS_ElemIteratorPtr mainElemIt
1548 ( new SMDS_IteratorOnIterators
1549 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1550 while ( mainElemIt->more() )
1552 const SMDS_MeshElement* e = mainElemIt->next();
1554 for ( i = 0; ( i < nb && !isIn ); ++i )
1555 isIn = toolGroupVec[i]->Contains( e );
1558 resGroupDS->SMDSGroup().Add( e );
1561 // Update Python script
1562 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1563 << ".CutListOfGroups( " << theMainGroups << ", "
1564 << theToolGroups << ", '" << theName << "' )";
1566 SMESH_CATCH( SMESH::throwCorbaException );
1568 return aResGrp._retn();
1571 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1573 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1574 bool & toStopChecking )
1576 toStopChecking = ( nbCommon < nbChecked );
1577 return nbCommon == nbNodes;
1579 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1580 bool & toStopChecking )
1582 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1583 return nbCommon == nbCorners;
1585 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1586 bool & toStopChecking )
1588 return nbCommon > 0;
1590 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1591 bool & toStopChecking )
1593 return nbCommon >= nbNodes / 2;
1597 //=============================================================================
1599 * Create a group of entities basing on nodes of other groups.
1600 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1601 * \param [in] anElemType - a type of elements to include to the new group.
1602 * \param [in] theName - a name of the new group.
1603 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1604 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1605 * new group provided that it is based on nodes of an element of \a aListOfGroups
1606 * \return SMESH_Group - the created group
1608 // IMP 19939, bug 22010, IMP 22635
1609 //=============================================================================
1611 SMESH::SMESH_Group_ptr
1612 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1613 SMESH::ElementType theElemType,
1614 const char* theName,
1615 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1616 CORBA::Boolean theUnderlyingOnly)
1617 throw (SALOME::SALOME_Exception)
1619 SMESH::SMESH_Group_var aResGrp;
1623 _preMeshInfo->FullLoadFromFile();
1625 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1627 if ( !theName || !aMeshDS )
1628 return SMESH::SMESH_Group::_nil();
1630 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1632 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1633 SMESH_Comment nbCoNoStr( "SMESH.");
1634 switch ( theNbCommonNodes ) {
1635 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1636 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1637 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1638 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1639 default: return aResGrp._retn();
1641 int nbChecked, nbCommon, nbNodes, nbCorners;
1647 aResGrp = CreateGroup( theElemType, theName );
1648 if ( aResGrp->_is_nil() )
1649 return SMESH::SMESH_Group::_nil();
1651 SMESHDS_GroupBase* groupBaseDS =
1652 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1653 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1655 vector<bool> isNodeInGroups;
1657 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1659 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1660 if ( CORBA::is_nil( aGrp ) )
1662 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1663 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1666 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1667 if ( !elIt ) continue;
1669 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1671 while ( elIt->more() ) {
1672 const SMDS_MeshElement* el = elIt->next();
1673 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1674 while ( nIt->more() )
1675 resGroupCore.Add( nIt->next() );
1678 // get elements of theElemType based on nodes of every element of group
1679 else if ( theUnderlyingOnly )
1681 while ( elIt->more() )
1683 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1684 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1685 TIDSortedElemSet checkedElems;
1686 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1687 while ( nIt->more() )
1689 const SMDS_MeshNode* n = nIt->next();
1690 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1691 // check nodes of elements of theElemType around el
1692 while ( elOfTypeIt->more() )
1694 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1695 if ( !checkedElems.insert( elOfType ).second ) continue;
1696 nbNodes = elOfType->NbNodes();
1697 nbCorners = elOfType->NbCornerNodes();
1699 bool toStopChecking = false;
1700 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1701 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1702 if ( elNodes.count( nIt2->next() ) &&
1703 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1705 resGroupCore.Add( elOfType );
1712 // get all nodes of elements of groups
1715 while ( elIt->more() )
1717 const SMDS_MeshElement* el = elIt->next(); // an element of group
1718 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1719 while ( nIt->more() )
1721 const SMDS_MeshNode* n = nIt->next();
1722 if ( n->GetID() >= isNodeInGroups.size() )
1723 isNodeInGroups.resize( n->GetID() + 1, false );
1724 isNodeInGroups[ n->GetID() ] = true;
1730 // Get elements of theElemType based on a certain number of nodes of elements of groups
1731 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1733 const SMDS_MeshNode* n;
1734 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1735 const int isNodeInGroupsSize = isNodeInGroups.size();
1736 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1738 if ( !isNodeInGroups[ iN ] ||
1739 !( n = aMeshDS->FindNode( iN )))
1742 // check nodes of elements of theElemType around n
1743 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1744 while ( elOfTypeIt->more() )
1746 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1747 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1752 nbNodes = elOfType->NbNodes();
1753 nbCorners = elOfType->NbCornerNodes();
1755 bool toStopChecking = false;
1756 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1757 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1759 const int nID = nIt->next()->GetID();
1760 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1761 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1763 resGroupCore.Add( elOfType );
1771 // Update Python script
1772 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1773 << ".CreateDimGroup( "
1774 << theGroups << ", " << theElemType << ", '" << theName << "', "
1775 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1777 SMESH_CATCH( SMESH::throwCorbaException );
1779 return aResGrp._retn();
1782 //================================================================================
1784 * \brief Remember GEOM group data
1786 //================================================================================
1788 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1789 CORBA::Object_ptr theSmeshObj)
1791 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1794 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1795 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1796 if ( groupSO->_is_nil() )
1799 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1800 GEOM::GEOM_IGroupOperations_wrap groupOp =
1801 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1802 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1805 _geomGroupData.push_back( TGeomGroupData() );
1806 TGeomGroupData & groupData = _geomGroupData.back();
1808 CORBA::String_var entry = groupSO->GetID();
1809 groupData._groupEntry = entry.in();
1811 for ( int i = 0; i < ids->length(); ++i )
1812 groupData._indices.insert( ids[i] );
1814 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1815 // shape index in SMESHDS
1816 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1817 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1820 //================================================================================
1822 * Remove GEOM group data relating to removed smesh object
1824 //================================================================================
1826 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1828 list<TGeomGroupData>::iterator
1829 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1830 for ( ; data != dataEnd; ++data ) {
1831 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1832 _geomGroupData.erase( data );
1838 //================================================================================
1840 * \brief Return new group contents if it has been changed and update group data
1842 //================================================================================
1844 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1846 TopoDS_Shape newShape;
1849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1850 if ( study->_is_nil() ) return newShape; // means "not changed"
1851 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1852 if ( !groupSO->_is_nil() )
1854 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1855 if ( CORBA::is_nil( groupObj )) return newShape;
1856 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1858 // get indices of group items
1859 set<int> curIndices;
1860 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1861 GEOM::GEOM_IGroupOperations_wrap groupOp =
1862 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1863 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1864 for ( int i = 0; i < ids->length(); ++i )
1865 curIndices.insert( ids[i] );
1867 if ( groupData._indices == curIndices )
1868 return newShape; // group not changed
1871 groupData._indices = curIndices;
1873 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1874 if ( !geomClient ) return newShape;
1875 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1876 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1877 newShape = _gen_i->GeomObjectToShape( geomGroup );
1880 if ( newShape.IsNull() ) {
1881 // geom group becomes empty - return empty compound
1882 TopoDS_Compound compound;
1883 BRep_Builder().MakeCompound(compound);
1884 newShape = compound;
1891 //-----------------------------------------------------------------------------
1893 * \brief Storage of shape and index used in CheckGeomGroupModif()
1895 struct TIndexedShape
1898 TopoDS_Shape _shape;
1899 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1901 //-----------------------------------------------------------------------------
1903 * \brief Data to re-create a group on geometry
1905 struct TGroupOnGeomData
1909 SMDSAbs_ElementType _type;
1911 Quantity_Color _color;
1915 //=============================================================================
1917 * \brief Update data if geometry changes
1921 //=============================================================================
1923 void SMESH_Mesh_i::CheckGeomModif()
1925 if ( !_impl->HasShapeToMesh() ) return;
1927 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1928 if ( study->_is_nil() ) return;
1930 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1931 if ( mainGO->_is_nil() ) return;
1933 if ( mainGO->GetType() == GEOM_GROUP ||
1934 mainGO->GetTick() == _mainShapeTick )
1936 CheckGeomGroupModif();
1940 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1941 if ( !geomClient ) return;
1942 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1943 if ( geomGen->_is_nil() ) return;
1945 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1946 geomClient->RemoveShapeFromBuffer( ior.in() );
1948 // Update data taking into account that
1949 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1952 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1953 if ( newShape.IsNull() )
1956 _mainShapeTick = mainGO->GetTick();
1958 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1960 // store data of groups on geometry
1961 vector< TGroupOnGeomData > groupsData;
1962 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1963 groupsData.reserve( groups.size() );
1964 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1965 for ( ; g != groups.end(); ++g )
1966 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1968 TGroupOnGeomData data;
1969 data._oldID = group->GetID();
1970 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1971 data._type = group->GetType();
1972 data._name = group->GetStoreName();
1973 data._color = group->GetColor();
1974 groupsData.push_back( data );
1976 // store assigned hypotheses
1977 vector< pair< int, THypList > > ids2Hyps;
1978 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1979 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1981 const TopoDS_Shape& s = s2hyps.Key();
1982 const THypList& hyps = s2hyps.ChangeValue();
1983 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1986 // change shape to mesh
1987 int oldNbSubShapes = meshDS->MaxShapeIndex();
1988 _impl->ShapeToMesh( TopoDS_Shape() );
1989 _impl->ShapeToMesh( newShape );
1991 // re-add shapes of geom groups
1992 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1993 for ( ; data != _geomGroupData.end(); ++data )
1995 TopoDS_Shape newShape = newGroupShape( *data );
1996 if ( !newShape.IsNull() )
1998 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2000 TopoDS_Compound compound;
2001 BRep_Builder().MakeCompound( compound );
2002 BRep_Builder().Add( compound, newShape );
2003 newShape = compound;
2005 _impl->GetSubMesh( newShape );
2008 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2009 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2010 SALOME::INTERNAL_ERROR );
2012 // re-assign hypotheses
2013 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2015 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2016 const THypList& hyps = ids2Hyps[i].second;
2017 THypList::const_iterator h = hyps.begin();
2018 for ( ; h != hyps.end(); ++h )
2019 _impl->AddHypothesis( s, (*h)->GetID() );
2023 for ( size_t i = 0; i < groupsData.size(); ++i )
2025 const TGroupOnGeomData& data = groupsData[i];
2027 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2028 if ( i2g == _mapGroups.end() ) continue;
2030 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2031 if ( !gr_i ) continue;
2034 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2035 meshDS->IndexToShape( data._shapeID ));
2038 _mapGroups.erase( i2g );
2042 g->GetGroupDS()->SetColor( data._color );
2043 gr_i->changeLocalId( id );
2044 _mapGroups[ id ] = i2g->second;
2045 if ( data._oldID != id )
2046 _mapGroups.erase( i2g );
2050 // update _mapSubMesh
2051 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2052 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2053 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2057 //=============================================================================
2059 * \brief Update objects depending on changed geom groups
2061 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2062 * issue 0020210: Update of a smesh group after modification of the associated geom group
2064 //=============================================================================
2066 void SMESH_Mesh_i::CheckGeomGroupModif()
2068 if ( !_impl->HasShapeToMesh() ) return;
2070 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2071 if ( study->_is_nil() ) return;
2073 CORBA::Long nbEntities = NbNodes() + NbElements();
2075 // Check if group contents changed
2077 typedef map< string, TopoDS_Shape > TEntry2Geom;
2078 TEntry2Geom newGroupContents;
2080 list<TGeomGroupData>::iterator
2081 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2082 for ( ; data != dataEnd; ++data )
2084 pair< TEntry2Geom::iterator, bool > it_new =
2085 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2086 bool processedGroup = !it_new.second;
2087 TopoDS_Shape& newShape = it_new.first->second;
2088 if ( !processedGroup )
2089 newShape = newGroupShape( *data );
2090 if ( newShape.IsNull() )
2091 continue; // no changes
2094 _preMeshInfo->ForgetOrLoad();
2096 if ( processedGroup ) { // update group indices
2097 list<TGeomGroupData>::iterator data2 = data;
2098 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2099 data->_indices = data2->_indices;
2102 // Update SMESH objects according to new GEOM group contents
2104 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2105 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2107 int oldID = submesh->GetId();
2108 if ( !_mapSubMeshIor.count( oldID ))
2110 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2112 // update hypotheses
2113 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2114 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2115 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2117 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2118 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2120 // care of submeshes
2121 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2122 int newID = newSubmesh->GetId();
2123 if ( newID != oldID ) {
2124 _mapSubMesh [ newID ] = newSubmesh;
2125 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2126 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2127 _mapSubMesh. erase(oldID);
2128 _mapSubMesh_i. erase(oldID);
2129 _mapSubMeshIor.erase(oldID);
2130 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2135 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2136 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2137 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2139 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2141 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2142 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2143 ds->SetShape( newShape );
2148 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2149 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2151 // Remove groups and submeshes basing on removed sub-shapes
2153 TopTools_MapOfShape newShapeMap;
2154 TopoDS_Iterator shapeIt( newShape );
2155 for ( ; shapeIt.More(); shapeIt.Next() )
2156 newShapeMap.Add( shapeIt.Value() );
2158 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2159 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2161 if ( newShapeMap.Contains( shapeIt.Value() ))
2163 TopTools_IndexedMapOfShape oldShapeMap;
2164 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2165 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2167 const TopoDS_Shape& oldShape = oldShapeMap(i);
2168 int oldInd = meshDS->ShapeToIndex( oldShape );
2170 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2171 if ( i_smIor != _mapSubMeshIor.end() ) {
2172 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2175 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2176 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2178 // check if a group bases on oldInd shape
2179 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2180 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2181 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2182 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2184 RemoveGroup( i_grp->second ); // several groups can base on same shape
2185 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2190 // Reassign hypotheses and update groups after setting the new shape to mesh
2192 // collect anassigned hypotheses
2193 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2194 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2195 TShapeHypList assignedHyps;
2196 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2198 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2199 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2200 if ( !hyps.empty() ) {
2201 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2202 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2203 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2206 // collect shapes supporting groups
2207 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2208 TShapeTypeList groupData;
2209 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2210 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2211 for ( ; grIt != groups.end(); ++grIt )
2213 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2215 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2217 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2218 _impl->ShapeToMesh( newShape );
2220 // reassign hypotheses
2221 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2222 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2224 TIndexedShape& geom = indS_hyps->first;
2225 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2226 int oldID = geom._index;
2227 int newID = meshDS->ShapeToIndex( geom._shape );
2228 if ( oldID == 1 ) { // main shape
2230 geom._shape = newShape;
2234 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2235 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2236 // care of submeshes
2237 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2238 if ( newID != oldID ) {
2239 _mapSubMesh [ newID ] = newSubmesh;
2240 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2241 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2242 _mapSubMesh. erase(oldID);
2243 _mapSubMesh_i. erase(oldID);
2244 _mapSubMeshIor.erase(oldID);
2245 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2249 TShapeTypeList::iterator geomType = groupData.begin();
2250 for ( ; geomType != groupData.end(); ++geomType )
2252 const TIndexedShape& geom = geomType->first;
2253 int oldID = geom._index;
2254 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2257 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2258 CORBA::String_var name = groupSO->GetName();
2260 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2262 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2263 group_i->changeLocalId( newID );
2266 break; // everything has been updated
2269 } // loop on group data
2273 CORBA::Long newNbEntities = NbNodes() + NbElements();
2274 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2275 if ( newNbEntities != nbEntities )
2277 // Add all SObjects with icons to soToUpdateIcons
2278 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2280 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2281 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2282 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2284 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2285 i_gr != _mapGroups.end(); ++i_gr ) // groups
2286 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2289 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2290 for ( ; so != soToUpdateIcons.end(); ++so )
2291 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2294 //=============================================================================
2296 * \brief Create standalone group from a group on geometry or filter
2298 //=============================================================================
2300 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2301 throw (SALOME::SALOME_Exception)
2303 SMESH::SMESH_Group_var aGroup;
2308 _preMeshInfo->FullLoadFromFile();
2310 if ( theGroup->_is_nil() )
2311 return aGroup._retn();
2313 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2315 return aGroup._retn();
2317 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2319 const int anId = aGroupToRem->GetLocalID();
2320 if ( !_impl->ConvertToStandalone( anId ) )
2321 return aGroup._retn();
2322 removeGeomGroupData( theGroup );
2324 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2326 // remove old instance of group from own map
2327 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2328 _mapGroups.erase( anId );
2330 SALOMEDS::StudyBuilder_var builder;
2331 SALOMEDS::SObject_wrap aGroupSO;
2332 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2333 if ( !aStudy->_is_nil() ) {
2334 builder = aStudy->NewBuilder();
2335 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2336 if ( !aGroupSO->_is_nil() )
2338 // remove reference to geometry
2339 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2340 for ( ; chItr->More(); chItr->Next() )
2341 // Remove group's child SObject
2342 builder->RemoveObject( chItr->Value() );
2344 // Update Python script
2345 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2346 << ".ConvertToStandalone( " << aGroupSO << " )";
2348 // change icon of Group on Filter
2351 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2352 const int isEmpty = ( elemTypes->length() == 0 );
2355 SALOMEDS::GenericAttribute_wrap anAttr =
2356 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2357 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2358 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2364 // remember new group in own map
2365 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2366 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2368 // register CORBA object for persistence
2369 _gen_i->RegisterObject( aGroup );
2371 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2372 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2373 //aGroup->Register();
2374 aGroupToRem->UnRegister();
2376 SMESH_CATCH( SMESH::throwCorbaException );
2378 return aGroup._retn();
2381 //=============================================================================
2385 //=============================================================================
2387 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2389 if(MYDEBUG) MESSAGE( "createSubMesh" );
2390 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2391 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2392 const int subMeshId = mySubMesh->GetId();
2394 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2395 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2397 _mapSubMesh [subMeshId] = mySubMesh;
2398 _mapSubMesh_i [subMeshId] = subMeshServant;
2399 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2401 subMeshServant->Register();
2403 // register CORBA object for persistence
2404 int nextId = _gen_i->RegisterObject( subMesh );
2405 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2406 else { nextId = 0; } // avoid "unused variable" warning
2408 // to track changes of GEOM groups
2409 addGeomGroupData( theSubShapeObject, subMesh );
2411 return subMesh._retn();
2414 //=======================================================================
2415 //function : getSubMesh
2417 //=======================================================================
2419 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2421 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2422 if ( it == _mapSubMeshIor.end() )
2423 return SMESH::SMESH_subMesh::_nil();
2425 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2428 //=============================================================================
2432 //=============================================================================
2434 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2435 GEOM::GEOM_Object_ptr theSubShapeObject )
2437 bool isHypChanged = false;
2438 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2439 return isHypChanged;
2441 const int subMeshId = theSubMesh->GetId();
2443 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2445 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2447 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2450 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2451 isHypChanged = !hyps.empty();
2452 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2453 for ( ; hyp != hyps.end(); ++hyp )
2454 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2461 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2462 isHypChanged = ( aHypList->length() > 0 );
2463 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2464 removeHypothesis( theSubShapeObject, aHypList[i] );
2467 catch( const SALOME::SALOME_Exception& ) {
2468 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2470 removeGeomGroupData( theSubShapeObject );
2474 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2475 if ( id_smi != _mapSubMesh_i.end() )
2476 id_smi->second->UnRegister();
2478 // remove a CORBA object
2479 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2480 if ( id_smptr != _mapSubMeshIor.end() )
2481 SMESH::SMESH_subMesh_var( id_smptr->second );
2483 _mapSubMesh.erase(subMeshId);
2484 _mapSubMesh_i.erase(subMeshId);
2485 _mapSubMeshIor.erase(subMeshId);
2487 return isHypChanged;
2490 //=============================================================================
2494 //=============================================================================
2496 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2497 const char* theName,
2498 const TopoDS_Shape& theShape,
2499 const SMESH_PredicatePtr& thePredicate )
2501 std::string newName;
2502 if ( !theName || strlen( theName ) == 0 )
2504 std::set< std::string > presentNames;
2505 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2506 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2508 CORBA::String_var name = i_gr->second->GetName();
2509 presentNames.insert( name.in() );
2512 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2513 } while ( !presentNames.insert( newName ).second );
2514 theName = newName.c_str();
2517 SMESH::SMESH_GroupBase_var aGroup;
2518 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2520 SMESH_GroupBase_i* aGroupImpl;
2521 if ( !theShape.IsNull() )
2522 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2523 else if ( thePredicate )
2524 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2526 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2528 aGroup = aGroupImpl->_this();
2529 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2530 aGroupImpl->Register();
2532 // register CORBA object for persistence
2533 int nextId = _gen_i->RegisterObject( aGroup );
2534 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2535 else { nextId = 0; } // avoid "unused variable" warning in release mode
2537 // to track changes of GEOM groups
2538 if ( !theShape.IsNull() ) {
2539 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2540 addGeomGroupData( geom, aGroup );
2543 return aGroup._retn();
2546 //=============================================================================
2548 * SMESH_Mesh_i::removeGroup
2550 * Should be called by ~SMESH_Group_i()
2552 //=============================================================================
2554 void SMESH_Mesh_i::removeGroup( const int theId )
2556 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2557 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2558 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2559 _mapGroups.erase( theId );
2560 removeGeomGroupData( group );
2561 if ( !_impl->RemoveGroup( theId ))
2563 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2564 RemoveGroup( group );
2566 group->UnRegister();
2570 //=============================================================================
2574 //=============================================================================
2576 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2577 throw(SALOME::SALOME_Exception)
2579 SMESH::log_array_var aLog;
2583 _preMeshInfo->FullLoadFromFile();
2585 list < SMESHDS_Command * >logDS = _impl->GetLog();
2586 aLog = new SMESH::log_array;
2588 int lg = logDS.size();
2591 list < SMESHDS_Command * >::iterator its = logDS.begin();
2592 while(its != logDS.end()){
2593 SMESHDS_Command *com = *its;
2594 int comType = com->GetType();
2596 int lgcom = com->GetNumber();
2598 const list < int >&intList = com->GetIndexes();
2599 int inum = intList.size();
2601 list < int >::const_iterator ii = intList.begin();
2602 const list < double >&coordList = com->GetCoords();
2603 int rnum = coordList.size();
2605 list < double >::const_iterator ir = coordList.begin();
2606 aLog[indexLog].commandType = comType;
2607 aLog[indexLog].number = lgcom;
2608 aLog[indexLog].coords.length(rnum);
2609 aLog[indexLog].indexes.length(inum);
2610 for(int i = 0; i < rnum; i++){
2611 aLog[indexLog].coords[i] = *ir;
2612 //MESSAGE(" "<<i<<" "<<ir.Value());
2615 for(int i = 0; i < inum; i++){
2616 aLog[indexLog].indexes[i] = *ii;
2617 //MESSAGE(" "<<i<<" "<<ii.Value());
2626 SMESH_CATCH( SMESH::throwCorbaException );
2628 return aLog._retn();
2632 //=============================================================================
2636 //=============================================================================
2638 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2642 SMESH_CATCH( SMESH::throwCorbaException );
2645 //=============================================================================
2649 //=============================================================================
2651 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2656 //=============================================================================
2660 //=============================================================================
2662 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2667 //=============================================================================
2670 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2671 // issue 0020918: groups removal is caused by hyp modification
2672 // issue 0021208: to forget not loaded mesh data at hyp modification
2673 struct TCallUp_i : public SMESH_Mesh::TCallUp
2675 SMESH_Mesh_i* _mesh;
2676 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2677 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2678 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2679 virtual void Load () { _mesh->Load(); }
2683 //================================================================================
2685 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2687 //================================================================================
2689 void SMESH_Mesh_i::onHypothesisModified()
2692 _preMeshInfo->ForgetOrLoad();
2695 //=============================================================================
2699 //=============================================================================
2701 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2703 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2706 _impl->SetCallUp( new TCallUp_i(this));
2709 //=============================================================================
2713 //=============================================================================
2715 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2717 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2721 //=============================================================================
2723 * Return mesh editor
2725 //=============================================================================
2727 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2728 throw (SALOME::SALOME_Exception)
2730 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2734 _preMeshInfo->FullLoadFromFile();
2736 // Create MeshEditor
2738 _editor = new SMESH_MeshEditor_i( this, false );
2739 aMeshEdVar = _editor->_this();
2741 // Update Python script
2742 TPythonDump() << _editor << " = "
2743 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2745 SMESH_CATCH( SMESH::throwCorbaException );
2747 return aMeshEdVar._retn();
2750 //=============================================================================
2752 * Return mesh edition previewer
2754 //=============================================================================
2756 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2757 throw (SALOME::SALOME_Exception)
2759 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2763 _preMeshInfo->FullLoadFromFile();
2765 if ( !_previewEditor )
2766 _previewEditor = new SMESH_MeshEditor_i( this, true );
2767 aMeshEdVar = _previewEditor->_this();
2769 SMESH_CATCH( SMESH::throwCorbaException );
2771 return aMeshEdVar._retn();
2774 //================================================================================
2776 * \brief Return true if the mesh has been edited since a last total re-compute
2777 * and those modifications may prevent successful partial re-compute
2779 //================================================================================
2781 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2783 Unexpect aCatch(SALOME_SalomeException);
2784 return _impl->HasModificationsToDiscard();
2787 //================================================================================
2789 * \brief Returns a random unique color
2791 //================================================================================
2793 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2795 const int MAX_ATTEMPTS = 100;
2797 double tolerance = 0.5;
2798 SALOMEDS::Color col;
2802 // generate random color
2803 double red = (double)rand() / RAND_MAX;
2804 double green = (double)rand() / RAND_MAX;
2805 double blue = (double)rand() / RAND_MAX;
2806 // check existence in the list of the existing colors
2807 bool matched = false;
2808 std::list<SALOMEDS::Color>::const_iterator it;
2809 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2810 SALOMEDS::Color color = *it;
2811 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2812 matched = tol < tolerance;
2814 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2815 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2823 //=============================================================================
2825 * Sets auto-color mode. If it is on, groups get unique random colors
2827 //=============================================================================
2829 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2831 Unexpect aCatch(SALOME_SalomeException);
2832 _impl->SetAutoColor(theAutoColor);
2834 TPythonDump pyDump; // not to dump group->SetColor() from below code
2835 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2837 std::list<SALOMEDS::Color> aReservedColors;
2838 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2839 for ( ; it != _mapGroups.end(); it++ ) {
2840 if ( CORBA::is_nil( it->second )) continue;
2841 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2842 it->second->SetColor( aColor );
2843 aReservedColors.push_back( aColor );
2847 //=============================================================================
2849 * Returns true if auto-color mode is on
2851 //=============================================================================
2853 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2855 Unexpect aCatch(SALOME_SalomeException);
2856 return _impl->GetAutoColor();
2859 //=============================================================================
2861 * Checks if there are groups with equal names
2863 //=============================================================================
2865 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2867 return _impl->HasDuplicatedGroupNamesMED();
2870 //================================================================================
2872 * \brief Care of a file before exporting mesh into it
2874 //================================================================================
2876 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2878 SMESH_File aFile( file );
2880 if (aFile.exists()) {
2881 // existing filesystem node
2882 if ( !aFile.isDirectory() ) {
2883 if ( aFile.openForWriting() ) {
2884 if ( overwrite && ! aFile.remove()) {
2885 msg << "Can't replace " << aFile.getName();
2888 msg << "Can't write into " << aFile.getName();
2891 msg << "Location " << aFile.getName() << " is not a file";
2895 // nonexisting file; check if it can be created
2896 if ( !aFile.openForWriting() ) {
2897 msg << "You cannot create the file "
2899 << ". Check the directory existance and access rights";
2907 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2911 //================================================================================
2913 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2914 * \param file - file name
2915 * \param overwrite - to erase the file or not
2916 * \retval string - mesh name
2918 //================================================================================
2920 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2921 CORBA::Boolean overwrite)
2924 PrepareForWriting(file, overwrite);
2925 string aMeshName = "Mesh";
2926 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2927 if ( !aStudy->_is_nil() ) {
2928 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2929 if ( !aMeshSO->_is_nil() ) {
2930 CORBA::String_var name = aMeshSO->GetName();
2932 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2933 if ( !aStudy->GetProperties()->IsLocked() )
2935 SALOMEDS::GenericAttribute_wrap anAttr;
2936 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2937 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2938 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2939 ASSERT(!aFileName->_is_nil());
2940 aFileName->SetValue(file);
2941 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2942 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2943 ASSERT(!aFileType->_is_nil());
2944 aFileType->SetValue("FICHIERMED");
2948 // Update Python script
2949 // set name of mesh before export
2950 TPythonDump() << _gen_i << ".SetName("
2951 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2953 // check names of groups
2959 //================================================================================
2961 * \brief Export to med file
2963 //================================================================================
2965 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2966 CORBA::Boolean auto_groups,
2967 SMESH::MED_VERSION theVersion,
2968 CORBA::Boolean overwrite,
2969 CORBA::Boolean autoDimension)
2970 throw(SALOME::SALOME_Exception)
2974 _preMeshInfo->FullLoadFromFile();
2976 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2977 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2979 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2980 << file << "', " << auto_groups << ", "
2981 << theVersion << ", " << overwrite << ", "
2982 << autoDimension << " )";
2984 SMESH_CATCH( SMESH::throwCorbaException );
2987 //================================================================================
2989 * \brief Export a mesh to a med file
2991 //================================================================================
2993 void SMESH_Mesh_i::ExportToMED (const char* file,
2994 CORBA::Boolean auto_groups,
2995 SMESH::MED_VERSION theVersion)
2996 throw(SALOME::SALOME_Exception)
2998 ExportToMEDX(file,auto_groups,theVersion,true);
3001 //================================================================================
3003 * \brief Export a mesh to a med file
3005 //================================================================================
3007 void SMESH_Mesh_i::ExportMED (const char* file,
3008 CORBA::Boolean auto_groups)
3009 throw(SALOME::SALOME_Exception)
3011 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3014 //================================================================================
3016 * \brief Export a mesh to a SAUV file
3018 //================================================================================
3020 void SMESH_Mesh_i::ExportSAUV (const char* file,
3021 CORBA::Boolean auto_groups)
3022 throw(SALOME::SALOME_Exception)
3024 Unexpect aCatch(SALOME_SalomeException);
3026 _preMeshInfo->FullLoadFromFile();
3028 string aMeshName = prepareMeshNameAndGroups(file, true);
3029 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3030 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3031 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3035 //================================================================================
3037 * \brief Export a mesh to a DAT file
3039 //================================================================================
3041 void SMESH_Mesh_i::ExportDAT (const char *file)
3042 throw(SALOME::SALOME_Exception)
3044 Unexpect aCatch(SALOME_SalomeException);
3046 _preMeshInfo->FullLoadFromFile();
3048 // Update Python script
3049 // check names of groups
3051 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3054 PrepareForWriting(file);
3055 _impl->ExportDAT(file);
3058 //================================================================================
3060 * \brief Export a mesh to an UNV file
3062 //================================================================================
3064 void SMESH_Mesh_i::ExportUNV (const char *file)
3065 throw(SALOME::SALOME_Exception)
3067 Unexpect aCatch(SALOME_SalomeException);
3069 _preMeshInfo->FullLoadFromFile();
3071 // Update Python script
3072 // check names of groups
3074 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3077 PrepareForWriting(file);
3078 _impl->ExportUNV(file);
3081 //================================================================================
3083 * \brief Export a mesh to an STL file
3085 //================================================================================
3087 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3088 throw(SALOME::SALOME_Exception)
3090 Unexpect aCatch(SALOME_SalomeException);
3092 _preMeshInfo->FullLoadFromFile();
3094 // Update Python script
3095 // check names of groups
3097 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3098 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3101 PrepareForWriting(file);
3102 _impl->ExportSTL(file, isascii);
3105 //================================================================================
3107 * \brief Export a part of mesh to a med file
3109 //================================================================================
3111 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3113 CORBA::Boolean auto_groups,
3114 SMESH::MED_VERSION version,
3115 CORBA::Boolean overwrite,
3116 CORBA::Boolean autoDimension,
3117 const GEOM::ListOfFields& fields,
3118 const char* geomAssocFields)
3119 throw (SALOME::SALOME_Exception)
3123 _preMeshInfo->FullLoadFromFile();
3126 bool have0dField = false;
3127 if ( fields.length() > 0 )
3129 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3130 if ( shapeToMesh->_is_nil() )
3131 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3133 for ( size_t i = 0; i < fields.length(); ++i )
3135 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3136 THROW_SALOME_CORBA_EXCEPTION
3137 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3138 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3139 if ( fieldShape->_is_nil() )
3140 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3141 if ( !fieldShape->IsSame( shapeToMesh ) )
3142 THROW_SALOME_CORBA_EXCEPTION
3143 ( "Field defined not on shape", SALOME::BAD_PARAM);
3144 if ( fields[i]->GetDimension() == 0 )
3147 if ( geomAssocFields )
3148 for ( int i = 0; geomAssocFields[i]; ++i )
3149 switch ( geomAssocFields[i] ) {
3150 case 'v':case 'e':case 'f':case 's': break;
3151 case 'V':case 'E':case 'F':case 'S': break;
3152 default: THROW_SALOME_CORBA_EXCEPTION
3153 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3157 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3161 string aMeshName = "Mesh";
3162 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3163 if ( CORBA::is_nil( meshPart ) ||
3164 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3166 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3167 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3168 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3169 meshDS = _impl->GetMeshDS();
3174 _preMeshInfo->FullLoadFromFile();
3176 PrepareForWriting(file, overwrite);
3178 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3179 if ( !aStudy->_is_nil() ) {
3180 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3181 if ( !SO->_is_nil() ) {
3182 CORBA::String_var name = SO->GetName();
3186 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3187 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3188 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3189 meshDS = tmpDSDeleter._obj = partDS;
3194 if ( _impl->HasShapeToMesh() )
3196 DriverMED_W_Field fieldWriter;
3197 fieldWriter.SetFile( file );
3198 fieldWriter.SetMeshName( aMeshName );
3199 fieldWriter.AddODOnVertices( have0dField );
3201 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3205 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3206 goList->length( fields.length() );
3207 for ( size_t i = 0; i < fields.length(); ++i )
3209 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3212 TPythonDump() << _this() << ".ExportPartToMED( "
3213 << meshPart << ", r'" << file << "', "
3214 << auto_groups << ", " << version << ", " << overwrite << ", "
3215 << autoDimension << ", " << goList
3216 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3218 SMESH_CATCH( SMESH::throwCorbaException );
3221 //================================================================================
3223 * Write GEOM fields to MED file
3225 //================================================================================