1 // Copyright (C) 2007-2020 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_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
119 _previewEditor = NULL;
124 //=============================================================================
128 //=============================================================================
130 SMESH_Mesh_i::~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 cached shapes if no more meshes remain; (the cache 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 * Associate <this> mesh with <theShape> and put 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 //================================================================================
224 * \brief Return the shape to mesh
226 //================================================================================
228 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
229 throw (SALOME::SALOME_Exception)
231 Unexpect aCatch(SALOME_SalomeException);
232 GEOM::GEOM_Object_var aShapeObj;
234 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
237 aShapeObj = _gen_i->ShapeToGeomObject( S );
238 if ( aShapeObj->_is_nil() )
240 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
241 // find GEOM_Object by entry (IPAL52735)
242 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
243 for ( ; data != _geomGroupData.end(); ++data )
244 if ( data->_smeshObject->_is_equivalent( _this() ))
246 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
247 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
248 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
254 catch(SALOME_Exception & S_ex) {
255 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
257 return aShapeObj._retn();
260 //================================================================================
262 * \brief Return false if the mesh is not yet fully loaded from the study file
264 //================================================================================
266 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
268 Unexpect aCatch(SALOME_SalomeException);
269 return !_preMeshInfo;
272 //================================================================================
274 * \brief Load full mesh data from the study file
276 //================================================================================
278 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
280 Unexpect aCatch(SALOME_SalomeException);
282 _preMeshInfo->FullLoadFromFile();
285 //================================================================================
287 * \brief Remove all nodes and elements
289 //================================================================================
291 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
299 //CheckGeomGroupModif(); // issue 20145
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
307 SMESH::SMESH_Mesh_var mesh = _this();
308 _gen_i->UpdateIcons( mesh );
311 //================================================================================
313 * \brief Remove all nodes and elements for indicated shape
315 //================================================================================
317 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
318 throw (SALOME::SALOME_Exception)
320 Unexpect aCatch(SALOME_SalomeException);
322 _preMeshInfo->FullLoadFromFile();
325 _impl->ClearSubMesh( ShapeID );
327 catch(SALOME_Exception & S_ex) {
328 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
330 _impl->GetMeshDS()->Modified();
332 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
335 //=============================================================================
337 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
339 //=============================================================================
341 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
343 SMESH::DriverMED_ReadStatus res;
346 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
347 res = SMESH::DRS_OK; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
349 res = SMESH::DRS_EMPTY; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
351 res = SMESH::DRS_WARN_RENUMBER; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
353 res = SMESH::DRS_WARN_SKIP_ELEM; break;
354 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
355 res = SMESH::DRS_WARN_DESCENDING; break;
356 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
358 res = SMESH::DRS_FAIL; break;
363 //=============================================================================
365 * Convert ::SMESH_ComputeError to SMESH::ComputeError
367 //=============================================================================
369 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
371 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
372 errVar->subShapeID = -1;
373 errVar->hasBadMesh = false;
375 if ( !errorPtr || errorPtr->IsOK() )
377 errVar->code = SMESH::COMPERR_OK;
381 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
382 errVar->comment = errorPtr->myComment.c_str();
384 return errVar._retn();
387 //=============================================================================
391 * Import mesh data from MED file
393 //=============================================================================
395 SMESH::DriverMED_ReadStatus
396 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
397 throw ( SALOME::SALOME_Exception )
399 Unexpect aCatch(SALOME_SalomeException);
402 status = _impl->MEDToMesh( theFileName, theMeshName );
404 catch( SALOME_Exception& S_ex ) {
405 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
408 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
411 CreateGroupServants();
413 int major, minor, release;
414 major = minor = release = 0;
415 MED::GetMEDVersion(theFileName, major, minor, release);
416 _medFileInfo = new SMESH::MedFileInfo();
417 _medFileInfo->fileName = theFileName;
418 _medFileInfo->fileSize = 0;
419 _medFileInfo->major = major;
420 _medFileInfo->minor = minor;
421 _medFileInfo->release = release;
422 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
424 return ConvertDriverMEDReadStatus(status);
427 //================================================================================
429 * \brief Import mesh data from the CGNS file
431 //================================================================================
433 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
434 const int theMeshIndex,
435 std::string& theMeshName )
436 throw ( SALOME::SALOME_Exception )
438 Unexpect aCatch(SALOME_SalomeException);
441 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
443 catch( SALOME_Exception& S_ex ) {
444 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
447 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
450 CreateGroupServants();
452 _medFileInfo = new SMESH::MedFileInfo();
453 _medFileInfo->fileName = theFileName;
454 _medFileInfo->major = 0;
455 _medFileInfo->minor = 0;
456 _medFileInfo->release = 0;
457 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
459 return ConvertDriverMEDReadStatus(status);
462 //================================================================================
464 * \brief Return string representation of a MED file version comprising nbDigits
466 //================================================================================
468 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
470 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
472 return CORBA::string_dup( ver.c_str() );
475 //================================================================================
477 * Return the list of med versions compatibles for write/append,
478 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
480 //================================================================================
482 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
484 SMESH::long_array_var aResult = new SMESH::long_array();
485 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
486 long nbver = mvok.size();
487 aResult->length( nbver );
488 for ( int i = 0; i < nbver; i++ )
489 aResult[i] = mvok[i];
490 return aResult._retn();
493 //=============================================================================
497 * Import mesh data from MED file
499 //=============================================================================
501 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
502 throw ( SALOME::SALOME_Exception )
506 // Read mesh with name = <theMeshName> into SMESH_Mesh
507 _impl->UNVToMesh( theFileName );
509 CreateGroupServants();
511 _medFileInfo = new SMESH::MedFileInfo();
512 _medFileInfo->fileName = theFileName;
513 _medFileInfo->major = 0;
514 _medFileInfo->minor = 0;
515 _medFileInfo->release = 0;
516 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
518 SMESH_CATCH( SMESH::throwCorbaException );
523 //=============================================================================
527 * Import mesh data from STL file
529 //=============================================================================
531 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
532 throw ( SALOME::SALOME_Exception )
536 // Read mesh with name = <theMeshName> into SMESH_Mesh
537 std::string name = _impl->STLToMesh( theFileName );
540 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
541 _gen_i->SetName( meshSO, name.c_str() );
543 _medFileInfo = new SMESH::MedFileInfo();
544 _medFileInfo->fileName = theFileName;
545 _medFileInfo->major = 0;
546 _medFileInfo->minor = 0;
547 _medFileInfo->release = 0;
548 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
550 SMESH_CATCH( SMESH::throwCorbaException );
555 //================================================================================
557 * \brief Function used in SMESH_CATCH by ImportGMFFile()
559 //================================================================================
563 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
565 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
569 //================================================================================
571 * \brief Import data from a GMF file and return an error description
573 //================================================================================
575 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
576 bool theMakeRequiredGroups )
577 throw (SALOME::SALOME_Exception)
579 SMESH_ComputeErrorPtr error;
582 #define SMESH_CAUGHT error =
585 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
587 _medFileInfo = new SMESH::MedFileInfo();
588 _medFileInfo->fileName = theFileName;
589 _medFileInfo->major = 0;
590 _medFileInfo->minor = 0;
591 _medFileInfo->release = 0;
592 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
594 SMESH_CATCH( exceptionToComputeError );
598 CreateGroupServants();
600 return ConvertComputeError( error );
603 //=============================================================================
605 * \brief Convert SMESH_Hypothesis::Hypothesis_Status into SMESH::Hypothesis_Status
607 //=============================================================================
609 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
611 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
612 (SMESH_Hypothesis::Hypothesis_Status theStatus)
615 RETURNCASE( HYP_OK );
616 RETURNCASE( HYP_MISSING );
617 RETURNCASE( HYP_CONCURRENT );
618 RETURNCASE( HYP_BAD_PARAMETER );
619 RETURNCASE( HYP_HIDDEN_ALGO );
620 RETURNCASE( HYP_HIDING_ALGO );
621 RETURNCASE( HYP_UNKNOWN_FATAL );
622 RETURNCASE( HYP_INCOMPATIBLE );
623 RETURNCASE( HYP_NOTCONFORM );
624 RETURNCASE( HYP_ALREADY_EXIST );
625 RETURNCASE( HYP_BAD_DIM );
626 RETURNCASE( HYP_BAD_SUBSHAPE );
627 RETURNCASE( HYP_BAD_GEOMETRY );
628 RETURNCASE( HYP_NEED_SHAPE );
629 RETURNCASE( HYP_INCOMPAT_HYPS );
632 return SMESH::HYP_UNKNOWN_FATAL;
635 //=============================================================================
639 * Call internal addHypothesis() and then add a reference to <anHyp> under
640 * the SObject actually having a reference to <aSubShape>.
641 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
643 //=============================================================================
645 SMESH::Hypothesis_Status
646 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
647 SMESH::SMESH_Hypothesis_ptr anHyp,
648 CORBA::String_out anErrorText)
649 throw(SALOME::SALOME_Exception)
651 Unexpect aCatch(SALOME_SalomeException);
653 const int prevNbMeshEnt = NbNodes() + NbElements();
656 _preMeshInfo->ForgetOrLoad();
659 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
660 anErrorText = error.c_str();
662 SMESH::SMESH_Mesh_var mesh( _this() );
663 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
665 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
667 //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
668 if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ )
669 _gen_i->UpdateIcons( mesh );
671 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
673 // Update Python script
674 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
675 << aSubShape << ", " << anHyp << " )";
677 return ConvertHypothesisStatus(status);
680 //================================================================================
682 * \brief Create a sub-mesh and add a hypothesis to it
684 //================================================================================
686 SMESH_Hypothesis::Hypothesis_Status
687 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
688 SMESH::SMESH_Hypothesis_ptr anHyp,
689 std::string* anErrorText)
691 if(MYDEBUG) MESSAGE("addHypothesis");
693 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
694 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
696 if (CORBA::is_nil( anHyp ))
697 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
699 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
702 TopoDS_Shape myLocSubShape;
703 //use PseudoShape in case if mesh has no shape
705 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
707 myLocSubShape = _impl->GetShapeToMesh();
709 const int hypId = anHyp->GetId();
711 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
712 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
714 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
716 // assure there is a corresponding submesh
717 if ( !_impl->IsMainShape( myLocSubShape )) {
718 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
719 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
720 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
723 else if ( anErrorText )
725 *anErrorText = error;
728 catch(SALOME_Exception & S_ex)
730 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
735 //================================================================================
737 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
739 //================================================================================
741 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
742 SMESH::SMESH_Hypothesis_ptr anHyp)
743 throw(SALOME::SALOME_Exception)
745 Unexpect aCatch(SALOME_SalomeException);
747 _preMeshInfo->ForgetOrLoad();
749 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
750 SMESH::SMESH_Mesh_var mesh = _this();
752 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
754 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
755 _gen_i->UpdateIcons( mesh );
757 // Update Python script
758 if(_impl->HasShapeToMesh())
759 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
760 << aSubShape << ", " << anHyp << " )";
762 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
765 return ConvertHypothesisStatus(status);
768 //=============================================================================
770 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
772 //=============================================================================
774 SMESH_Hypothesis::Hypothesis_Status
775 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
776 SMESH::SMESH_Hypothesis_ptr anHyp)
778 if(MYDEBUG) MESSAGE("removeHypothesis()");
780 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
781 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
783 if (CORBA::is_nil( anHyp ))
784 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
787 _preMeshInfo->ForgetOrLoad();
789 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
792 TopoDS_Shape myLocSubShape;
793 //use PseudoShape in case if mesh has no shape
794 if( _impl->HasShapeToMesh() )
795 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
797 myLocSubShape = _impl->GetShapeToMesh();
799 const int hypId = anHyp->GetId();
800 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
801 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
803 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
807 catch(SALOME_Exception & S_ex)
809 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
814 //================================================================================
816 * \brief Return hypotheses assigned to a given sub-shape
818 //================================================================================
820 SMESH::ListOfHypothesis *
821 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
822 throw(SALOME::SALOME_Exception)
824 Unexpect aCatch(SALOME_SalomeException);
825 if (MYDEBUG) MESSAGE("GetHypothesisList");
826 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
827 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
829 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
832 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
833 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
834 myLocSubShape = _impl->GetShapeToMesh();
835 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
836 int i = 0, n = aLocalList.size();
839 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
840 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
841 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
843 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
844 if ( id_hypptr != _mapHypo.end() )
845 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
849 catch(SALOME_Exception & S_ex) {
850 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
853 return aList._retn();
856 //================================================================================
858 * \brief Return sub-meshes
860 //================================================================================
862 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
864 Unexpect aCatch(SALOME_SalomeException);
865 if (MYDEBUG) MESSAGE("GetSubMeshes");
867 SMESH::submesh_array_var aList = new SMESH::submesh_array();
870 TPythonDump aPythonDump;
871 if ( !_mapSubMeshIor.empty() )
875 aList->length( _mapSubMeshIor.size() );
877 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
878 for ( ; it != _mapSubMeshIor.end(); it++ ) {
879 if ( CORBA::is_nil( it->second )) continue;
880 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
882 if (i > 1) aPythonDump << ", ";
883 aPythonDump << it->second;
887 catch(SALOME_Exception & S_ex) {
888 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
891 // Update Python script
892 if ( !_mapSubMeshIor.empty() )
893 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
895 return aList._retn();
898 //================================================================================
900 * \brief Create and return a sub-mesh on the given sub-shape
902 //================================================================================
904 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
905 const char* theName )
906 throw(SALOME::SALOME_Exception)
908 Unexpect aCatch(SALOME_SalomeException);
909 if (CORBA::is_nil(aSubShape))
910 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
912 SMESH::SMESH_subMesh_var subMesh;
913 SMESH::SMESH_Mesh_var aMesh = _this();
915 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
917 //Get or Create the SMESH_subMesh object implementation
919 TopoDS_Iterator it( myLocSubShape );
920 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
921 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
922 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
923 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
927 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
929 subMesh = getSubMesh( subMeshId );
931 // create a new subMesh object servant if there is none for the shape
932 if ( subMesh->_is_nil() )
933 subMesh = createSubMesh( aSubShape );
934 if ( _gen_i->CanPublishInStudy( subMesh ))
936 SALOMEDS::SObject_wrap aSO =
937 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
938 if ( !aSO->_is_nil()) {
939 // Update Python script
940 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
941 << aSubShape << ", '" << theName << "' )";
945 catch(SALOME_Exception & S_ex) {
946 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
948 return subMesh._retn();
951 //================================================================================
953 * \brief Remove a sub-mesh
955 //================================================================================
957 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
958 throw (SALOME::SALOME_Exception)
962 if ( theSubMesh->_is_nil() )
965 GEOM::GEOM_Object_var aSubShape;
966 // Remove submesh's SObject
967 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
968 if ( !anSO->_is_nil() ) {
969 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
970 SALOMEDS::SObject_wrap anObj, aRef;
971 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
972 anObj->ReferencedObject( aRef.inout() ))
974 CORBA::Object_var obj = aRef->GetObject();
975 aSubShape = GEOM::GEOM_Object::_narrow( obj );
977 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
978 // aSubShape = theSubMesh->GetSubShape();
980 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
981 builder->RemoveObjectWithChildren( anSO );
983 // Update Python script
984 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
987 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
989 _preMeshInfo->ForgetOrLoad();
991 SMESH_CATCH( SMESH::throwCorbaException );
994 //================================================================================
996 * \brief Create a standalone group
998 //================================================================================
1000 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1001 const char* theName )
1002 throw(SALOME::SALOME_Exception)
1004 Unexpect aCatch(SALOME_SalomeException);
1006 _preMeshInfo->FullLoadFromFile();
1008 SMESH::SMESH_Group_var aNewGroup =
1009 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1011 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1013 SMESH::SMESH_Mesh_var mesh = _this();
1014 SALOMEDS::SObject_wrap aSO =
1015 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1016 if ( !aSO->_is_nil())
1017 // Update Python script
1018 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1019 << theElemType << ", '" << theName << "' )";
1021 return aNewGroup._retn();
1024 //================================================================================
1026 * \brief Create a group based on the given geometry
1028 //================================================================================
1030 SMESH::SMESH_GroupOnGeom_ptr
1031 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1032 const char* theName,
1033 GEOM::GEOM_Object_ptr theGeomObj)
1034 throw(SALOME::SALOME_Exception)
1036 Unexpect aCatch(SALOME_SalomeException);
1038 _preMeshInfo->FullLoadFromFile();
1040 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1042 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1043 if ( !aShape.IsNull() )
1046 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1048 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1050 SMESH::SMESH_Mesh_var mesh = _this();
1051 SALOMEDS::SObject_wrap aSO =
1052 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1053 if ( !aSO->_is_nil())
1054 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1055 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1059 return aNewGroup._retn();
1062 //================================================================================
1064 * \brief Creates a group whose contents is defined by filter
1065 * \param theElemType - group type
1066 * \param theName - group name
1067 * \param theFilter - the filter
1068 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1070 //================================================================================
1072 SMESH::SMESH_GroupOnFilter_ptr
1073 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1074 const char* theName,
1075 SMESH::Filter_ptr theFilter )
1076 throw (SALOME::SALOME_Exception)
1078 Unexpect aCatch(SALOME_SalomeException);
1080 _preMeshInfo->FullLoadFromFile();
1082 if ( CORBA::is_nil( theFilter ))
1083 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1085 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1087 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1089 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1090 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1093 if ( !aNewGroup->_is_nil() )
1094 aNewGroup->SetFilter( theFilter );
1096 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1098 SMESH::SMESH_Mesh_var mesh = _this();
1099 SALOMEDS::SObject_wrap aSO =
1100 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1102 if ( !aSO->_is_nil())
1103 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1104 << theElemType << ", '" << theName << "', " << theFilter << " )";
1106 return aNewGroup._retn();
1109 //================================================================================
1111 * \brief Remove a group
1113 //================================================================================
1115 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1116 throw (SALOME::SALOME_Exception)
1118 if ( theGroup->_is_nil() )
1123 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1127 if ( aGroup->GetMeshServant() != this )
1128 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1129 SALOME::BAD_PARAM );
1131 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1132 if ( !aGroupSO->_is_nil() )
1134 // Update Python script
1135 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1137 // Remove group's SObject
1138 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1139 builder->RemoveObjectWithChildren( aGroupSO );
1141 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1143 // Remove the group from SMESH data structures
1144 removeGroup( aGroup->GetLocalID() );
1146 SMESH_CATCH( SMESH::throwCorbaException );
1149 //=============================================================================
1151 * Remove group with its contents
1153 //=============================================================================
1155 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1156 throw (SALOME::SALOME_Exception)
1160 _preMeshInfo->FullLoadFromFile();
1162 if ( theGroup->_is_nil() )
1165 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1166 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1167 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1170 vector<int> nodeIds; // to remove nodes becoming free
1171 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1172 if ( !isNodal && !theGroup->IsEmpty() )
1174 CORBA::Long elemID = theGroup->GetID( 1 );
1175 int nbElemNodes = GetElemNbNodes( elemID );
1176 if ( nbElemNodes > 0 )
1177 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1180 // Retrieve contents
1181 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1182 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1183 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1184 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1185 elems.assign( elemBeg, elemEnd );
1187 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1190 RemoveGroup( theGroup );
1193 for ( size_t i = 0; i < elems.size(); ++i )
1195 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1199 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1200 nodeIds.push_back( nIt->next()->GetID() );
1202 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1206 _impl->GetMeshDS()->RemoveElement( elems[i] );
1210 // Remove free nodes
1211 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1212 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1213 if ( n->NbInverseElements() == 0 )
1214 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1216 _impl->GetMeshDS()->Modified();
1217 _impl->SetIsModified( true );
1219 // Update Python script (theGroup must be alive for this)
1220 pyDump << SMESH::SMESH_Mesh_var(_this())
1221 << ".RemoveGroupWithContents( " << theGroup << " )";
1223 SMESH_CATCH( SMESH::throwCorbaException );
1226 //================================================================================
1228 * \brief Get the list of groups existing in the mesh
1229 * \retval SMESH::ListOfGroups * - list of groups
1231 //================================================================================
1233 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1235 Unexpect aCatch(SALOME_SalomeException);
1236 if (MYDEBUG) MESSAGE("GetGroups");
1238 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1241 TPythonDump aPythonDump;
1242 if ( !_mapGroups.empty() )
1244 aPythonDump << "[ ";
1246 aList->length( _mapGroups.size() );
1248 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1249 for ( ; it != _mapGroups.end(); it++ ) {
1250 if ( CORBA::is_nil( it->second )) continue;
1251 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1253 if (i > 1) aPythonDump << ", ";
1254 aPythonDump << it->second;
1258 catch(SALOME_Exception & S_ex) {
1259 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1261 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1263 return aList._retn();
1266 //=============================================================================
1268 * Get number of groups existing in the mesh
1270 //=============================================================================
1272 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1274 Unexpect aCatch(SALOME_SalomeException);
1275 return _mapGroups.size();
1278 //=============================================================================
1280 * New group including all mesh elements present in initial groups is created.
1282 //=============================================================================
1284 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1285 SMESH::SMESH_GroupBase_ptr theGroup2,
1286 const char* theName )
1287 throw (SALOME::SALOME_Exception)
1289 SMESH::SMESH_Group_var aResGrp;
1293 _preMeshInfo->FullLoadFromFile();
1295 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1296 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1298 if ( theGroup1->GetType() != theGroup2->GetType() )
1299 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1304 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1305 if ( aResGrp->_is_nil() )
1306 return SMESH::SMESH_Group::_nil();
1308 aResGrp->AddFrom( theGroup1 );
1309 aResGrp->AddFrom( theGroup2 );
1311 // Update Python script
1312 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1313 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1315 SMESH_CATCH( SMESH::throwCorbaException );
1317 return aResGrp._retn();
1320 //=============================================================================
1322 * \brief New group including all mesh elements present in initial groups is created.
1323 * \param theGroups list of groups
1324 * \param theName name of group to be created
1325 * \return pointer to the new group
1327 //=============================================================================
1329 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1330 const char* theName )
1331 throw (SALOME::SALOME_Exception)
1333 SMESH::SMESH_Group_var aResGrp;
1336 _preMeshInfo->FullLoadFromFile();
1339 return SMESH::SMESH_Group::_nil();
1344 SMESH::ElementType aType = SMESH::ALL;
1345 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1347 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1348 if ( CORBA::is_nil( aGrp ) )
1350 if ( aType == SMESH::ALL )
1351 aType = aGrp->GetType();
1352 else if ( aType != aGrp->GetType() )
1353 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1356 if ( aType == SMESH::ALL )
1357 return SMESH::SMESH_Group::_nil();
1362 aResGrp = CreateGroup( aType, theName );
1363 if ( aResGrp->_is_nil() )
1364 return SMESH::SMESH_Group::_nil();
1366 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1367 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1369 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1370 if ( !CORBA::is_nil( aGrp ) )
1372 aResGrp->AddFrom( aGrp );
1373 if ( g > 0 ) pyDump << ", ";
1377 pyDump << " ], '" << theName << "' )";
1379 SMESH_CATCH( SMESH::throwCorbaException );
1381 return aResGrp._retn();
1384 //=============================================================================
1386 * New group is created. All mesh elements that are
1387 * present in both initial groups are added to the new one.
1389 //=============================================================================
1391 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1392 SMESH::SMESH_GroupBase_ptr theGroup2,
1393 const char* theName )
1394 throw (SALOME::SALOME_Exception)
1396 SMESH::SMESH_Group_var aResGrp;
1401 _preMeshInfo->FullLoadFromFile();
1403 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1404 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1406 if ( theGroup1->GetType() != theGroup2->GetType() )
1407 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1411 // Create Intersection
1412 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1413 if ( aResGrp->_is_nil() )
1414 return aResGrp._retn();
1416 SMESHDS_GroupBase* groupDS1 = 0;
1417 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1418 groupDS1 = grp_i->GetGroupDS();
1420 SMESHDS_GroupBase* groupDS2 = 0;
1421 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1422 groupDS2 = grp_i->GetGroupDS();
1424 SMESHDS_Group* resGroupDS = 0;
1425 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1426 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1428 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1430 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1431 while ( elemIt1->more() )
1433 const SMDS_MeshElement* e = elemIt1->next();
1434 if ( groupDS2->Contains( e ))
1435 resGroupDS->SMDSGroup().Add( e );
1438 // Update Python script
1439 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1440 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1442 SMESH_CATCH( SMESH::throwCorbaException );
1444 return aResGrp._retn();
1447 //=============================================================================
1449 \brief Intersect list of groups. New group is created. All mesh elements that
1450 are present in all initial groups simultaneously are added to the new one.
1451 \param theGroups list of groups
1452 \param theName name of group to be created
1453 \return pointer on the group
1455 //=============================================================================
1457 SMESH::SMESH_Group_ptr
1458 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1459 const char* theName )
1460 throw (SALOME::SALOME_Exception)
1462 SMESH::SMESH_Group_var aResGrp;
1467 _preMeshInfo->FullLoadFromFile();
1470 return SMESH::SMESH_Group::_nil();
1472 // check types and get SMESHDS_GroupBase's
1473 SMESH::ElementType aType = SMESH::ALL;
1474 vector< SMESHDS_GroupBase* > groupVec;
1475 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1477 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1478 if ( CORBA::is_nil( aGrp ) )
1480 if ( aType == SMESH::ALL )
1481 aType = aGrp->GetType();
1482 else if ( aType != aGrp->GetType() )
1483 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1486 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1487 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1489 if ( grpDS->IsEmpty() )
1494 groupVec.push_back( grpDS );
1497 if ( aType == SMESH::ALL ) // all groups are nil
1498 return SMESH::SMESH_Group::_nil();
1503 aResGrp = CreateGroup( aType, theName );
1505 SMESHDS_Group* resGroupDS = 0;
1506 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1507 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1508 if ( !resGroupDS || groupVec.empty() )
1509 return aResGrp._retn();
1512 size_t i, nb = groupVec.size();
1513 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1514 while ( elemIt1->more() )
1516 const SMDS_MeshElement* e = elemIt1->next();
1518 for ( i = 1; ( i < nb && inAll ); ++i )
1519 inAll = groupVec[i]->Contains( e );
1522 resGroupDS->SMDSGroup().Add( e );
1525 // Update Python script
1526 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1527 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1529 SMESH_CATCH( SMESH::throwCorbaException );
1531 return aResGrp._retn();
1534 //=============================================================================
1536 * New group is created. All mesh elements that are present in
1537 * a main group but is not present in a tool group are added to the new one
1539 //=============================================================================
1541 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1542 SMESH::SMESH_GroupBase_ptr theGroup2,
1543 const char* theName )
1544 throw (SALOME::SALOME_Exception)
1546 SMESH::SMESH_Group_var aResGrp;
1551 _preMeshInfo->FullLoadFromFile();
1553 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1556 if ( theGroup1->GetType() != theGroup2->GetType() )
1557 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1561 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1562 if ( aResGrp->_is_nil() )
1563 return aResGrp._retn();
1565 SMESHDS_GroupBase* groupDS1 = 0;
1566 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1567 groupDS1 = grp_i->GetGroupDS();
1569 SMESHDS_GroupBase* groupDS2 = 0;
1570 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1571 groupDS2 = grp_i->GetGroupDS();
1573 SMESHDS_Group* resGroupDS = 0;
1574 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1575 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1577 if ( groupDS1 && groupDS2 && resGroupDS )
1579 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1580 while ( elemIt1->more() )
1582 const SMDS_MeshElement* e = elemIt1->next();
1583 if ( !groupDS2->Contains( e ))
1584 resGroupDS->SMDSGroup().Add( e );
1587 // Update Python script
1588 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1589 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1591 SMESH_CATCH( SMESH::throwCorbaException );
1593 return aResGrp._retn();
1596 //=============================================================================
1598 \brief Cut lists of groups. New group is created. All mesh elements that are
1599 present in main groups but do not present in tool groups are added to the new one
1600 \param theMainGroups list of main groups
1601 \param theToolGroups list of tool groups
1602 \param theName name of group to be created
1603 \return pointer on the group
1605 //=============================================================================
1607 SMESH::SMESH_Group_ptr
1608 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1609 const SMESH::ListOfGroups& theToolGroups,
1610 const char* theName )
1611 throw (SALOME::SALOME_Exception)
1613 SMESH::SMESH_Group_var aResGrp;
1618 _preMeshInfo->FullLoadFromFile();
1621 return SMESH::SMESH_Group::_nil();
1623 // check types and get SMESHDS_GroupBase's
1624 SMESH::ElementType aType = SMESH::ALL;
1625 vector< SMESHDS_GroupBase* > toolGroupVec;
1626 vector< SMDS_ElemIteratorPtr > mainIterVec;
1628 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1630 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1631 if ( CORBA::is_nil( aGrp ) )
1633 if ( aType == SMESH::ALL )
1634 aType = aGrp->GetType();
1635 else if ( aType != aGrp->GetType() )
1636 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1638 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1639 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1640 if ( !grpDS->IsEmpty() )
1641 mainIterVec.push_back( grpDS->GetElements() );
1643 if ( aType == SMESH::ALL ) // all main groups are nil
1644 return SMESH::SMESH_Group::_nil();
1645 if ( mainIterVec.empty() ) // all main groups are empty
1646 return aResGrp._retn();
1648 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1650 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1651 if ( CORBA::is_nil( aGrp ) )
1653 if ( aType != aGrp->GetType() )
1654 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1656 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1657 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1658 toolGroupVec.push_back( grpDS );
1664 aResGrp = CreateGroup( aType, theName );
1666 SMESHDS_Group* resGroupDS = 0;
1667 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1668 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1670 return aResGrp._retn();
1673 size_t i, nb = toolGroupVec.size();
1674 SMDS_ElemIteratorPtr mainElemIt
1675 ( new SMDS_IteratorOnIterators
1676 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1677 while ( mainElemIt->more() )
1679 const SMDS_MeshElement* e = mainElemIt->next();
1681 for ( i = 0; ( i < nb && !isIn ); ++i )
1682 isIn = toolGroupVec[i]->Contains( e );
1685 resGroupDS->SMDSGroup().Add( e );
1688 // Update Python script
1689 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1690 << ".CutListOfGroups( " << theMainGroups << ", "
1691 << theToolGroups << ", '" << theName << "' )";
1693 SMESH_CATCH( SMESH::throwCorbaException );
1695 return aResGrp._retn();
1698 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1700 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1701 bool & toStopChecking )
1703 toStopChecking = ( nbCommon < nbChecked );
1704 return nbCommon == nbNodes;
1706 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1707 bool & toStopChecking )
1709 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1710 return nbCommon == nbCorners;
1712 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1713 bool & toStopChecking )
1715 return nbCommon > 0;
1717 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1718 bool & toStopChecking )
1720 return nbCommon >= (nbNodes+1) / 2;
1724 //=============================================================================
1726 * Create a group of entities basing on nodes of other groups.
1727 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1728 * \param [in] anElemType - a type of elements to include to the new group.
1729 * \param [in] theName - a name of the new group.
1730 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1731 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1732 * new group provided that it is based on nodes of an element of \a aListOfGroups
1733 * \return SMESH_Group - the created group
1735 // IMP 19939, bug 22010, IMP 22635
1736 //=============================================================================
1738 SMESH::SMESH_Group_ptr
1739 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1740 SMESH::ElementType theElemType,
1741 const char* theName,
1742 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1743 CORBA::Boolean theUnderlyingOnly)
1744 throw (SALOME::SALOME_Exception)
1746 SMESH::SMESH_Group_var aResGrp;
1750 _preMeshInfo->FullLoadFromFile();
1752 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1754 if ( !theName || !aMeshDS )
1755 return SMESH::SMESH_Group::_nil();
1757 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1759 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1760 SMESH_Comment nbCoNoStr( "SMESH.");
1761 switch ( theNbCommonNodes ) {
1762 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1763 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1764 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1765 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1766 default: return aResGrp._retn();
1768 int nbChecked, nbCommon, nbNodes, nbCorners;
1774 aResGrp = CreateGroup( theElemType, theName );
1775 if ( aResGrp->_is_nil() )
1776 return SMESH::SMESH_Group::_nil();
1778 SMESHDS_GroupBase* groupBaseDS =
1779 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1780 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1782 vector<bool> isNodeInGroups;
1784 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1786 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1787 if ( CORBA::is_nil( aGrp ) )
1789 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1790 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1793 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1794 if ( !elIt ) continue;
1796 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1798 while ( elIt->more() ) {
1799 const SMDS_MeshElement* el = elIt->next();
1800 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1801 while ( nIt->more() )
1802 resGroupCore.Add( nIt->next() );
1805 // get elements of theElemType based on nodes of every element of group
1806 else if ( theUnderlyingOnly )
1808 while ( elIt->more() )
1810 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1811 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1812 TIDSortedElemSet checkedElems;
1813 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1814 while ( nIt->more() )
1816 const SMDS_MeshNode* n = nIt->next();
1817 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1818 // check nodes of elements of theElemType around el
1819 while ( elOfTypeIt->more() )
1821 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1822 if ( !checkedElems.insert( elOfType ).second ) continue;
1823 nbNodes = elOfType->NbNodes();
1824 nbCorners = elOfType->NbCornerNodes();
1826 bool toStopChecking = false;
1827 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1828 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1829 if ( elNodes.count( nIt2->next() ) &&
1830 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1832 resGroupCore.Add( elOfType );
1839 // get all nodes of elements of groups
1842 while ( elIt->more() )
1844 const SMDS_MeshElement* el = elIt->next(); // an element of group
1845 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1846 while ( nIt->more() )
1848 const SMDS_MeshNode* n = nIt->next();
1849 if ( n->GetID() >= (int) isNodeInGroups.size() )
1850 isNodeInGroups.resize( n->GetID() + 1, false );
1851 isNodeInGroups[ n->GetID() ] = true;
1857 // Get elements of theElemType based on a certain number of nodes of elements of groups
1858 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1860 const SMDS_MeshNode* n;
1861 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1862 const int isNodeInGroupsSize = isNodeInGroups.size();
1863 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1865 if ( !isNodeInGroups[ iN ] ||
1866 !( n = aMeshDS->FindNode( iN )))
1869 // check nodes of elements of theElemType around n
1870 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1871 while ( elOfTypeIt->more() )
1873 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1874 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1879 nbNodes = elOfType->NbNodes();
1880 nbCorners = elOfType->NbCornerNodes();
1882 bool toStopChecking = false;
1883 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1884 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1886 const int nID = nIt->next()->GetID();
1887 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1888 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1890 resGroupCore.Add( elOfType );
1898 // Update Python script
1899 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1900 << ".CreateDimGroup( "
1901 << theGroups << ", " << theElemType << ", '" << theName << "', "
1902 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1904 SMESH_CATCH( SMESH::throwCorbaException );
1906 return aResGrp._retn();
1909 //================================================================================
1911 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1912 * existing 1D elements as group boundaries.
1913 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1914 * adjacent faces is more than \a sharpAngle in degrees.
1915 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1916 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1917 * \return ListOfGroups - the created groups
1919 //================================================================================
1921 SMESH::ListOfGroups*
1922 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1923 CORBA::Boolean theCreateEdges,
1924 CORBA::Boolean theUseExistingEdges )
1925 throw (SALOME::SALOME_Exception)
1927 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1928 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1931 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1937 _preMeshInfo->FullLoadFromFile();
1939 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1941 std::vector< SMESH_MeshAlgos::Edge > edges =
1942 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1944 if ( theCreateEdges )
1946 std::vector<const SMDS_MeshNode *> nodes(2);
1947 for ( size_t i = 0; i < edges.size(); ++i )
1949 nodes[0] = edges[i]._node1;
1950 nodes[1] = edges[i]._node2;
1951 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1953 if ( edges[i]._medium )
1954 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1956 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1960 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1961 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1963 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1965 resultGroups->length( faceGroups.size() );
1966 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1968 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1969 _editor->GenerateGroupName("Group").c_str());
1970 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1972 SMESHDS_GroupBase* groupBaseDS =
1973 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1974 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1976 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1977 for ( size_t i = 0; i < faces.size(); ++i )
1978 groupCore.Add( faces[i] );
1981 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1982 << ".FaceGroupsSeparatedByEdges( "
1983 << TVar( theSharpAngle ) << ", "
1984 << theCreateEdges << ", "
1985 << theUseExistingEdges << " )";
1987 SMESH_CATCH( SMESH::throwCorbaException );
1988 return resultGroups._retn();
1992 //================================================================================
1994 * \brief Remember GEOM group data
1996 //================================================================================
1998 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1999 CORBA::Object_ptr theSmeshObj)
2001 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2004 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2005 if ( groupSO->_is_nil() )
2008 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2009 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2010 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2013 _geomGroupData.push_back( TGeomGroupData() );
2014 TGeomGroupData & groupData = _geomGroupData.back();
2016 CORBA::String_var entry = groupSO->GetID();
2017 groupData._groupEntry = entry.in();
2019 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2020 groupData._indices.insert( ids[i] );
2022 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2023 // shape index in SMESHDS
2024 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2025 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2028 //================================================================================
2030 * Remove GEOM group data relating to removed smesh object
2032 //================================================================================
2034 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2036 list<TGeomGroupData>::iterator
2037 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2038 for ( ; data != dataEnd; ++data ) {
2039 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2040 _geomGroupData.erase( data );
2046 //================================================================================
2048 * \brief Replace a shape in the mesh upon Break Link
2050 //================================================================================
2052 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2053 throw (SALOME::SALOME_Exception)
2055 // check if geometry changed
2056 bool geomChanged = true;
2057 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2058 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2059 geomChanged = ( oldGeom->GetTick() != theNewGeom->GetTick() );
2061 TopoDS_Shape S = _impl->GetShapeToMesh();
2062 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2063 TCollection_AsciiString aIOR;
2064 if ( geomClient->Find( S, aIOR ))
2065 geomClient->RemoveShapeFromBuffer( aIOR );
2067 // clear buffer also for sub-groups
2068 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2069 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2070 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2071 for (; g != groups.end(); ++g)
2072 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2074 const TopoDS_Shape& s = group->GetShape();
2075 if ( geomClient->Find( s, aIOR ))
2076 geomClient->RemoveShapeFromBuffer( aIOR );
2079 // clear buffer also for sub-meshes
2080 std::map<int, SMESH_subMesh_i*>::const_iterator aSubMeshIter = _mapSubMesh_i.cbegin();
2081 for(; aSubMeshIter != _mapSubMesh_i.cend(); aSubMeshIter++) {
2082 int aShapeID = aSubMeshIter->first;
2083 const TopoDS_Shape& aSubShape = meshDS->IndexToShape(aShapeID);
2084 TCollection_AsciiString aShapeIOR;
2085 if ( geomClient->Find( aSubShape, aShapeIOR ))
2086 geomClient->RemoveShapeFromBuffer( aShapeIOR );
2090 int shapeID, fromID, toID; // indices of elements of a sub-mesh
2092 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2093 std::vector< SMDS_PositionPtr > positions; // node positions
2096 // store positions of elements on geometry
2098 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2099 meshDS->MaxElementID() > meshDS->NbElements() )
2102 meshDS->CompactMesh();
2104 positions.resize( meshDS->NbNodes() + 1 );
2105 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2107 const SMDS_MeshNode* n = nodeIt->next();
2108 positions[ n->GetID() ] = n->GetPosition();
2111 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2112 for ( int isNode = 0; isNode < 2; ++isNode )
2114 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2115 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2116 ranges.push_back( TRange{ 0,0,0 });
2117 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2118 while ( elemIt->more() )
2120 const SMDS_MeshElement* e = elemIt->next();
2121 const int elemID = e->GetID();
2122 const int shapeID = e->GetShapeID();
2123 TRange & lastRange = ranges.back();
2124 if ( lastRange.shapeID != shapeID ||
2125 lastRange.toID != elemID )
2126 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2128 lastRange.toID = elemID + 1;
2130 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2132 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2133 else sm->RemoveElement( e );
2140 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2141 SMESH::SMESH_Mesh_var me = _this();
2142 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2143 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2144 if ( !aSO->_is_nil() )
2146 SALOMEDS::SObject_wrap aShapeRefSO;
2147 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2149 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2150 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2151 builder->Addreference( aShapeRefSO, aShapeSO );
2155 // re-assign global hypotheses to the new shape
2156 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2157 CheckGeomModif( true );
2161 // restore positions of elements on geometry
2162 for ( int isNode = 0; isNode < 2; ++isNode )
2164 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2165 for ( size_t i = 1; i < ranges.size(); ++i )
2167 int elemID = ranges[ i ].fromID;
2168 int toID = ranges[ i ].toID;
2169 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2171 for ( ; elemID < toID; ++elemID )
2172 smDS->AddNode( meshDS->FindNode( elemID ));
2174 for ( ; elemID < toID; ++elemID )
2175 smDS->AddElement( meshDS->FindElement( elemID ));
2177 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2178 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2181 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2182 if ( positions[ nodeID ])
2183 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2184 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2187 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2190 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2191 << me <<".GetMesh()), " << entry.in() << ")";
2193 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2197 //================================================================================
2199 * \brief Return new group contents if it has been changed and update group data
2201 //================================================================================
2203 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2205 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2207 TopoDS_Shape newShape;
2208 SALOMEDS::SObject_wrap groupSO;
2210 if ( how == IS_BREAK_LINK )
2212 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2213 SALOMEDS::SObject_wrap geomRefSO;
2214 if ( !meshSO->_is_nil() &&
2215 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2217 geomRefSO->ReferencedObject( groupSO.inout() );
2223 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2226 if ( groupSO->_is_nil() )
2229 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2230 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2231 if ( geomGroup->_is_nil() )
2234 // get indices of group items
2235 set<int> curIndices;
2236 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2237 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2238 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2239 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2240 curIndices.insert( ids[i] );
2242 bool sameIndices = ( groupData._indices == curIndices );
2243 if ( how == ONLY_IF_CHANGED && sameIndices )
2244 return newShape; // group not changed
2247 CORBA::String_var entry = geomGroup->GetStudyEntry();
2248 groupData._groupEntry = entry.in();
2249 groupData._indices = curIndices;
2251 newShape = _gen_i->GeomObjectToShape( geomGroup );
2253 // check if newShape is up-to-date
2254 if ( !newShape.IsNull() && ids->length() > 0 )
2256 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2259 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2260 for ( ; exp.More() && !toUpdate; exp.Next() )
2262 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2263 toUpdate = ( curIndices.erase( ind ) == 0 );
2265 if ( !curIndices.empty() )
2270 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2271 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2272 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2273 newShape = _gen_i->GeomObjectToShape( geomGroup );
2278 // geom group becomes empty - return empty compound
2279 TopoDS_Compound compound;
2280 BRep_Builder().MakeCompound(compound);
2281 newShape = compound;
2289 //-----------------------------------------------------------------------------
2291 * \brief Storage of shape and index used in CheckGeomGroupModif()
2293 struct TIndexedShape
2296 TopoDS_Shape _shape;
2297 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2299 //-----------------------------------------------------------------------------
2301 * \brief Data to re-create a group on geometry
2303 struct TGroupOnGeomData
2306 TopoDS_Shape _shape;
2307 SMDSAbs_ElementType _type;
2309 Quantity_Color _color;
2311 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2313 _oldID = group->GetID();
2314 _type = group->GetType();
2315 _name = group->GetStoreName();
2316 _color = group->GetColor();
2320 //-----------------------------------------------------------------------------
2322 * \brief Check if a filter is still valid after geometry removal
2324 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2326 if ( theFilter->_is_nil() )
2328 SMESH::Filter::Criteria_var criteria;
2329 theFilter->GetCriteria( criteria.out() );
2331 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2333 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2335 switch ( criteria[ iCr ].Type )
2337 case SMESH::FT_BelongToGeom:
2338 case SMESH::FT_BelongToPlane:
2339 case SMESH::FT_BelongToCylinder:
2340 case SMESH::FT_BelongToGenSurface:
2341 case SMESH::FT_LyingOnGeom:
2342 entry = thresholdID;
2344 case SMESH::FT_ConnectedElements:
2347 entry = thresholdID;
2353 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2354 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2355 if ( so->_is_nil() )
2357 CORBA::Object_var obj = so->GetObject();
2358 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2359 if ( gen->GeomObjectToShape( geom ).IsNull() )
2362 } // loop on criteria
2368 //=============================================================================
2370 * \brief Update data if geometry changes
2374 //=============================================================================
2376 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2378 SMESH::SMESH_Mesh_var me = _this();
2379 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2381 TPythonDump dumpNothing; // prevent any dump
2383 //bool removedFromClient = false;
2385 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2387 //removedFromClient = _impl->HasShapeToMesh();
2389 // try to find geometry by study reference
2390 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2391 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2392 if ( !meshSO->_is_nil() &&
2393 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2394 geomRefSO->ReferencedObject( geomSO.inout() ))
2396 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2397 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2400 if ( mainGO->_is_nil() && // geometry removed ==>
2401 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2403 // convert geom dependent groups into standalone ones
2404 CheckGeomGroupModif();
2406 _impl->ShapeToMesh( TopoDS_Shape() );
2408 // remove sub-meshes
2409 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2410 while ( i_sm != _mapSubMeshIor.end() )
2412 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2414 RemoveSubMesh( sm );
2416 // remove all children except groups in the study
2417 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2418 SALOMEDS::SObject_wrap so;
2419 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2420 if ( meshSO->FindSubObject( tag, so.inout() ))
2421 builder->RemoveObjectWithChildren( so );
2423 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2429 if ( !_impl->HasShapeToMesh() ) return;
2432 // Update after group modification
2434 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2435 if ( !theIsBreakLink )
2436 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2438 int nb = NbNodes() + NbElements();
2439 CheckGeomGroupModif();
2440 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2441 _gen_i->UpdateIcons( me );
2445 // Update after shape modification or breakLink w/o geometry change
2447 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2448 if ( !geomClient ) return;
2449 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2450 if ( geomGen->_is_nil() ) return;
2451 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2452 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2454 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2456 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2457 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2459 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2460 geomClient->RemoveShapeFromBuffer( ior.in() );
2461 newShape = _gen_i->GeomObjectToShape( mainGO );
2464 // Update data taking into account that if topology doesn't change
2465 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2468 _preMeshInfo->ForgetAllData();
2470 if ( geomChanged || !isShaper )
2472 if ( newShape.IsNull() )
2475 _mainShapeTick = mainGO->GetTick();
2477 // store data of groups on geometry including new TopoDS_Shape's
2478 std::vector< TGroupOnGeomData > groupsData;
2479 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2480 groupsData.reserve( groups.size() );
2481 TopTools_DataMapOfShapeShape old2newShapeMap;
2482 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2483 for ( ; g != groups.end(); ++g )
2485 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2487 groupsData.push_back( TGroupOnGeomData( group ));
2490 SMESH::SMESH_GroupOnGeom_var gog;
2491 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2492 if ( i_grp != _mapGroups.end() )
2493 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2495 GEOM::GEOM_Object_var geom;
2496 if ( !gog->_is_nil() )
2498 if ( !theIsBreakLink )
2499 geom = gog->GetShape();
2501 if ( theIsBreakLink || geom->_is_nil() )
2503 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2504 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2505 if ( !grpSO->_is_nil() &&
2506 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2507 geomRefSO->ReferencedObject( geomSO.inout() ))
2509 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2510 geom = GEOM::GEOM_Object::_narrow( geomObj );
2514 if ( old2newShapeMap.IsBound( group->GetShape() ))
2516 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2518 else if ( !geom->_is_nil() )
2520 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2521 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2523 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2524 geomClient->RemoveShapeFromBuffer( ior.in() );
2525 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2527 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2532 // store assigned hypotheses
2533 std::vector< pair< int, THypList > > ids2Hyps;
2534 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2535 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2537 const TopoDS_Shape& s = s2hyps.Key();
2538 const THypList& hyps = s2hyps.ChangeValue();
2539 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2542 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2544 // count shapes excluding compounds corresponding to geom groups
2545 int oldNbSubShapes = meshDS->MaxShapeIndex();
2546 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2548 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2549 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2552 std::set<int> subIds;
2553 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2554 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2555 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2558 // check if shape topology changes - save shape type per shape ID
2559 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2560 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2561 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2563 // change shape to mesh
2564 _impl->ShapeToMesh( TopoDS_Shape() );
2565 _impl->ShapeToMesh( newShape );
2567 // check if shape topology changes - check new shape types
2568 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2569 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2571 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2572 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2575 // re-add shapes (compounds) of geom groups
2576 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2577 TIndices2GroupData ii2grData;
2578 std::vector< int > ii;
2579 std::map< int, int > old2newIDs; // group IDs
2580 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2581 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2583 TGeomGroupData* data = &(*dataIt);
2584 ii.reserve( data->_indices.size() );
2585 ii.assign( data->_indices.begin(), data->_indices.end() );
2586 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2587 if ( ii2gd->second != data )
2589 data->_groupEntry = ii2gd->second->_groupEntry;
2590 data->_indices = ii2gd->second->_indices;
2593 const int oldNbSub = data->_indices.size();
2594 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2596 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2597 if ( ii2i != ii2iMap.end() )
2599 oldID = ii2i->second;
2600 ii2iMap.erase( ii2i );
2602 if ( !oldID && oldNbSub == 1 )
2604 if ( old2newIDs.count( oldID ))
2607 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2608 newShape = newGroupShape( *data, how );
2610 if ( !newShape.IsNull() )
2612 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2614 TopoDS_Compound compound;
2615 BRep_Builder().MakeCompound( compound );
2616 BRep_Builder().Add( compound, newShape );
2617 newShape = compound;
2619 int newID = _impl->GetSubMesh( newShape )->GetId();
2620 if ( oldID /*&& oldID != newID*/ )
2621 old2newIDs.insert( std::make_pair( oldID, newID ));
2622 if ( oldNbSub == 1 )
2623 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2627 // re-assign hypotheses
2628 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2630 int sID = ids2Hyps[i].first;
2633 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2634 if ( o2n != old2newIDs.end() )
2636 else if ( !sameTopology )
2639 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2642 const THypList& hyps = ids2Hyps[i].second;
2643 THypList::const_iterator h = hyps.begin();
2644 for ( ; h != hyps.end(); ++h )
2645 _impl->AddHypothesis( s, (*h)->GetID() );
2649 // restore groups on geometry
2650 for ( size_t i = 0; i < groupsData.size(); ++i )
2652 const TGroupOnGeomData& data = groupsData[i];
2653 if ( data._shape.IsNull() )
2656 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2657 if ( i2g == _mapGroups.end() ) continue;
2659 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2660 if ( !gr_i ) continue;
2662 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2664 _mapGroups.erase( i2g );
2666 g->GetGroupDS()->SetColor( data._color );
2669 if ( !sameTopology )
2671 std::map< int, int >::iterator o2n = old2newIDs.begin();
2672 for ( ; o2n != old2newIDs.end(); ++o2n )
2674 int newID = o2n->second, oldID = o2n->first;
2675 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2679 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2680 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2681 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2683 _mapSubMesh. erase(oldID);
2684 _mapSubMesh_i. erase(oldID);
2685 _mapSubMeshIor.erase(oldID);
2687 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2691 // update _mapSubMesh
2692 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2693 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2694 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2697 if ( !sameTopology )
2699 // remove invalid study sub-objects
2700 CheckGeomGroupModif();
2703 _gen_i->UpdateIcons( me );
2705 if ( !theIsBreakLink && isShaper )
2707 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2708 if ( !meshSO->_is_nil() )
2709 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2713 //=============================================================================
2715 * \brief Update objects depending on changed geom groups
2717 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2718 * issue 0020210: Update of a smesh group after modification of the associated geom group
2720 //=============================================================================
2722 void SMESH_Mesh_i::CheckGeomGroupModif()
2724 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2725 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2726 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2727 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2728 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2730 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2731 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2732 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2734 int nbValid = 0, nbRemoved = 0;
2735 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2736 for ( ; chItr->More(); chItr->Next() )
2738 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2739 if ( !smSO->_is_nil() &&
2740 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2741 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2743 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2744 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2745 if ( !geom->_non_existent() )
2748 continue; // keep the sub-mesh
2751 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2752 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2753 if ( !sm->_is_nil() && !sm->_non_existent() )
2755 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2756 if ( smGeom->_is_nil() )
2758 RemoveSubMesh( sm );
2765 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2766 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2770 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2771 builder->RemoveObjectWithChildren( rootSO );
2775 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2776 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2777 while ( i_gr != _mapGroups.end())
2779 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2781 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2782 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2783 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2784 bool isValidGeom = false;
2785 if ( !onGeom->_is_nil() )
2787 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2788 if ( !isValidGeom ) // check reference
2790 isValidGeom = ( ! groupSO->_is_nil() &&
2791 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2792 refSO->ReferencedObject( geomSO.inout() ) &&
2793 ! geomSO->_is_nil() &&
2794 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2797 else if ( !onFilt->_is_nil() )
2799 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2803 isValidGeom = ( !groupSO->_is_nil() &&
2804 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2808 if ( !IsLoaded() || group->IsEmpty() )
2810 RemoveGroup( group );
2812 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2814 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2816 else // is it possible?
2818 builder->RemoveObjectWithChildren( refSO );
2824 if ( !_impl->HasShapeToMesh() ) return;
2826 CORBA::Long nbEntities = NbNodes() + NbElements();
2828 // Check if group contents changed
2830 typedef map< string, TopoDS_Shape > TEntry2Geom;
2831 TEntry2Geom newGroupContents;
2833 list<TGeomGroupData>::iterator
2834 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2835 for ( ; data != dataEnd; ++data )
2837 pair< TEntry2Geom::iterator, bool > it_new =
2838 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2839 bool processedGroup = !it_new.second;
2840 TopoDS_Shape& newShape = it_new.first->second;
2841 if ( !processedGroup )
2842 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2843 if ( newShape.IsNull() )
2844 continue; // no changes
2847 _preMeshInfo->ForgetOrLoad();
2849 if ( processedGroup ) { // update group indices
2850 list<TGeomGroupData>::iterator data2 = data;
2851 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2852 data->_indices = data2->_indices;
2855 // Update SMESH objects according to new GEOM group contents
2857 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2858 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2860 int oldID = submesh->GetId();
2861 if ( !_mapSubMeshIor.count( oldID ))
2863 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2865 // update hypotheses
2866 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2867 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2868 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2870 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2871 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2873 // care of submeshes
2874 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2875 int newID = newSubmesh->GetId();
2876 if ( newID != oldID ) {
2877 _mapSubMesh [ newID ] = newSubmesh;
2878 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2879 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2880 _mapSubMesh. erase(oldID);
2881 _mapSubMesh_i. erase(oldID);
2882 _mapSubMeshIor.erase(oldID);
2883 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2888 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2889 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2890 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2892 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2894 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2895 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2896 ds->SetShape( newShape );
2901 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2902 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2904 // Remove groups and submeshes basing on removed sub-shapes
2906 TopTools_MapOfShape newShapeMap;
2907 TopoDS_Iterator shapeIt( newShape );
2908 for ( ; shapeIt.More(); shapeIt.Next() )
2909 newShapeMap.Add( shapeIt.Value() );
2911 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2912 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2914 if ( newShapeMap.Contains( shapeIt.Value() ))
2916 TopTools_IndexedMapOfShape oldShapeMap;
2917 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2918 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2920 const TopoDS_Shape& oldShape = oldShapeMap(i);
2921 int oldInd = meshDS->ShapeToIndex( oldShape );
2923 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2924 if ( i_smIor != _mapSubMeshIor.end() ) {
2925 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2928 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2929 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2931 // check if a group bases on oldInd shape
2932 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2933 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2934 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2935 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2937 RemoveGroup( i_grp->second ); // several groups can base on same shape
2938 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2943 // Reassign hypotheses and update groups after setting the new shape to mesh
2945 // collect anassigned hypotheses
2946 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2947 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2948 TShapeHypList assignedHyps;
2949 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2951 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2952 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2953 if ( !hyps.empty() ) {
2954 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2955 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2956 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2959 // collect shapes supporting groups
2960 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2961 TShapeTypeList groupData;
2962 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2963 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2964 for ( ; grIt != groups.end(); ++grIt )
2966 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2968 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2970 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2972 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2973 _impl->ShapeToMesh( newShape );
2975 // reassign hypotheses
2976 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2977 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2979 TIndexedShape& geom = indS_hyps->first;
2980 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2981 int oldID = geom._index;
2982 int newID = meshDS->ShapeToIndex( geom._shape );
2983 if ( oldID == 1 ) { // main shape
2985 geom._shape = newShape;
2989 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2990 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2991 // care of sub-meshes
2992 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2993 if ( newID != oldID ) {
2994 _mapSubMesh [ newID ] = newSubmesh;
2995 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2996 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2997 _mapSubMesh. erase(oldID);
2998 _mapSubMesh_i. erase(oldID);
2999 _mapSubMeshIor.erase(oldID);
3000 _mapSubMesh_i [ newID ]->changeLocalId( newID );
3004 TShapeTypeList::iterator geomType = groupData.begin();
3005 for ( ; geomType != groupData.end(); ++geomType )
3007 const TIndexedShape& geom = geomType->first;
3008 int oldID = geom._index;
3009 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
3012 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
3013 CORBA::String_var name = groupSO->GetName();
3015 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
3016 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
3017 /*id=*/-1, geom._shape ))
3018 group_i->changeLocalId( group->GetID() );
3021 break; // everything has been updated
3024 } // loop on group data
3028 CORBA::Long newNbEntities = NbNodes() + NbElements();
3029 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3030 if ( newNbEntities != nbEntities )
3032 // Add all SObjects with icons to soToUpdateIcons
3033 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3035 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3036 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3037 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3039 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3040 i_gr != _mapGroups.end(); ++i_gr ) // groups
3041 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3044 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3045 for ( ; so != soToUpdateIcons.end(); ++so )
3046 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3049 //=============================================================================
3051 * \brief Create standalone group from a group on geometry or filter
3053 //=============================================================================
3055 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3056 throw (SALOME::SALOME_Exception)
3058 SMESH::SMESH_Group_var aGroup;
3063 _preMeshInfo->FullLoadFromFile();
3065 if ( theGroup->_is_nil() )
3066 return aGroup._retn();
3068 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3070 return aGroup._retn();
3072 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3074 const int anId = aGroupToRem->GetLocalID();
3075 if ( !_impl->ConvertToStandalone( anId ) )
3076 return aGroup._retn();
3077 removeGeomGroupData( theGroup );
3079 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3081 // remove old instance of group from own map
3082 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3083 _mapGroups.erase( anId );
3085 SALOMEDS::StudyBuilder_var builder;
3086 SALOMEDS::SObject_wrap aGroupSO;
3087 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3088 if ( !aStudy->_is_nil() ) {
3089 builder = aStudy->NewBuilder();
3090 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3091 if ( !aGroupSO->_is_nil() )
3093 // remove reference to geometry
3094 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3095 for ( ; chItr->More(); chItr->Next() )
3097 // Remove group's child SObject
3098 SALOMEDS::SObject_wrap so = chItr->Value();
3099 builder->RemoveObject( so );
3101 // Update Python script
3102 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3103 << ".ConvertToStandalone( " << aGroupSO << " )";
3105 // change icon of Group on Filter
3108 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3109 // const int isEmpty = ( elemTypes->length() == 0 );
3112 SALOMEDS::GenericAttribute_wrap anAttr =
3113 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3114 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3115 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3121 // remember new group in own map
3122 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3123 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3125 // register CORBA object for persistence
3126 _gen_i->RegisterObject( aGroup );
3128 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3129 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3130 //aGroup->Register();
3131 aGroupToRem->UnRegister();
3133 SMESH_CATCH( SMESH::throwCorbaException );
3135 return aGroup._retn();
3138 //================================================================================
3140 * \brief Create a sub-mesh on a given sub-shape
3142 //================================================================================
3144 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3146 if(MYDEBUG) MESSAGE( "createSubMesh" );
3147 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3148 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3151 SMESH_subMesh_i * subMeshServant;
3154 subMeshId = mySubMesh->GetId();
3155 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3157 else // "invalid sub-mesh"
3159 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3160 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3161 if ( _mapSubMesh.empty() )
3164 subMeshId = _mapSubMesh.begin()->first - 1;
3165 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3168 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3170 _mapSubMesh [subMeshId] = mySubMesh;
3171 _mapSubMesh_i [subMeshId] = subMeshServant;
3172 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3174 subMeshServant->Register();
3176 // register CORBA object for persistence
3177 int nextId = _gen_i->RegisterObject( subMesh );
3178 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3179 else { nextId = 0; } // avoid "unused variable" warning
3181 // to track changes of GEOM groups
3182 if ( subMeshId > 0 )
3183 addGeomGroupData( theSubShapeObject, subMesh );
3185 return subMesh._retn();
3188 //================================================================================
3190 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3192 //================================================================================
3194 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3196 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3197 if ( it == _mapSubMeshIor.end() )
3198 return SMESH::SMESH_subMesh::_nil();
3200 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3203 //================================================================================
3205 * \brief Remove a sub-mesh based on the given sub-shape
3207 //================================================================================
3209 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3210 GEOM::GEOM_Object_ptr theSubShapeObject )
3212 bool isHypChanged = false;
3213 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3214 return isHypChanged;
3216 const int subMeshId = theSubMesh->GetId();
3218 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3221 if (( _mapSubMesh.count( subMeshId )) &&
3222 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3224 TopoDS_Shape S = sm->GetSubShape();
3227 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3228 isHypChanged = !hyps.empty();
3229 if ( isHypChanged && _preMeshInfo )
3230 _preMeshInfo->ForgetOrLoad();
3231 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3232 for ( ; hyp != hyps.end(); ++hyp )
3233 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3240 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3241 isHypChanged = ( aHypList->length() > 0 );
3242 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3243 removeHypothesis( theSubShapeObject, aHypList[i] );
3246 catch( const SALOME::SALOME_Exception& ) {
3247 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3249 removeGeomGroupData( theSubShapeObject );
3253 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3254 if ( id_smi != _mapSubMesh_i.end() )
3255 id_smi->second->UnRegister();
3257 // remove a CORBA object
3258 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3259 if ( id_smptr != _mapSubMeshIor.end() )
3260 SMESH::SMESH_subMesh_var( id_smptr->second );
3262 _mapSubMesh.erase(subMeshId);
3263 _mapSubMesh_i.erase(subMeshId);
3264 _mapSubMeshIor.erase(subMeshId);
3266 return isHypChanged;
3269 //================================================================================
3271 * \brief Create a group. Group type depends on given arguments
3273 //================================================================================
3275 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3276 const char* theName,
3278 const TopoDS_Shape& theShape,
3279 const SMESH_PredicatePtr& thePredicate )
3281 std::string newName;
3282 if ( !theName || !theName[0] )
3284 std::set< std::string > presentNames;
3285 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3286 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3288 CORBA::String_var name = i_gr->second->GetName();
3289 presentNames.insert( name.in() );
3292 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3293 } while ( !presentNames.insert( newName ).second );
3294 theName = newName.c_str();
3296 SMESH::SMESH_GroupBase_var aGroup;
3297 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3298 theID, theShape, thePredicate ))
3300 int anId = g->GetID();
3301 SMESH_GroupBase_i* aGroupImpl;
3302 if ( !theShape.IsNull() )
3303 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3304 else if ( thePredicate )
3305 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3307 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3309 aGroup = aGroupImpl->_this();
3310 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3311 aGroupImpl->Register();
3313 // register CORBA object for persistence
3314 int nextId = _gen_i->RegisterObject( aGroup );
3315 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3316 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3318 // to track changes of GEOM groups
3319 if ( !theShape.IsNull() ) {
3320 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3321 addGeomGroupData( geom, aGroup );
3324 return aGroup._retn();
3327 //=============================================================================
3329 * SMESH_Mesh_i::removeGroup
3331 * Should be called by ~SMESH_Group_i()
3333 //=============================================================================
3335 void SMESH_Mesh_i::removeGroup( const int theId )
3337 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3338 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3339 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3340 _mapGroups.erase( theId );
3341 removeGeomGroupData( group );
3342 if ( !_impl->RemoveGroup( theId ))
3344 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3345 RemoveGroup( group );
3347 group->UnRegister();
3351 //================================================================================
3353 * \brief Return a log that can be used to move another mesh to the same state as this one
3355 //================================================================================
3357 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3358 throw(SALOME::SALOME_Exception)
3360 SMESH::log_array_var aLog;
3364 _preMeshInfo->FullLoadFromFile();
3366 list < SMESHDS_Command * >logDS = _impl->GetLog();
3367 aLog = new SMESH::log_array;
3369 int lg = logDS.size();
3371 list < SMESHDS_Command * >::iterator its = logDS.begin();
3372 while(its != logDS.end()){
3373 SMESHDS_Command *com = *its;
3374 int comType = com->GetType();
3375 int lgcom = com->GetNumber();
3376 const list < int >&intList = com->GetIndexes();
3377 int inum = intList.size();
3378 list < int >::const_iterator ii = intList.begin();
3379 const list < double >&coordList = com->GetCoords();
3380 int rnum = coordList.size();
3381 list < double >::const_iterator ir = coordList.begin();
3382 aLog[indexLog].commandType = comType;
3383 aLog[indexLog].number = lgcom;
3384 aLog[indexLog].coords.length(rnum);
3385 aLog[indexLog].indexes.length(inum);
3386 for(int i = 0; i < rnum; i++){
3387 aLog[indexLog].coords[i] = *ir;
3390 for(int i = 0; i < inum; i++){
3391 aLog[indexLog].indexes[i] = *ii;
3400 SMESH_CATCH( SMESH::throwCorbaException );
3402 return aLog._retn();
3405 //================================================================================
3407 * \brief Remove the log of commands
3409 //================================================================================
3411 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3415 SMESH_CATCH( SMESH::throwCorbaException );
3418 //================================================================================
3420 * \brief Return a mesh ID
3422 //================================================================================
3424 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3429 //=============================================================================
3432 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3433 // issue 0020918: groups removal is caused by hyp modification
3434 // issue 0021208: to forget not loaded mesh data at hyp modification
3435 struct TCallUp_i : public SMESH_Mesh::TCallUp
3437 SMESH_Mesh_i* _mesh;
3438 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3439 void RemoveGroup (const int theGroupID) override { _mesh->removeGroup( theGroupID ); }
3440 void HypothesisModified( int hypID,
3441 bool updIcons) override { _mesh->onHypothesisModified( hypID,
3443 void Load () override { _mesh->Load(); }
3444 bool IsLoaded() override { return _mesh->IsLoaded(); }
3445 TopoDS_Shape GetShapeByEntry(const std::string& entry) override
3447 GEOM::GEOM_Object_var go = SMESH_Gen_i::GetGeomObjectByEntry( entry );
3448 return SMESH_Gen_i::GeomObjectToShape( go );
3453 //================================================================================
3455 * \brief callback from _impl to
3456 * 1) forget not loaded mesh data (issue 0021208)
3457 * 2) mark hypothesis as valid
3459 //================================================================================
3461 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3464 _preMeshInfo->ForgetOrLoad();
3466 if ( theUpdateIcons )
3468 SMESH::SMESH_Mesh_var mesh = _this();
3469 _gen_i->UpdateIcons( mesh );
3472 if ( _nbInvalidHypos != 0 )
3474 // mark a hypothesis as valid after edition
3476 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3477 SALOMEDS::SObject_wrap hypRoot;
3478 if ( !smeshComp->_is_nil() &&
3479 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3481 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3482 for ( ; anIter->More(); anIter->Next() )
3484 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3485 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3486 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3487 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3488 _gen_i->HighLightInvalid( hyp, false );
3490 nbInvalid += _gen_i->IsInvalid( hypSO );
3493 _nbInvalidHypos = nbInvalid;
3497 //================================================================================
3499 * \brief Set mesh implementation
3501 //================================================================================
3503 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3505 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3508 _impl->SetCallUp( new TCallUp_i(this));
3511 //=============================================================================
3513 * Return a mesh implementation
3515 //=============================================================================
3517 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3519 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3523 //=============================================================================
3525 * Return mesh editor
3527 //=============================================================================
3529 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3530 throw (SALOME::SALOME_Exception)
3532 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3536 _preMeshInfo->FullLoadFromFile();
3538 // Create MeshEditor
3540 _editor = new SMESH_MeshEditor_i( this, false );
3541 aMeshEdVar = _editor->_this();
3543 // Update Python script
3544 TPythonDump() << _editor << " = "
3545 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3547 SMESH_CATCH( SMESH::throwCorbaException );
3549 return aMeshEdVar._retn();
3552 //=============================================================================
3554 * Return mesh edition previewer
3556 //=============================================================================
3558 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3559 throw (SALOME::SALOME_Exception)
3561 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3565 _preMeshInfo->FullLoadFromFile();
3567 if ( !_previewEditor )
3568 _previewEditor = new SMESH_MeshEditor_i( this, true );
3569 aMeshEdVar = _previewEditor->_this();
3571 SMESH_CATCH( SMESH::throwCorbaException );
3573 return aMeshEdVar._retn();
3576 //================================================================================
3578 * \brief Return true if the mesh has been edited since a last total re-compute
3579 * and those modifications may prevent successful partial re-compute
3581 //================================================================================
3583 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3585 Unexpect aCatch(SALOME_SalomeException);
3586 return _impl->HasModificationsToDiscard();
3589 //================================================================================
3591 * \brief Return a random unique color
3593 //================================================================================
3595 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3597 const int MAX_ATTEMPTS = 100;
3599 double tolerance = 0.5;
3600 SALOMEDS::Color col;
3604 // generate random color
3605 double red = (double)rand() / RAND_MAX;
3606 double green = (double)rand() / RAND_MAX;
3607 double blue = (double)rand() / RAND_MAX;
3608 // check existence in the list of the existing colors
3609 bool matched = false;
3610 std::list<SALOMEDS::Color>::const_iterator it;
3611 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3612 SALOMEDS::Color color = *it;
3613 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3614 matched = tol < tolerance;
3616 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3617 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3625 //=============================================================================
3627 * Set auto-color mode. If it is on, groups get unique random colors
3629 //=============================================================================
3631 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3633 Unexpect aCatch(SALOME_SalomeException);
3634 _impl->SetAutoColor(theAutoColor);
3636 TPythonDump pyDump; // not to dump group->SetColor() from below code
3637 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3639 std::list<SALOMEDS::Color> aReservedColors;
3640 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3641 for ( ; it != _mapGroups.end(); it++ ) {
3642 if ( CORBA::is_nil( it->second )) continue;
3643 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3644 it->second->SetColor( aColor );
3645 aReservedColors.push_back( aColor );
3649 //=============================================================================
3651 * Return true if auto-color mode is on
3653 //=============================================================================
3655 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3657 Unexpect aCatch(SALOME_SalomeException);
3658 return _impl->GetAutoColor();
3661 //=============================================================================
3663 * Check if there are groups with equal names
3665 //=============================================================================
3667 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3669 return _impl->HasDuplicatedGroupNamesMED();
3672 //================================================================================
3674 * \brief Care of a file before exporting mesh into it
3676 //================================================================================
3678 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3680 SMESH_File aFile( file, false );
3682 if ( aFile.exists() ) {
3683 // existing filesystem node
3684 if ( !aFile.isDirectory() ) {
3685 if ( aFile.openForWriting() ) {
3686 if ( overwrite && ! aFile.remove()) {
3687 msg << "Can't replace " << aFile.getName();
3690 msg << "Can't write into " << aFile.getName();
3693 msg << "Location " << aFile.getName() << " is not a file";
3697 // nonexisting file; check if it can be created
3698 if ( !aFile.openForWriting() ) {
3699 msg << "You cannot create the file "
3701 << ". Check the directory existence and access rights";
3709 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3713 //================================================================================
3715 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3716 * \param file - file name
3717 * \param overwrite - to erase the file or not
3718 * \retval string - mesh name
3720 //================================================================================
3722 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3723 CORBA::Boolean overwrite)
3726 PrepareForWriting(file, overwrite);
3727 string aMeshName = "Mesh";
3728 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3729 if ( !aStudy->_is_nil() ) {
3730 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3731 if ( !aMeshSO->_is_nil() ) {
3732 CORBA::String_var name = aMeshSO->GetName();
3734 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3735 if ( !aStudy->GetProperties()->IsLocked() )
3737 SALOMEDS::GenericAttribute_wrap anAttr;
3738 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3739 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3740 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3741 ASSERT(!aFileName->_is_nil());
3742 aFileName->SetValue(file);
3743 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3744 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3745 ASSERT(!aFileType->_is_nil());
3746 aFileType->SetValue("FICHIERMED");
3750 // Update Python script
3751 // set name of mesh before export
3752 TPythonDump() << _gen_i << ".SetName("
3753 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3755 // check names of groups
3761 //================================================================================
3763 * \brief Export to MED file
3765 //================================================================================
3767 void SMESH_Mesh_i::ExportMED(const char* file,
3768 CORBA::Boolean auto_groups,
3769 CORBA::Long version,
3770 CORBA::Boolean overwrite,
3771 CORBA::Boolean autoDimension)
3772 throw(SALOME::SALOME_Exception)
3774 //MESSAGE("MED minor version: "<< minor);
3777 _preMeshInfo->FullLoadFromFile();
3779 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3780 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3782 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3784 << "auto_groups=" <<auto_groups << ", "
3785 << "version=" << version << ", "
3786 << "overwrite=" << overwrite << ", "
3787 << "meshPart=None, "
3788 << "autoDimension=" << autoDimension << " )";
3790 SMESH_CATCH( SMESH::throwCorbaException );
3793 //================================================================================
3795 * \brief Export a mesh to a SAUV file
3797 //================================================================================
3799 void SMESH_Mesh_i::ExportSAUV (const char* file,
3800 CORBA::Boolean auto_groups)
3801 throw(SALOME::SALOME_Exception)
3803 Unexpect aCatch(SALOME_SalomeException);
3805 _preMeshInfo->FullLoadFromFile();
3807 string aMeshName = prepareMeshNameAndGroups(file, true);
3808 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3809 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3810 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3814 //================================================================================
3816 * \brief Export a mesh to a DAT file
3818 //================================================================================
3820 void SMESH_Mesh_i::ExportDAT (const char *file)
3821 throw(SALOME::SALOME_Exception)
3823 Unexpect aCatch(SALOME_SalomeException);
3825 _preMeshInfo->FullLoadFromFile();
3827 // Update Python script
3828 // check names of groups
3830 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3833 PrepareForWriting(file);
3834 _impl->ExportDAT(file);
3837 //================================================================================
3839 * \brief Export a mesh to an UNV file
3841 //================================================================================
3843 void SMESH_Mesh_i::ExportUNV (const char *file)
3844 throw(SALOME::SALOME_Exception)
3846 Unexpect aCatch(SALOME_SalomeException);
3848 _preMeshInfo->FullLoadFromFile();
3850 // Update Python script
3851 // check names of groups
3853 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3856 PrepareForWriting(file);
3857 _impl->ExportUNV(file);
3860 //================================================================================
3862 * \brief Export a mesh to an STL file
3864 //================================================================================
3866 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3867 throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 _preMeshInfo->FullLoadFromFile();
3873 // Update Python script
3874 // check names of groups
3876 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3877 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3879 CORBA::String_var name;
3880 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3881 if ( !so->_is_nil() )
3882 name = so->GetName();
3885 PrepareForWriting( file );
3886 _impl->ExportSTL( file, isascii, name.in() );
3889 //================================================================================
3891 * \brief Export a part of mesh to a med file
3893 //================================================================================
3895 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3897 CORBA::Boolean auto_groups,
3898 CORBA::Long version,
3899 CORBA::Boolean overwrite,
3900 CORBA::Boolean autoDimension,
3901 const GEOM::ListOfFields& fields,
3902 const char* geomAssocFields,
3903 CORBA::Double ZTolerance)
3904 throw (SALOME::SALOME_Exception)
3906 MESSAGE("MED version: "<< version);
3909 _preMeshInfo->FullLoadFromFile();
3912 bool have0dField = false;
3913 if ( fields.length() > 0 )
3915 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3916 if ( shapeToMesh->_is_nil() )
3917 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3919 for ( size_t i = 0; i < fields.length(); ++i )
3921 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3922 THROW_SALOME_CORBA_EXCEPTION
3923 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3924 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3925 if ( fieldShape->_is_nil() )
3926 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3927 if ( !fieldShape->IsSame( shapeToMesh ) )
3928 THROW_SALOME_CORBA_EXCEPTION
3929 ( "Field defined not on shape", SALOME::BAD_PARAM);
3930 if ( fields[i]->GetDimension() == 0 )
3933 if ( geomAssocFields )
3934 for ( int i = 0; geomAssocFields[i]; ++i )
3935 switch ( geomAssocFields[i] ) {
3936 case 'v':case 'e':case 'f':case 's': break;
3937 case 'V':case 'E':case 'F':case 'S': break;
3938 default: THROW_SALOME_CORBA_EXCEPTION
3939 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3943 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3947 string aMeshName = "Mesh";
3948 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3949 if ( CORBA::is_nil( meshPart ) ||
3950 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3952 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3953 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3954 0, autoDimension, /*addODOnVertices=*/have0dField,
3956 meshDS = _impl->GetMeshDS();
3961 _preMeshInfo->FullLoadFromFile();
3963 PrepareForWriting(file, overwrite);
3965 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3966 if ( !SO->_is_nil() ) {
3967 CORBA::String_var name = SO->GetName();
3971 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3972 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3973 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3974 meshDS = tmpDSDeleter._obj = partDS;
3979 if ( _impl->HasShapeToMesh() )
3981 DriverMED_W_Field fieldWriter;
3982 fieldWriter.SetFile( file );
3983 fieldWriter.SetMeshName( aMeshName );
3984 fieldWriter.AddODOnVertices( have0dField );
3986 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3990 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3991 goList->length( fields.length() );
3992 for ( size_t i = 0; i < fields.length(); ++i )
3994 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3997 TPythonDump() << _this() << ".ExportPartToMED( "
3998 << meshPart << ", r'"
4000 << auto_groups << ", "
4002 << overwrite << ", "
4003 << autoDimension << ", "
4005 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
4006 << TVar( ZTolerance )
4009 SMESH_CATCH( SMESH::throwCorbaException );
4012 //================================================================================
4014 * Write GEOM fields to MED file
4016 //================================================================================
4018 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
4019 SMESHDS_Mesh* meshDS,
4020 const GEOM::ListOfFields& fields,
4021 const char* geomAssocFields)
4023 #define METH "SMESH_Mesh_i::exportMEDFields() "
4025 if (( fields.length() < 1 ) &&
4026 ( !geomAssocFields || !geomAssocFields[0] ))
4029 std::vector< std::vector< double > > dblVals;
4030 std::vector< std::vector< int > > intVals;
4031 std::vector< int > subIdsByDim[ 4 ];
4032 const double noneDblValue = 0.;
4033 const double noneIntValue = 0;
4035 for ( size_t iF = 0; iF < fields.length(); ++iF )
4039 int dim = fields[ iF ]->GetDimension();
4040 SMDSAbs_ElementType elemType;
4041 TopAbs_ShapeEnum shapeType;
4043 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4044 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4045 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4046 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4048 continue; // skip fields on whole shape
4050 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4051 if ( dataType == GEOM::FDT_String )
4053 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4054 if ( stepIDs->length() < 1 )
4056 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4057 if ( comps->length() < 1 )
4059 CORBA::String_var name = fields[ iF ]->GetName();
4061 if ( !fieldWriter.Set( meshDS,
4065 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4068 for ( size_t iC = 0; iC < comps->length(); ++iC )
4069 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4071 dblVals.resize( comps->length() );
4072 intVals.resize( comps->length() );
4074 // find sub-shape IDs
4076 std::vector< int >& subIds = subIdsByDim[ dim ];
4077 if ( subIds.empty() )
4078 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4079 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4080 subIds.push_back( id );
4084 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4088 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4090 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4091 if ( step->_is_nil() )
4094 CORBA::Long stamp = step->GetStamp();
4095 CORBA::Long id = step->GetID();
4096 fieldWriter.SetDtIt( int( stamp ), int( id ));
4098 // fill dblVals or intVals
4099 for ( size_t iC = 0; iC < comps->length(); ++iC )
4100 if ( dataType == GEOM::FDT_Double )
4102 dblVals[ iC ].clear();
4103 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4107 intVals[ iC ].clear();
4108 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4112 case GEOM::FDT_Double:
4114 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4115 if ( dblStep->_is_nil() ) continue;
4116 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4117 if ( vv->length() != subIds.size() * comps->length() )
4118 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4119 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4120 for ( size_t iC = 0; iC < comps->length(); ++iC )
4121 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4126 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4127 if ( intStep->_is_nil() ) continue;
4128 GEOM::ListOfLong_var vv = intStep->GetValues();
4129 if ( vv->length() != subIds.size() * comps->length() )
4130 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4131 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4132 for ( size_t iC = 0; iC < comps->length(); ++iC )
4133 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4136 case GEOM::FDT_Bool:
4138 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4139 if ( boolStep->_is_nil() ) continue;
4140 GEOM::short_array_var vv = boolStep->GetValues();
4141 if ( vv->length() != subIds.size() * comps->length() )
4142 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4143 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4144 for ( size_t iC = 0; iC < comps->length(); ++iC )
4145 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4151 // pass values to fieldWriter
4152 elemIt = fieldWriter.GetOrderedElems();
4153 if ( dataType == GEOM::FDT_Double )
4154 while ( elemIt->more() )
4156 const SMDS_MeshElement* e = elemIt->next();
4157 const int shapeID = e->getshapeId();
4158 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4159 for ( size_t iC = 0; iC < comps->length(); ++iC )
4160 fieldWriter.AddValue( noneDblValue );
4162 for ( size_t iC = 0; iC < comps->length(); ++iC )
4163 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4166 while ( elemIt->more() )
4168 const SMDS_MeshElement* e = elemIt->next();
4169 const int shapeID = e->getshapeId();
4170 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4171 for ( size_t iC = 0; iC < comps->length(); ++iC )
4172 fieldWriter.AddValue( (double) noneIntValue );
4174 for ( size_t iC = 0; iC < comps->length(); ++iC )
4175 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4179 fieldWriter.Perform();
4180 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4181 if ( res && res->IsKO() )
4183 if ( res->myComment.empty() )
4184 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4186 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4192 if ( !geomAssocFields || !geomAssocFields[0] )
4195 // write geomAssocFields
4197 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4198 shapeDim[ TopAbs_COMPOUND ] = 3;
4199 shapeDim[ TopAbs_COMPSOLID ] = 3;
4200 shapeDim[ TopAbs_SOLID ] = 3;
4201 shapeDim[ TopAbs_SHELL ] = 2;
4202 shapeDim[ TopAbs_FACE ] = 2;
4203 shapeDim[ TopAbs_WIRE ] = 1;
4204 shapeDim[ TopAbs_EDGE ] = 1;
4205 shapeDim[ TopAbs_VERTEX ] = 0;
4206 shapeDim[ TopAbs_SHAPE ] = 3;
4208 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4210 std::vector< std::string > compNames;
4211 switch ( geomAssocFields[ iF ]) {
4213 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4214 compNames.push_back( "dim" );
4217 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4220 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4223 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4227 compNames.push_back( "id" );
4228 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4229 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4231 fieldWriter.SetDtIt( -1, -1 );
4233 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4237 if ( compNames.size() == 2 ) // _vertices_
4238 while ( elemIt->more() )
4240 const SMDS_MeshElement* e = elemIt->next();
4241 const int shapeID = e->getshapeId();
4244 fieldWriter.AddValue( (double) -1 );
4245 fieldWriter.AddValue( (double) -1 );
4249 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4250 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4251 fieldWriter.AddValue( (double) shapeID );
4255 while ( elemIt->more() )
4257 const SMDS_MeshElement* e = elemIt->next();
4258 const int shapeID = e->getshapeId();
4260 fieldWriter.AddValue( (double) -1 );
4262 fieldWriter.AddValue( (double) shapeID );
4266 fieldWriter.Perform();
4267 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4268 if ( res && res->IsKO() )
4270 if ( res->myComment.empty() )
4271 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4273 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4276 } // loop on geomAssocFields
4281 //================================================================================
4283 * \brief Export a part of mesh to a DAT file
4285 //================================================================================
4287 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4289 throw (SALOME::SALOME_Exception)
4291 Unexpect aCatch(SALOME_SalomeException);
4293 _preMeshInfo->FullLoadFromFile();
4295 PrepareForWriting(file);
4297 SMESH_MeshPartDS partDS( meshPart );
4298 _impl->ExportDAT(file,&partDS);
4300 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4301 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4303 //================================================================================
4305 * \brief Export a part of mesh to an UNV file
4307 //================================================================================
4309 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4311 throw (SALOME::SALOME_Exception)
4313 Unexpect aCatch(SALOME_SalomeException);
4315 _preMeshInfo->FullLoadFromFile();
4317 PrepareForWriting(file);
4319 SMESH_MeshPartDS partDS( meshPart );
4320 _impl->ExportUNV(file, &partDS);
4322 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4323 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4325 //================================================================================
4327 * \brief Export a part of mesh to an STL file
4329 //================================================================================
4331 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4333 ::CORBA::Boolean isascii)
4334 throw (SALOME::SALOME_Exception)
4336 Unexpect aCatch(SALOME_SalomeException);
4338 _preMeshInfo->FullLoadFromFile();
4340 PrepareForWriting(file);
4342 CORBA::String_var name;
4343 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4344 if ( !so->_is_nil() )
4345 name = so->GetName();
4347 SMESH_MeshPartDS partDS( meshPart );
4348 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4350 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4351 << meshPart<< ", r'" << file << "', " << isascii << ")";
4354 //================================================================================
4356 * \brief Export a part of mesh to an STL file
4358 //================================================================================
4360 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4362 CORBA::Boolean overwrite,
4363 CORBA::Boolean groupElemsByType)
4364 throw (SALOME::SALOME_Exception)
4367 Unexpect aCatch(SALOME_SalomeException);
4369 _preMeshInfo->FullLoadFromFile();
4371 PrepareForWriting(file,overwrite);
4373 std::string meshName("");
4374 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4375 if ( !so->_is_nil() )
4377 CORBA::String_var name = so->GetName();
4378 meshName = name.in();
4382 SMESH_MeshPartDS partDS( meshPart );
4383 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4385 SMESH_CATCH( SMESH::throwCorbaException );
4387 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4388 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4390 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4394 //================================================================================
4396 * \brief Export a part of mesh to a GMF file
4398 //================================================================================
4400 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4402 bool withRequiredGroups)
4403 throw (SALOME::SALOME_Exception)
4405 Unexpect aCatch(SALOME_SalomeException);
4407 _preMeshInfo->FullLoadFromFile();
4409 PrepareForWriting(file,/*overwrite=*/true);
4411 SMESH_MeshPartDS partDS( meshPart );
4412 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4414 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4415 << meshPart<< ", r'"
4417 << withRequiredGroups << ")";
4420 //=============================================================================
4422 * Return computation progress [0.,1]
4424 //=============================================================================
4426 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4430 return _impl->GetComputeProgress();
4432 SMESH_CATCH( SMESH::doNothing );
4436 //================================================================================
4438 * \brief Return nb of nodes
4440 //================================================================================
4442 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4444 Unexpect aCatch(SALOME_SalomeException);
4446 return _preMeshInfo->NbNodes();
4448 return _impl->NbNodes();
4451 //================================================================================
4453 * \brief Return nb of elements
4455 //================================================================================
4457 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4459 Unexpect aCatch(SALOME_SalomeException);
4461 return _preMeshInfo->NbElements();
4463 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4466 //================================================================================
4468 * \brief Return nb of 0D elements
4470 //================================================================================
4472 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4474 Unexpect aCatch(SALOME_SalomeException);
4476 return _preMeshInfo->Nb0DElements();
4478 return _impl->Nb0DElements();
4481 //================================================================================
4483 * \brief Return nb of BALL elements
4485 //================================================================================
4487 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4489 Unexpect aCatch(SALOME_SalomeException);
4491 return _preMeshInfo->NbBalls();
4493 return _impl->NbBalls();
4496 //================================================================================
4498 * \brief Return nb of 1D elements
4500 //================================================================================
4502 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4504 Unexpect aCatch(SALOME_SalomeException);
4506 return _preMeshInfo->NbEdges();
4508 return _impl->NbEdges();
4511 //================================================================================
4513 * \brief Return nb of edges
4515 //================================================================================
4517 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4518 throw(SALOME::SALOME_Exception)
4520 Unexpect aCatch(SALOME_SalomeException);
4522 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4524 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4527 //================================================================================
4529 * \brief Return nb of faces
4531 //================================================================================
4533 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4535 Unexpect aCatch(SALOME_SalomeException);
4537 return _preMeshInfo->NbFaces();
4539 return _impl->NbFaces();
4542 //================================================================================
4544 * \brief Return nb of tringles
4546 //================================================================================
4548 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4550 Unexpect aCatch(SALOME_SalomeException);
4552 return _preMeshInfo->NbTriangles();
4554 return _impl->NbTriangles();
4557 //================================================================================
4559 * \brief Return nb of bi-quadratic triangles
4561 //================================================================================
4563 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4565 Unexpect aCatch(SALOME_SalomeException);
4567 return _preMeshInfo->NbBiQuadTriangles();
4569 return _impl->NbBiQuadTriangles();
4572 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4574 Unexpect aCatch(SALOME_SalomeException);
4576 return _preMeshInfo->NbQuadrangles();
4578 return _impl->NbQuadrangles();
4581 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4583 Unexpect aCatch(SALOME_SalomeException);
4585 return _preMeshInfo->NbBiQuadQuadrangles();
4587 return _impl->NbBiQuadQuadrangles();
4590 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4592 Unexpect aCatch(SALOME_SalomeException);
4594 return _preMeshInfo->NbPolygons();
4596 return _impl->NbPolygons();
4599 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4601 Unexpect aCatch(SALOME_SalomeException);
4603 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4605 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4608 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4609 throw(SALOME::SALOME_Exception)
4611 Unexpect aCatch(SALOME_SalomeException);
4613 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4615 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4618 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4619 throw(SALOME::SALOME_Exception)
4621 Unexpect aCatch(SALOME_SalomeException);
4623 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4625 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4628 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4629 throw(SALOME::SALOME_Exception)
4631 Unexpect aCatch(SALOME_SalomeException);
4633 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4635 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4638 //=============================================================================
4640 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4642 Unexpect aCatch(SALOME_SalomeException);
4644 return _preMeshInfo->NbVolumes();
4646 return _impl->NbVolumes();
4649 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4651 Unexpect aCatch(SALOME_SalomeException);
4653 return _preMeshInfo->NbTetras();
4655 return _impl->NbTetras();
4658 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4660 Unexpect aCatch(SALOME_SalomeException);
4662 return _preMeshInfo->NbHexas();
4664 return _impl->NbHexas();
4667 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4669 Unexpect aCatch(SALOME_SalomeException);
4671 return _preMeshInfo->NbTriQuadHexas();
4673 return _impl->NbTriQuadraticHexas();
4676 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4678 Unexpect aCatch(SALOME_SalomeException);
4680 return _preMeshInfo->NbPyramids();
4682 return _impl->NbPyramids();
4685 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4687 Unexpect aCatch(SALOME_SalomeException);
4689 return _preMeshInfo->NbPrisms();
4691 return _impl->NbPrisms();
4694 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4696 Unexpect aCatch(SALOME_SalomeException);
4698 return _preMeshInfo->NbHexPrisms();
4700 return _impl->NbHexagonalPrisms();
4703 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4705 Unexpect aCatch(SALOME_SalomeException);
4707 return _preMeshInfo->NbPolyhedrons();
4709 return _impl->NbPolyhedrons();
4712 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4713 throw(SALOME::SALOME_Exception)
4715 Unexpect aCatch(SALOME_SalomeException);
4717 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4719 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4722 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4723 throw(SALOME::SALOME_Exception)
4725 Unexpect aCatch(SALOME_SalomeException);
4727 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4729 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4732 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4733 throw(SALOME::SALOME_Exception)
4735 Unexpect aCatch(SALOME_SalomeException);
4737 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4739 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4742 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4743 throw(SALOME::SALOME_Exception)
4745 Unexpect aCatch(SALOME_SalomeException);
4747 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4749 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4752 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4753 throw(SALOME::SALOME_Exception)
4755 Unexpect aCatch(SALOME_SalomeException);
4757 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4759 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4762 //=============================================================================
4764 * Return nb of published sub-meshes
4766 //=============================================================================
4768 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4770 Unexpect aCatch(SALOME_SalomeException);
4771 return _mapSubMesh_i.size();
4774 //=============================================================================
4776 * Dumps mesh into a string
4778 //=============================================================================
4780 char* SMESH_Mesh_i::Dump()
4784 return CORBA::string_dup( os.str().c_str() );
4787 //=============================================================================
4789 * Method of SMESH_IDSource interface
4791 //=============================================================================
4793 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4795 return GetElementsId();
4798 //=============================================================================
4800 * Return ids of all elements
4802 //=============================================================================
4804 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4805 throw (SALOME::SALOME_Exception)
4807 Unexpect aCatch(SALOME_SalomeException);
4809 _preMeshInfo->FullLoadFromFile();
4811 SMESH::long_array_var aResult = new SMESH::long_array();
4812 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4814 if ( aSMESHDS_Mesh == NULL )
4815 return aResult._retn();
4817 long nbElements = NbElements();
4818 aResult->length( nbElements );
4819 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4820 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4821 aResult[i] = anIt->next()->GetID();
4823 return aResult._retn();
4827 //=============================================================================
4829 * Return ids of all elements of given type
4831 //=============================================================================
4833 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4834 throw (SALOME::SALOME_Exception)
4836 Unexpect aCatch(SALOME_SalomeException);
4838 _preMeshInfo->FullLoadFromFile();
4840 SMESH::long_array_var aResult = new SMESH::long_array();
4841 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4843 if ( aSMESHDS_Mesh == NULL )
4844 return aResult._retn();
4846 long nbElements = NbElements();
4848 // No sense in returning ids of elements along with ids of nodes:
4849 // when theElemType == SMESH::ALL, return node ids only if
4850 // there are no elements
4851 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4852 return GetNodesId();
4854 aResult->length( nbElements );
4858 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4859 while ( i < nbElements && anIt->more() )
4860 aResult[i++] = anIt->next()->GetID();
4862 aResult->length( i );
4864 return aResult._retn();
4867 //=============================================================================
4869 * Return ids of all nodes
4871 //=============================================================================
4873 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4874 throw (SALOME::SALOME_Exception)
4876 Unexpect aCatch(SALOME_SalomeException);
4878 _preMeshInfo->FullLoadFromFile();
4880 SMESH::long_array_var aResult = new SMESH::long_array();
4881 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4883 if ( aMeshDS == NULL )
4884 return aResult._retn();
4886 long nbNodes = NbNodes();
4887 aResult->length( nbNodes );
4888 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4889 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4890 aResult[i] = anIt->next()->GetID();
4892 return aResult._retn();
4895 //=============================================================================
4897 * Return type of the given element
4899 //=============================================================================
4901 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4902 throw (SALOME::SALOME_Exception)
4904 SMESH::ElementType type = SMESH::ALL;
4908 _preMeshInfo->FullLoadFromFile();
4910 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4912 SMESH_CATCH( SMESH::throwCorbaException );
4917 //=============================================================================
4919 * Return geometric type of the given element
4921 //=============================================================================
4923 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4924 throw (SALOME::SALOME_Exception)
4927 _preMeshInfo->FullLoadFromFile();
4929 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4931 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4933 return ( SMESH::EntityType ) e->GetEntityType();
4936 //=============================================================================
4938 * Return type of the given element
4940 //=============================================================================
4942 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4943 throw (SALOME::SALOME_Exception)
4946 _preMeshInfo->FullLoadFromFile();
4948 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4950 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4952 return ( SMESH::GeometryType ) e->GetGeomType();
4955 //=============================================================================
4957 * Return ID of elements for given submesh
4959 //=============================================================================
4961 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4962 throw (SALOME::SALOME_Exception)
4964 SMESH::long_array_var aResult = new SMESH::long_array();
4968 _preMeshInfo->FullLoadFromFile();
4970 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4971 if(!SM) return aResult._retn();
4973 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4974 if(!SDSM) return aResult._retn();
4976 aResult->length(SDSM->NbElements());
4978 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4980 while ( eIt->more() ) {
4981 aResult[i++] = eIt->next()->GetID();
4984 SMESH_CATCH( SMESH::throwCorbaException );
4986 return aResult._retn();
4989 //=============================================================================
4991 * Return ID of nodes for given sub-mesh
4992 * If param all==true - return all nodes, else -
4993 * Return only nodes on shapes.
4995 //=============================================================================
4997 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4999 throw (SALOME::SALOME_Exception)
5001 SMESH::long_array_var aResult = new SMESH::long_array();
5005 _preMeshInfo->FullLoadFromFile();
5007 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5008 if(!SM) return aResult._retn();
5010 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5011 if(!SDSM) return aResult._retn();
5014 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
5015 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
5016 while ( nIt->more() ) {
5017 const SMDS_MeshNode* elem = nIt->next();
5018 theElems.insert( elem->GetID() );
5021 else { // all nodes of submesh elements
5022 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5023 while ( eIt->more() ) {
5024 const SMDS_MeshElement* anElem = eIt->next();
5025 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
5026 while ( nIt->more() ) {
5027 const SMDS_MeshElement* elem = nIt->next();
5028 theElems.insert( elem->GetID() );
5033 aResult->length(theElems.size());
5034 set<int>::iterator itElem;
5036 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
5037 aResult[i++] = *itElem;
5039 SMESH_CATCH( SMESH::throwCorbaException );
5041 return aResult._retn();
5044 //=============================================================================
5046 * Return type of elements for given sub-mesh
5048 //=============================================================================
5050 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
5051 throw (SALOME::SALOME_Exception)
5053 SMESH::ElementType type = SMESH::ALL;
5057 _preMeshInfo->FullLoadFromFile();
5059 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5060 if(!SM) return SMESH::ALL;
5062 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5063 if(!SDSM) return SMESH::ALL;
5065 if(SDSM->NbElements()==0)
5066 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
5068 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5069 const SMDS_MeshElement* anElem = eIt->next();
5071 type = ( SMESH::ElementType ) anElem->GetType();
5073 SMESH_CATCH( SMESH::throwCorbaException );
5079 //=============================================================================
5081 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5083 //=============================================================================
5085 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5088 _preMeshInfo->FullLoadFromFile();
5090 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5091 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5096 //=============================================================================
5098 * Get XYZ coordinates of node as list of double
5099 * If there is not node for given ID - return empty list
5101 //=============================================================================
5103 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5106 _preMeshInfo->FullLoadFromFile();
5108 SMESH::double_array_var aResult = new SMESH::double_array();
5109 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5110 if ( aMeshDS == NULL )
5111 return aResult._retn();
5114 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5116 return aResult._retn();
5120 aResult[0] = aNode->X();
5121 aResult[1] = aNode->Y();
5122 aResult[2] = aNode->Z();
5123 return aResult._retn();
5127 //=============================================================================
5129 * For given node return list of IDs of inverse elements
5130 * If there is not node for given ID - return empty list
5132 //=============================================================================
5134 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5135 SMESH::ElementType elemType)
5138 _preMeshInfo->FullLoadFromFile();
5140 SMESH::long_array_var aResult = new SMESH::long_array();
5141 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5142 if ( aMeshDS == NULL )
5143 return aResult._retn();
5146 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5148 return aResult._retn();
5150 // find inverse elements
5151 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5152 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5153 aResult->length( aNode->NbInverseElements( type ));
5154 for( int i = 0; eIt->more(); ++i )
5156 const SMDS_MeshElement* elem = eIt->next();
5157 aResult[ i ] = elem->GetID();
5159 return aResult._retn();
5162 //=============================================================================
5164 * \brief Return position of a node on shape
5166 //=============================================================================
5168 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5171 _preMeshInfo->FullLoadFromFile();
5173 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5174 aNodePosition->shapeID = 0;
5175 aNodePosition->shapeType = GEOM::SHAPE;
5177 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5178 if ( !mesh ) return aNodePosition;
5180 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5182 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5184 aNodePosition->shapeID = aNode->getshapeId();
5185 switch ( pos->GetTypeOfPosition() ) {
5187 aNodePosition->shapeType = GEOM::EDGE;
5188 aNodePosition->params.length(1);
5189 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5191 case SMDS_TOP_FACE: {
5192 SMDS_FacePositionPtr fPos = pos;
5193 aNodePosition->shapeType = GEOM::FACE;
5194 aNodePosition->params.length(2);
5195 aNodePosition->params[0] = fPos->GetUParameter();
5196 aNodePosition->params[1] = fPos->GetVParameter();
5199 case SMDS_TOP_VERTEX:
5200 aNodePosition->shapeType = GEOM::VERTEX;
5202 case SMDS_TOP_3DSPACE:
5203 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5204 aNodePosition->shapeType = GEOM::SOLID;
5205 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5206 aNodePosition->shapeType = GEOM::SHELL;
5212 return aNodePosition;
5215 //=============================================================================
5217 * \brief Return position of an element on shape
5219 //=============================================================================
5221 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5224 _preMeshInfo->FullLoadFromFile();
5226 SMESH::ElementPosition anElementPosition;
5227 anElementPosition.shapeID = 0;
5228 anElementPosition.shapeType = GEOM::SHAPE;
5230 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5231 if ( !mesh ) return anElementPosition;
5233 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5235 anElementPosition.shapeID = anElem->getshapeId();
5236 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5237 if ( !aSp.IsNull() ) {
5238 switch ( aSp.ShapeType() ) {
5240 anElementPosition.shapeType = GEOM::EDGE;
5243 anElementPosition.shapeType = GEOM::FACE;
5246 anElementPosition.shapeType = GEOM::VERTEX;
5249 anElementPosition.shapeType = GEOM::SOLID;
5252 anElementPosition.shapeType = GEOM::SHELL;
5258 return anElementPosition;
5261 //=============================================================================
5263 * If given element is node return IDs of shape from position
5264 * If there is not node for given ID - return -1
5266 //=============================================================================
5268 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5271 _preMeshInfo->FullLoadFromFile();
5273 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5274 if ( aMeshDS == NULL )
5278 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5280 return aNode->getshapeId();
5287 //=============================================================================
5289 * For given element return ID of result shape after
5290 * ::FindShape() from SMESH_MeshEditor
5291 * If there is not element for given ID - return -1
5293 //=============================================================================
5295 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5298 _preMeshInfo->FullLoadFromFile();
5300 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5301 if ( aMeshDS == NULL )
5304 // try to find element
5305 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5309 ::SMESH_MeshEditor aMeshEditor(_impl);
5310 int index = aMeshEditor.FindShape( elem );
5318 //=============================================================================
5320 * Return number of nodes for given element
5321 * If there is not element for given ID - return -1
5323 //=============================================================================
5325 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5328 _preMeshInfo->FullLoadFromFile();
5330 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5331 if ( aMeshDS == NULL ) return -1;
5332 // try to find element
5333 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5334 if(!elem) return -1;
5335 return elem->NbNodes();
5339 //=============================================================================
5341 * Return ID of node by given index for given element
5342 * If there is not element for given ID - return -1
5343 * If there is not node for given index - return -2
5345 //=============================================================================
5347 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5350 _preMeshInfo->FullLoadFromFile();
5352 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5353 if ( aMeshDS == NULL ) return -1;
5354 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5355 if(!elem) return -1;
5356 if( index>=elem->NbNodes() || index<0 ) return -1;
5357 return elem->GetNode(index)->GetID();
5360 //=============================================================================
5362 * Return IDs of nodes of given element
5364 //=============================================================================
5366 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5369 _preMeshInfo->FullLoadFromFile();
5371 SMESH::long_array_var aResult = new SMESH::long_array();
5372 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5374 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5376 aResult->length( elem->NbNodes() );
5377 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5378 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5379 aResult[ i ] = n->GetID();
5382 return aResult._retn();
5385 //=============================================================================
5387 * Return true if given node is medium node
5388 * in given quadratic element
5390 //=============================================================================
5392 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5395 _preMeshInfo->FullLoadFromFile();
5397 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5398 if ( aMeshDS == NULL ) return false;
5400 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5401 if(!aNode) return false;
5402 // try to find element
5403 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5404 if(!elem) return false;
5406 return elem->IsMediumNode(aNode);
5410 //=============================================================================
5412 * Return true if given node is medium node
5413 * in one of quadratic elements
5415 //=============================================================================
5417 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5418 SMESH::ElementType theElemType)
5421 _preMeshInfo->FullLoadFromFile();
5423 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5424 if ( aMeshDS == NULL ) return false;
5427 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5428 if(!aNode) return false;
5430 SMESH_MesherHelper aHelper( *(_impl) );
5432 SMDSAbs_ElementType aType;
5433 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5434 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5435 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5436 else aType = SMDSAbs_All;
5438 return aHelper.IsMedium(aNode,aType);
5442 //=============================================================================
5444 * Return number of edges for given element
5446 //=============================================================================
5448 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5451 _preMeshInfo->FullLoadFromFile();
5453 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5454 if ( aMeshDS == NULL ) return -1;
5455 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5456 if(!elem) return -1;
5457 return elem->NbEdges();
5461 //=============================================================================
5463 * Return number of faces for given element
5465 //=============================================================================
5467 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5470 _preMeshInfo->FullLoadFromFile();
5472 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5473 if ( aMeshDS == NULL ) return -1;
5474 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5475 if(!elem) return -1;
5476 return elem->NbFaces();
5479 //================================================================================
5481 * \brief Return nodes of given face (counted from zero) for given element.
5483 //================================================================================
5485 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5486 CORBA::Short faceIndex)
5489 _preMeshInfo->FullLoadFromFile();
5491 SMESH::long_array_var aResult = new SMESH::long_array();
5492 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5494 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5496 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5497 if ( faceIndex < vtool.NbFaces() )
5499 aResult->length( vtool.NbFaceNodes( faceIndex ));
5500 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5501 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5502 aResult[ i ] = nn[ i ]->GetID();
5506 return aResult._retn();
5509 //================================================================================
5511 * \brief Return three components of normal of given mesh face.
5513 //================================================================================
5515 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5516 CORBA::Boolean normalized)
5519 _preMeshInfo->FullLoadFromFile();
5521 SMESH::double_array_var aResult = new SMESH::double_array();
5523 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5526 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5528 aResult->length( 3 );
5529 aResult[ 0 ] = normal.X();
5530 aResult[ 1 ] = normal.Y();
5531 aResult[ 2 ] = normal.Z();
5534 return aResult._retn();
5537 //================================================================================
5539 * \brief Return an element based on all given nodes.
5541 //================================================================================
5543 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5546 _preMeshInfo->FullLoadFromFile();
5548 CORBA::Long elemID(0);
5549 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5551 vector< const SMDS_MeshNode * > nn( nodes.length() );
5552 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5553 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5556 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5557 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5558 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5559 _impl->NbVolumes( ORDER_QUADRATIC )))
5560 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5562 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5567 //================================================================================
5569 * \brief Return elements including all given nodes.
5571 //================================================================================
5573 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5574 SMESH::ElementType elemType)
5577 _preMeshInfo->FullLoadFromFile();
5579 SMESH::long_array_var result = new SMESH::long_array();
5581 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5583 vector< const SMDS_MeshNode * > nn( nodes.length() );
5584 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5585 nn[i] = mesh->FindNode( nodes[i] );
5587 std::vector<const SMDS_MeshElement *> elems;
5588 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5589 result->length( elems.size() );
5590 for ( size_t i = 0; i < elems.size(); ++i )
5591 result[i] = elems[i]->GetID();
5593 return result._retn();
5596 //=============================================================================
5598 * Return true if given element is polygon
5600 //=============================================================================
5602 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5605 _preMeshInfo->FullLoadFromFile();
5607 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5608 if ( aMeshDS == NULL ) return false;
5609 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5610 if(!elem) return false;
5611 return elem->IsPoly();
5615 //=============================================================================
5617 * Return true if given element is quadratic
5619 //=============================================================================
5621 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5624 _preMeshInfo->FullLoadFromFile();
5626 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5627 if ( aMeshDS == NULL ) return false;
5628 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5629 if(!elem) return false;
5630 return elem->IsQuadratic();
5633 //=============================================================================
5635 * Return diameter of ball discrete element or zero in case of an invalid \a id
5637 //=============================================================================
5639 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5642 _preMeshInfo->FullLoadFromFile();
5644 if ( const SMDS_BallElement* ball =
5645 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5646 return ball->GetDiameter();
5651 //=============================================================================
5653 * Return bary center for given element
5655 //=============================================================================
5657 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5660 _preMeshInfo->FullLoadFromFile();
5662 SMESH::double_array_var aResult = new SMESH::double_array();
5663 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5664 if ( aMeshDS == NULL )
5665 return aResult._retn();
5667 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5669 return aResult._retn();
5671 if(elem->GetType()==SMDSAbs_Volume) {
5672 SMDS_VolumeTool aTool;
5673 if(aTool.Set(elem)) {
5675 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5680 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5682 double x=0., y=0., z=0.;
5683 for(; anIt->more(); ) {
5685 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5699 return aResult._retn();
5702 //================================================================================
5704 * \brief Create a group of elements preventing computation of a sub-shape
5706 //================================================================================
5708 SMESH::ListOfGroups*
5709 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5710 const char* theGroupName )
5711 throw ( SALOME::SALOME_Exception )
5713 Unexpect aCatch(SALOME_SalomeException);
5715 if ( !theGroupName || strlen( theGroupName) == 0 )
5716 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5718 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5719 ::SMESH_MeshEditor::ElemFeatures elemType;
5721 // submesh by subshape id
5722 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5723 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5726 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5727 if ( error && error->HasBadElems() )
5729 // sort bad elements by type
5730 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5731 const list<const SMDS_MeshElement*>& badElems =
5732 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5733 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5734 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5735 for ( ; elemIt != elemEnd; ++elemIt )
5737 const SMDS_MeshElement* elem = *elemIt;
5738 if ( !elem ) continue;
5740 if ( elem->GetID() < 1 )
5742 // elem is a temporary element, make a real element
5743 vector< const SMDS_MeshNode* > nodes;
5744 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5745 while ( nIt->more() && elem )
5747 nodes.push_back( nIt->next() );
5748 if ( nodes.back()->GetID() < 1 )
5749 elem = 0; // a temporary element on temporary nodes
5753 ::SMESH_MeshEditor editor( _impl );
5754 elem = editor.AddElement( nodes, elemType.Init( elem ));
5758 elemsByType[ elem->GetType() ].push_back( elem );
5761 // how many groups to create?
5763 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5764 nbTypes += int( !elemsByType[ i ].empty() );
5765 groups->length( nbTypes );
5768 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5770 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5771 if ( elems.empty() ) continue;
5773 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5774 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5776 SMESH::SMESH_Mesh_var mesh = _this();
5777 SALOMEDS::SObject_wrap aSO =
5778 _gen_i->PublishGroup( mesh, groups[ iG ],
5779 GEOM::GEOM_Object::_nil(), theGroupName);
5781 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5782 if ( !grp_i ) continue;
5784 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5785 for ( size_t iE = 0; iE < elems.size(); ++iE )
5786 grpDS->SMDSGroup().Add( elems[ iE ]);
5791 return groups._retn();
5794 //=============================================================================
5796 * Create and publish group servants if any groups were imported or created anyhow
5798 //=============================================================================
5800 void SMESH_Mesh_i::CreateGroupServants()
5802 SMESH::SMESH_Mesh_var aMesh = _this();
5805 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5806 while ( groupIt->more() )
5808 ::SMESH_Group* group = groupIt->next();
5809 int anId = group->GetID();
5811 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5812 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5814 addedIDs.insert( anId );
5816 SMESH_GroupBase_i* aGroupImpl;
5818 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5819 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5821 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5822 shape = groupOnGeom->GetShape();
5825 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5828 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5829 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5830 aGroupImpl->Register();
5832 // register CORBA object for persistence
5833 int nextId = _gen_i->RegisterObject( groupVar );
5834 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5835 else { nextId = 0; } // avoid "unused variable" warning in release mode
5837 // publishing the groups in the study
5838 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5839 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5842 if ( !addedIDs.empty() )
5845 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5846 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5848 set<int>::iterator it = addedIDs.find( i_grp->first );
5849 if ( it != addedIDs.end() )
5851 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5852 addedIDs.erase( it );
5853 if ( addedIDs.empty() )
5860 //=============================================================================
5862 * \brief Return true if all sub-meshes are computed OK - to update an icon
5864 //=============================================================================
5866 bool SMESH_Mesh_i::IsComputedOK()
5868 return _impl->IsComputedOK();
5871 //=============================================================================
5873 * \brief Return groups cantained in _mapGroups by their IDs
5875 //=============================================================================
5877 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5879 int nbGroups = groupIDs.size();
5880 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5881 aList->length( nbGroups );
5883 list<int>::const_iterator ids = groupIDs.begin();
5884 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5886 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5887 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5888 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5890 aList->length( nbGroups );
5891 return aList._retn();
5894 //=============================================================================
5896 * \brief Return information about imported file
5898 //=============================================================================
5900 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5902 SMESH::MedFileInfo_var res( _medFileInfo );
5903 if ( !res.operator->() ) {
5904 res = new SMESH::MedFileInfo;
5906 res->fileSize = res->major = res->minor = res->release = -1;
5911 //=======================================================================
5912 //function : FileInfoToString
5913 //purpose : Persistence of file info
5914 //=======================================================================
5916 std::string SMESH_Mesh_i::FileInfoToString()
5919 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5921 s = SMESH_Comment( _medFileInfo->fileSize )
5922 << " " << _medFileInfo->major
5923 << " " << _medFileInfo->minor
5924 << " " << _medFileInfo->release
5925 << " " << _medFileInfo->fileName;
5930 //=======================================================================
5931 //function : FileInfoFromString
5932 //purpose : Persistence of file info
5933 //=======================================================================
5935 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5937 std::string size, major, minor, release, fileName;
5938 std::istringstream is(info);
5939 is >> size >> major >> minor >> release;
5940 fileName = info.data() + ( size.size() + 1 +
5943 release.size()+ 1 );
5945 _medFileInfo = new SMESH::MedFileInfo();
5946 _medFileInfo->fileName = fileName.c_str();
5947 _medFileInfo->fileSize = atoi( size.c_str() );
5948 _medFileInfo->major = atoi( major.c_str() );
5949 _medFileInfo->minor = atoi( minor.c_str() );
5950 _medFileInfo->release = atoi( release.c_str() );
5953 //=============================================================================
5955 * \brief Pass names of mesh groups from study to mesh DS
5957 //=============================================================================
5959 void SMESH_Mesh_i::checkGroupNames()
5961 int nbGrp = NbGroups();
5965 SMESH::ListOfGroups* grpList = 0;
5966 // avoid dump of "GetGroups"
5968 // store python dump into a local variable inside local scope
5969 SMESH::TPythonDump pDump; // do not delete this line of code
5970 grpList = GetGroups();
5973 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5974 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5977 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5978 if ( aGrpSO->_is_nil() )
5980 // correct name of the mesh group if necessary
5981 const char* guiName = aGrpSO->GetName();
5982 if ( strcmp(guiName, aGrp->GetName()) )
5983 aGrp->SetName( guiName );
5987 //=============================================================================
5989 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
5991 //=============================================================================
5992 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5994 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5998 //=============================================================================
6000 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
6002 //=============================================================================
6004 char* SMESH_Mesh_i::GetParameters()
6006 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
6009 //=============================================================================
6011 * \brief Return list of notebook variables used for last Mesh operation
6013 //=============================================================================
6014 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
6016 SMESH::string_array_var aResult = new SMESH::string_array();
6017 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
6019 CORBA::String_var aParameters = GetParameters();
6020 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
6021 if ( aSections->length() > 0 ) {
6022 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
6023 aResult->length( aVars.length() );
6024 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
6025 aResult[i] = CORBA::string_dup( aVars[i] );
6028 return aResult._retn();
6031 //================================================================================
6033 * \brief Return types of elements it contains
6035 //================================================================================
6037 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
6040 return _preMeshInfo->GetTypes();
6042 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
6046 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
6047 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
6048 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
6049 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
6050 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
6051 if (_impl->NbNodes() &&
6052 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
6053 types->length( nbTypes );
6055 return types._retn();
6058 //================================================================================
6060 * \brief Return self
6062 //================================================================================
6064 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
6066 return SMESH::SMESH_Mesh::_duplicate( _this() );
6069 //================================================================================
6071 * \brief Return false if GetMeshInfo() return incorrect information that may
6072 * happen if mesh data is not yet fully loaded from the file of study.
6076 //================================================================================
6078 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6080 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6083 //=============================================================================
6085 * \brief Return number of mesh elements per each \a EntityType
6087 //=============================================================================
6089 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6092 return _preMeshInfo->GetMeshInfo();
6094 SMESH::long_array_var aRes = new SMESH::long_array();
6095 aRes->length(SMESH::Entity_Last);
6096 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6098 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6100 return aRes._retn();
6101 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6102 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6103 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6104 return aRes._retn();
6107 //=============================================================================
6109 * \brief Return number of mesh elements per each \a ElementType
6111 //=============================================================================
6113 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6115 SMESH::long_array_var aRes = new SMESH::long_array();
6116 aRes->length(SMESH::NB_ELEMENT_TYPES);
6117 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6120 const SMDS_MeshInfo* meshInfo = 0;
6122 meshInfo = _preMeshInfo;
6123 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6124 meshInfo = & meshDS->GetMeshInfo();
6127 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6128 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6130 return aRes._retn();
6133 //=============================================================================
6135 * Collect statistic of mesh elements given by iterator
6137 //=============================================================================
6139 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6140 SMESH::long_array& theInfo)
6142 if (!theItr) return;
6143 while (theItr->more())
6144 theInfo[ theItr->next()->GetEntityType() ]++;
6146 //=============================================================================
6148 * Return mesh unstructed grid information.
6150 //=============================================================================
6152 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6154 SALOMEDS::TMPFile_var SeqFile;
6155 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6156 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6158 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6159 aWriter->WriteToOutputStringOn();
6160 aWriter->SetInputData(aGrid);
6161 aWriter->SetFileTypeToBinary();
6163 char* str = aWriter->GetOutputString();
6164 int size = aWriter->GetOutputStringLength();
6166 //Allocate octet buffer of required size
6167 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6168 //Copy ostrstream content to the octet buffer
6169 memcpy(OctetBuf, str, size);
6170 //Create and return TMPFile
6171 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6175 return SeqFile._retn();
6178 //=============================================================================
6179 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6180 * SMESH::ElementType type) */
6182 using namespace SMESH::Controls;
6183 //-----------------------------------------------------------------------------
6184 struct PredicateIterator : public SMDS_ElemIterator
6186 SMDS_ElemIteratorPtr _elemIter;
6187 PredicatePtr _predicate;
6188 const SMDS_MeshElement* _elem;
6189 SMDSAbs_ElementType _type;
6191 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6192 PredicatePtr predicate,
6193 SMDSAbs_ElementType type):
6194 _elemIter(iterator), _predicate(predicate), _type(type)
6202 virtual const SMDS_MeshElement* next()
6204 const SMDS_MeshElement* res = _elem;
6206 while ( _elemIter->more() && !_elem )
6208 if ((_elem = _elemIter->next()) &&
6209 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6210 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6217 //-----------------------------------------------------------------------------
6218 struct IDSourceIterator : public SMDS_ElemIterator
6220 const CORBA::Long* _idPtr;
6221 const CORBA::Long* _idEndPtr;
6222 SMESH::long_array_var _idArray;
6223 const SMDS_Mesh* _mesh;
6224 const SMDSAbs_ElementType _type;
6225 const SMDS_MeshElement* _elem;
6227 IDSourceIterator( const SMDS_Mesh* mesh,
6228 const CORBA::Long* ids,
6230 SMDSAbs_ElementType type):
6231 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6233 if ( _idPtr && nbIds && _mesh )
6236 IDSourceIterator( const SMDS_Mesh* mesh,
6237 SMESH::long_array* idArray,
6238 SMDSAbs_ElementType type):
6239 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6241 if ( idArray && _mesh )
6243 _idPtr = &_idArray[0];
6244 _idEndPtr = _idPtr + _idArray->length();
6252 virtual const SMDS_MeshElement* next()
6254 const SMDS_MeshElement* res = _elem;
6256 while ( _idPtr < _idEndPtr && !_elem )
6258 if ( _type == SMDSAbs_Node )
6260 _elem = _mesh->FindNode( *_idPtr++ );
6262 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6263 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6271 //-----------------------------------------------------------------------------
6273 struct NodeOfElemIterator : public SMDS_ElemIterator
6275 TColStd_MapOfInteger _checkedNodeIDs;
6276 SMDS_ElemIteratorPtr _elemIter;
6277 SMDS_ElemIteratorPtr _nodeIter;
6278 const SMDS_MeshElement* _node;
6280 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6282 if ( _elemIter && _elemIter->more() )
6284 _nodeIter = _elemIter->next()->nodesIterator();
6292 virtual const SMDS_MeshElement* next()
6294 const SMDS_MeshElement* res = _node;
6296 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6298 if ( _nodeIter->more() )
6300 _node = _nodeIter->next();
6301 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6306 _nodeIter = _elemIter->next()->nodesIterator();
6314 //=============================================================================
6316 * Return iterator on elements of given type in given object
6318 //=============================================================================
6320 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6321 SMESH::ElementType theType)
6323 SMDS_ElemIteratorPtr elemIt;
6324 bool typeOK = ( theType == SMESH::ALL );
6325 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6327 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6328 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6329 if ( !mesh_i ) return elemIt;
6330 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6332 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6334 elemIt = meshDS->elementsIterator( elemType );
6337 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6339 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6342 elemIt = sm->GetElements();
6343 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6345 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6346 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6350 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6352 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6353 if ( groupDS && ( elemType == groupDS->GetType() ||
6354 elemType == SMDSAbs_Node ||
6355 elemType == SMDSAbs_All ))
6357 elemIt = groupDS->GetElements();
6358 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6361 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6363 if ( filter_i->GetElementType() == theType ||
6364 filter_i->GetElementType() == SMESH::ALL ||
6365 elemType == SMDSAbs_Node ||
6366 elemType == SMDSAbs_All)
6368 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6369 if ( pred_i && pred_i->GetPredicate() )
6371 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6372 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6373 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6374 elemIt = SMDS_ElemIteratorPtr
6375 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6376 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6382 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6383 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6384 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6386 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6387 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6390 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6391 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6395 SMESH::long_array_var ids = theObject->GetIDs();
6396 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6398 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6401 if ( elemIt && elemIt->more() && !typeOK )
6403 if ( elemType == SMDSAbs_Node )
6405 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6409 elemIt = SMDS_ElemIteratorPtr();
6415 //=============================================================================
6416 namespace // Finding concurrent hypotheses
6417 //=============================================================================
6421 * \brief mapping of mesh dimension into shape type
6423 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6425 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6427 case 0: aType = TopAbs_VERTEX; break;
6428 case 1: aType = TopAbs_EDGE; break;
6429 case 2: aType = TopAbs_FACE; break;
6431 default:aType = TopAbs_SOLID; break;
6436 //-----------------------------------------------------------------------------
6438 * \brief Internal structure used to find concurrent submeshes
6440 * It represents a pair < submesh, concurrent dimension >, where
6441 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6442 * with another submesh. In other words, it is dimension of a hypothesis assigned
6449 int _dim; //!< a dimension the algo can build (concurrent dimension)
6450 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6451 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6452 const SMESH_subMesh* _subMesh;
6453 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6455 //-----------------------------------------------------------------------------
6456 // Return the algorithm
6457 const SMESH_Algo* GetAlgo() const
6458 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6460 //-----------------------------------------------------------------------------
6462 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6464 const TopoDS_Shape& theShape)
6466 _subMesh = theSubMesh;
6467 SetShape( theDim, theShape );
6470 //-----------------------------------------------------------------------------
6472 void SetShape(const int theDim,
6473 const TopoDS_Shape& theShape)
6476 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6477 if (_dim >= _ownDim)
6478 _shapeMap.Add( theShape );
6480 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6481 for( ; anExp.More(); anExp.Next() )
6482 _shapeMap.Add( anExp.Current() );
6486 //-----------------------------------------------------------------------------
6487 //! Check sharing of sub-shapes
6488 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6489 const TopTools_MapOfShape& theToFind,
6490 const TopAbs_ShapeEnum theType)
6492 bool isShared = false;
6493 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6494 for (; !isShared && anItr.More(); anItr.Next() )
6496 const TopoDS_Shape aSubSh = anItr.Key();
6497 // check for case when concurrent dimensions are same
6498 isShared = theToFind.Contains( aSubSh );
6499 // check for sub-shape with concurrent dimension
6500 TopExp_Explorer anExp( aSubSh, theType );
6501 for ( ; !isShared && anExp.More(); anExp.Next() )
6502 isShared = theToFind.Contains( anExp.Current() );
6507 //-----------------------------------------------------------------------------
6508 //! check algorithms
6509 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6510 const SMESHDS_Hypothesis* theA2)
6512 if ( !theA1 || !theA2 ||
6513 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6514 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6515 return false; // one of the hypothesis is not algorithm
6516 // check algorithm names (should be equal)
6517 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6521 //-----------------------------------------------------------------------------
6522 //! Check if sub-shape hypotheses are concurrent
6523 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6525 if ( _subMesh == theOther->_subMesh )
6526 return false; // same sub-shape - should not be
6528 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6529 // any of the two submeshes is not on COMPOUND shape )
6530 // -> no concurrency
6531 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6532 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6533 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6534 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6535 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6538 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6539 if ( !checkSubShape )
6542 // check algorithms to be same
6543 const SMESH_Algo* a1 = this->GetAlgo();
6544 const SMESH_Algo* a2 = theOther->GetAlgo();
6545 bool isSame = checkAlgo( a1, a2 );
6549 // commented off for IPAL54678
6550 // if ( !a1 || !a2 )
6551 // return false; // pb?
6552 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6555 // check hypothesises for concurrence (skip first as algorithm)
6557 // pointers should be same, because it is referened from mesh hypothesis partition
6558 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6559 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6560 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6561 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6563 // the submeshes are concurrent if their algorithms has different parameters
6564 return nbSame != theOther->_hypotheses.size() - 1;
6567 // Return true if algorithm of this SMESH_DimHyp is used if no
6568 // sub-mesh order is imposed by the user
6569 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6571 // NeedDiscreteBoundary() algo has a higher priority
6572 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6573 theOther->GetAlgo()->NeedDiscreteBoundary() )
6574 return !this->GetAlgo()->NeedDiscreteBoundary();
6576 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6579 }; // end of SMESH_DimHyp
6580 //-----------------------------------------------------------------------------
6582 typedef list<const SMESH_DimHyp*> TDimHypList;
6584 //-----------------------------------------------------------------------------
6586 void addDimHypInstance(const int theDim,
6587 const TopoDS_Shape& theShape,
6588 const SMESH_Algo* theAlgo,
6589 const SMESH_subMesh* theSubMesh,
6590 const list <const SMESHDS_Hypothesis*>& theHypList,
6591 TDimHypList* theDimHypListArr )
6593 if ( !theAlgo->NeedDiscreteBoundary() &&
6594 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6596 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6597 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6599 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6600 dimHyp->_hypotheses.push_front(theAlgo);
6601 listOfdimHyp.push_back( dimHyp );
6604 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6605 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6606 theHypList.begin(), theHypList.end() );
6609 //-----------------------------------------------------------------------------
6610 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6611 TDimHypList& theListOfConcurr)
6613 if ( theListOfConcurr.empty() )
6615 theListOfConcurr.push_back( theDimHyp );
6619 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6620 while ( hypIt != theListOfConcurr.end() &&
6621 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6623 theListOfConcurr.insert( hypIt, theDimHyp );
6627 //-----------------------------------------------------------------------------
6628 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6629 const TDimHypList& theListOfDimHyp,
6630 TDimHypList& theListOfConcurrHyp,
6631 set<int>& theSetOfConcurrId )
6633 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6634 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6636 const SMESH_DimHyp* curDimHyp = *rIt;
6637 if ( curDimHyp == theDimHyp )
6638 break; // meet own dimHyp pointer in same dimension
6640 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6641 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6643 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6648 //-----------------------------------------------------------------------------
6649 void unionLists(TListOfInt& theListOfId,
6650 TListOfListOfInt& theListOfListOfId,
6653 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6654 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6657 continue; //skip already treated lists
6658 // check if other list has any same submesh object
6659 TListOfInt& otherListOfId = *it;
6660 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6661 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6664 // union two lists (from source into target)
6665 TListOfInt::iterator it2 = otherListOfId.begin();
6666 for ( ; it2 != otherListOfId.end(); it2++ ) {
6667 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6668 theListOfId.push_back(*it2);
6670 // clear source list
6671 otherListOfId.clear();
6674 //-----------------------------------------------------------------------------
6676 //! free memory allocated for dimension-hypothesis objects
6677 void removeDimHyps( TDimHypList* theArrOfList )
6679 for (int i = 0; i < 4; i++ ) {
6680 TDimHypList& listOfdimHyp = theArrOfList[i];
6681 TDimHypList::const_iterator it = listOfdimHyp.begin();
6682 for ( ; it != listOfdimHyp.end(); it++ )
6687 //-----------------------------------------------------------------------------
6689 * \brief find common submeshes with given submesh
6690 * \param theSubMeshList list of already collected submesh to check
6691 * \param theSubMesh given submesh to intersect with other
6692 * \param theCommonSubMeshes collected common submeshes
6694 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6695 const SMESH_subMesh* theSubMesh,
6696 set<const SMESH_subMesh*>& theCommon )
6700 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6701 for ( ; it != theSubMeshList.end(); it++ )
6702 theSubMesh->FindIntersection( *it, theCommon );
6703 theSubMeshList.push_back( theSubMesh );
6704 //theCommon.insert( theSubMesh );
6707 //-----------------------------------------------------------------------------
6708 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6710 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6711 for ( ; listsIt != smLists.end(); ++listsIt )
6713 const TListOfInt& smIDs = *listsIt;
6714 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6722 //=============================================================================
6724 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6726 //=============================================================================
6728 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6730 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6731 if ( isSubMeshInList( submeshID, anOrder ))
6734 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6735 return isSubMeshInList( submeshID, allConurrent );
6738 //=============================================================================
6740 * \brief Return sub-mesh objects list in meshing order
6742 //=============================================================================
6744 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6746 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6748 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6750 return aResult._retn();
6752 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6753 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6754 anOrder.splice( anOrder.end(), allConurrent );
6757 TListOfListOfInt::iterator listIt = anOrder.begin();
6758 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6759 unionLists( *listIt, anOrder, listIndx + 1 );
6761 // convert submesh ids into interface instances
6762 // and dump command into python
6763 convertMeshOrder( anOrder, aResult, false );
6765 return aResult._retn();
6768 //=============================================================================
6770 * \brief Finds concurrent sub-meshes
6772 //=============================================================================
6774 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6776 TListOfListOfInt anOrder;
6777 ::SMESH_Mesh& mesh = GetImpl();
6779 // collect submeshes and detect concurrent algorithms and hypothesises
6780 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6782 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6783 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6785 ::SMESH_subMesh* sm = (*i_sm).second;
6787 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6789 // list of assigned hypothesises
6790 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6791 // Find out dimensions where the submesh can be concurrent.
6792 // We define the dimensions by algo of each of hypotheses in hypList
6793 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6794 for( ; hypIt != hypList.end(); hypIt++ )
6796 SMESH_Algo* anAlgo = 0;
6797 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6798 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6799 // hyp it-self is algo
6800 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6802 // try to find algorithm with help of sub-shapes
6803 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6804 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6805 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6808 continue; // no algorithm assigned to a current submesh
6810 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6811 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6812 // and !anAlgo->NeedLowerHyps( dim ))
6814 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6815 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6816 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6818 } // end iterations on submesh
6820 // iterate on created dimension-hypotheses and check for concurrents
6821 for ( int i = 0; i < 4; i++ )
6823 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6824 // check for concurrents in own and other dimensions (step-by-step)
6825 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6826 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6828 const SMESH_DimHyp* dimHyp = *dhIt;
6829 TDimHypList listOfConcurr;
6830 set<int> setOfConcurrIds;
6831 // looking for concurrents and collect into own list
6832 for ( int j = i; j < 4; j++ )
6833 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6834 // check if any concurrents found
6835 if ( listOfConcurr.size() > 0 )
6837 // add own submesh to list of concurrent
6838 addInOrderOfPriority( dimHyp, listOfConcurr );
6839 list<int> listOfConcurrIds;
6840 TDimHypList::iterator hypIt = listOfConcurr.begin();
6841 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6842 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6843 anOrder.push_back( listOfConcurrIds );
6848 removeDimHyps(dimHypListArr);
6850 // now, minimize the number of concurrent groups
6851 // Here we assume that lists of submeshes can have same submesh
6852 // in case of multi-dimension algorithms, as result
6853 // list with common submesh has to be united into one list
6855 TListOfListOfInt::iterator listIt = anOrder.begin();
6856 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6857 unionLists( *listIt, anOrder, listIndx + 1 );
6862 //=============================================================================
6864 * \brief Set submesh object order
6865 * \param theSubMeshArray submesh array order
6867 //=============================================================================
6869 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6872 _preMeshInfo->ForgetOrLoad();
6875 ::SMESH_Mesh& mesh = GetImpl();
6877 TPythonDump aPythonDump; // prevent dump of called methods
6878 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6880 TListOfListOfInt subMeshOrder;
6881 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6883 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6884 TListOfInt subMeshIds;
6886 aPythonDump << ", ";
6887 aPythonDump << "[ ";
6888 // Collect subMeshes which should be clear
6889 // do it list-by-list, because modification of submesh order
6890 // take effect between concurrent submeshes only
6891 set<const SMESH_subMesh*> subMeshToClear;
6892 list<const SMESH_subMesh*> subMeshList;
6893 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6895 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6897 aPythonDump << ", ";
6898 aPythonDump << subMesh;
6899 subMeshIds.push_back( subMesh->GetId() );
6900 // detect common parts of submeshes
6901 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6902 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6904 aPythonDump << " ]";
6905 subMeshOrder.push_back( subMeshIds );
6907 // clear collected sub-meshes
6908 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6909 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6910 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6912 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6913 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6914 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6917 aPythonDump << " ])";
6919 mesh.SetMeshOrder( subMeshOrder );
6922 SMESH::SMESH_Mesh_var me = _this();
6923 _gen_i->UpdateIcons( me );
6928 //=============================================================================
6930 * \brief Convert submesh ids into submesh interfaces
6932 //=============================================================================
6934 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6935 SMESH::submesh_array_array& theResOrder,
6936 const bool theIsDump)
6938 int nbSet = theIdsOrder.size();
6939 TPythonDump aPythonDump; // prevent dump of called methods
6941 aPythonDump << "[ ";
6942 theResOrder.length(nbSet);
6943 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6945 for( ; it != theIdsOrder.end(); it++ )
6947 // translate submesh identificators into submesh objects
6948 // takeing into account real number of concurrent lists
6949 const TListOfInt& aSubOrder = (*it);
6950 if (!aSubOrder.size())
6953 aPythonDump << "[ ";
6954 // convert shape indices into interfaces
6955 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6956 aResSubSet->length(aSubOrder.size());
6957 TListOfInt::const_iterator subIt = aSubOrder.begin();
6959 for( j = 0; subIt != aSubOrder.end(); subIt++ )
6961 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6963 SMESH::SMESH_subMesh_var subMesh =
6964 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6967 aPythonDump << ", ";
6968 aPythonDump << subMesh;
6970 aResSubSet[ j++ ] = subMesh;
6973 aPythonDump << " ]";
6975 theResOrder[ listIndx++ ] = aResSubSet;
6977 // correct number of lists
6978 theResOrder.length( listIndx );
6981 // finilise python dump
6982 aPythonDump << " ]";
6983 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6987 namespace // utils used by SMESH_MeshPartDS
6990 * \brief Class used to access to protected data of SMDS_MeshInfo
6992 struct TMeshInfo : public SMDS_MeshInfo
6994 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6997 * \brief Element holing its ID only
6999 struct TElemID : public SMDS_LinearEdge
7001 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
7005 //================================================================================
7007 // Implementation of SMESH_MeshPartDS
7009 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
7010 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
7012 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
7013 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
7016 _meshDS = mesh_i->GetImpl().GetMeshDS();
7018 SetPersistentId( _meshDS->GetPersistentId() );
7020 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
7022 // <meshPart> is the whole mesh
7023 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
7025 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
7026 myGroupSet = _meshDS->GetGroups();
7031 SMESH::long_array_var anIDs = meshPart->GetIDs();
7032 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
7033 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
7035 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7036 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
7037 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7042 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7043 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
7044 if ( _elements[ e->GetType() ].insert( e ).second )
7047 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7048 while ( nIt->more() )
7050 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7051 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7058 ShapeToMesh( _meshDS->ShapeToMesh() );
7060 _meshDS = 0; // to enforce iteration on _elements and _nodes
7063 // -------------------------------------------------------------------------------------
7064 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
7065 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
7068 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
7069 for ( ; partIt != meshPart.end(); ++partIt )
7070 if ( const SMDS_MeshElement * e = *partIt )
7071 if ( _elements[ e->GetType() ].insert( e ).second )
7074 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7075 while ( nIt->more() )
7077 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7078 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7084 // -------------------------------------------------------------------------------------
7085 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7087 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7089 TElemID elem( IDelem );
7090 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7091 if ( !_elements[ iType ].empty() )
7093 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7094 if ( it != _elements[ iType ].end() )
7099 // -------------------------------------------------------------------------------------
7100 bool SMESH_MeshPartDS::HasNumerationHoles()
7102 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7104 return ( MinNodeID() != 1 ||
7105 MaxNodeID() != NbNodes() ||
7106 MinElementID() != 1 ||
7107 MaxElementID() != NbElements() );
7109 // -------------------------------------------------------------------------------------
7110 int SMESH_MeshPartDS::MaxNodeID() const
7112 if ( _meshDS ) return _meshDS->MaxNodeID();
7113 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7115 // -------------------------------------------------------------------------------------
7116 int SMESH_MeshPartDS::MinNodeID() const
7118 if ( _meshDS ) return _meshDS->MinNodeID();
7119 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7121 // -------------------------------------------------------------------------------------
7122 int SMESH_MeshPartDS::MaxElementID() const
7124 if ( _meshDS ) return _meshDS->MaxElementID();
7126 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7127 if ( !_elements[ iType ].empty() )
7128 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7131 // -------------------------------------------------------------------------------------
7132 int SMESH_MeshPartDS::MinElementID() const
7134 if ( _meshDS ) return _meshDS->MinElementID();
7136 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7137 if ( !_elements[ iType ].empty() )
7138 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7141 // -------------------------------------------------------------------------------------
7142 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7144 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7146 typedef SMDS_SetIterator
7147 <const SMDS_MeshElement*,
7148 TIDSortedElemSet::const_iterator,
7149 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7150 SMDS_MeshElement::GeomFilter
7153 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7155 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7156 _elements[type].end(),
7157 SMDS_MeshElement::GeomFilter( geomType )));
7159 // -------------------------------------------------------------------------------------
7160 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7162 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7164 typedef SMDS_SetIterator
7165 <const SMDS_MeshElement*,
7166 TIDSortedElemSet::const_iterator,
7167 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7168 SMDS_MeshElement::EntityFilter
7171 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7173 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7174 _elements[type].end(),
7175 SMDS_MeshElement::EntityFilter( entity )));
7177 // -------------------------------------------------------------------------------------
7178 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7180 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7181 if ( type == SMDSAbs_All && !_meshDS )
7183 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7185 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7186 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7188 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7190 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7191 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7193 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7194 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7196 // -------------------------------------------------------------------------------------
7197 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7198 iterType SMESH_MeshPartDS::methName() const \
7200 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7201 return _meshDS ? _meshDS->methName() : iterType \
7202 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7204 // -------------------------------------------------------------------------------------
7205 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7206 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7207 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7208 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7209 #undef _GET_ITER_DEFINE
7211 // END Implementation of SMESH_MeshPartDS
7213 //================================================================================