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 _preMeshInfo->ForgetOrLoad();
655 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
658 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
659 anErrorText = error.c_str();
661 SMESH::SMESH_Mesh_var mesh( _this() );
662 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
664 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
666 //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
667 if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ )
668 _gen_i->UpdateIcons( mesh );
670 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
672 // Update Python script
673 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
674 << aSubShape << ", " << anHyp << " )";
676 return ConvertHypothesisStatus(status);
679 //================================================================================
681 * \brief Create a sub-mesh and add a hypothesis to it
683 //================================================================================
685 SMESH_Hypothesis::Hypothesis_Status
686 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
687 SMESH::SMESH_Hypothesis_ptr anHyp,
688 std::string* anErrorText)
690 if(MYDEBUG) MESSAGE("addHypothesis");
692 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
693 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
695 if (CORBA::is_nil( anHyp ))
696 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
698 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
701 TopoDS_Shape myLocSubShape;
702 //use PseudoShape in case if mesh has no shape
704 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
706 myLocSubShape = _impl->GetShapeToMesh();
708 const int hypId = anHyp->GetId();
710 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
711 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
713 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
715 // assure there is a corresponding submesh
716 if ( !_impl->IsMainShape( myLocSubShape )) {
717 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
718 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
719 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
722 else if ( anErrorText )
724 *anErrorText = error;
727 catch(SALOME_Exception & S_ex)
729 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
734 //================================================================================
736 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
738 //================================================================================
740 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
741 SMESH::SMESH_Hypothesis_ptr anHyp)
742 throw(SALOME::SALOME_Exception)
744 Unexpect aCatch(SALOME_SalomeException);
746 _preMeshInfo->ForgetOrLoad();
748 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
749 SMESH::SMESH_Mesh_var mesh = _this();
751 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
753 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
754 _gen_i->UpdateIcons( mesh );
756 // Update Python script
757 if(_impl->HasShapeToMesh())
758 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
759 << aSubShape << ", " << anHyp << " )";
761 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
764 return ConvertHypothesisStatus(status);
767 //=============================================================================
769 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
771 //=============================================================================
773 SMESH_Hypothesis::Hypothesis_Status
774 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
775 SMESH::SMESH_Hypothesis_ptr anHyp)
777 if(MYDEBUG) MESSAGE("removeHypothesis()");
779 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
780 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
782 if (CORBA::is_nil( anHyp ))
783 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
786 _preMeshInfo->ForgetOrLoad();
788 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
791 TopoDS_Shape myLocSubShape;
792 //use PseudoShape in case if mesh has no shape
793 if( _impl->HasShapeToMesh() )
794 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
796 myLocSubShape = _impl->GetShapeToMesh();
798 const int hypId = anHyp->GetId();
799 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
800 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
802 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
806 catch(SALOME_Exception & S_ex)
808 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
813 //================================================================================
815 * \brief Return hypotheses assigned to a given sub-shape
817 //================================================================================
819 SMESH::ListOfHypothesis *
820 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (MYDEBUG) MESSAGE("GetHypothesisList");
825 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
826 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
828 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
831 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
833 myLocSubShape = _impl->GetShapeToMesh();
834 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
835 int i = 0, n = aLocalList.size();
838 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
839 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
840 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
842 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
843 if ( id_hypptr != _mapHypo.end() )
844 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
848 catch(SALOME_Exception & S_ex) {
849 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
852 return aList._retn();
855 //================================================================================
857 * \brief Return sub-meshes
859 //================================================================================
861 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
863 Unexpect aCatch(SALOME_SalomeException);
864 if (MYDEBUG) MESSAGE("GetSubMeshes");
866 SMESH::submesh_array_var aList = new SMESH::submesh_array();
869 TPythonDump aPythonDump;
870 if ( !_mapSubMeshIor.empty() )
874 aList->length( _mapSubMeshIor.size() );
876 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
877 for ( ; it != _mapSubMeshIor.end(); it++ ) {
878 if ( CORBA::is_nil( it->second )) continue;
879 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
881 if (i > 1) aPythonDump << ", ";
882 aPythonDump << it->second;
886 catch(SALOME_Exception & S_ex) {
887 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
890 // Update Python script
891 if ( !_mapSubMeshIor.empty() )
892 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
894 return aList._retn();
897 //================================================================================
899 * \brief Create and return a sub-mesh on the given sub-shape
901 //================================================================================
903 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
904 const char* theName )
905 throw(SALOME::SALOME_Exception)
907 Unexpect aCatch(SALOME_SalomeException);
908 if (CORBA::is_nil(aSubShape))
909 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
911 SMESH::SMESH_subMesh_var subMesh;
912 SMESH::SMESH_Mesh_var aMesh = _this();
914 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
916 //Get or Create the SMESH_subMesh object implementation
918 TopoDS_Iterator it( myLocSubShape );
919 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
920 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
921 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
922 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
926 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
928 subMesh = getSubMesh( subMeshId );
930 // create a new subMesh object servant if there is none for the shape
931 if ( subMesh->_is_nil() )
932 subMesh = createSubMesh( aSubShape );
933 if ( _gen_i->CanPublishInStudy( subMesh ))
935 SALOMEDS::SObject_wrap aSO =
936 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
937 if ( !aSO->_is_nil()) {
938 // Update Python script
939 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
940 << aSubShape << ", '" << theName << "' )";
944 catch(SALOME_Exception & S_ex) {
945 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
947 return subMesh._retn();
950 //================================================================================
952 * \brief Remove a sub-mesh
954 //================================================================================
956 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
957 throw (SALOME::SALOME_Exception)
961 if ( theSubMesh->_is_nil() )
964 GEOM::GEOM_Object_var aSubShape;
965 // Remove submesh's SObject
966 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
967 if ( !anSO->_is_nil() ) {
968 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
969 SALOMEDS::SObject_wrap anObj, aRef;
970 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
971 anObj->ReferencedObject( aRef.inout() ))
973 CORBA::Object_var obj = aRef->GetObject();
974 aSubShape = GEOM::GEOM_Object::_narrow( obj );
976 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
977 // aSubShape = theSubMesh->GetSubShape();
979 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
980 builder->RemoveObjectWithChildren( anSO );
982 // Update Python script
983 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
986 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
988 _preMeshInfo->ForgetOrLoad();
990 SMESH_CATCH( SMESH::throwCorbaException );
993 //================================================================================
995 * \brief Create a standalone group
997 //================================================================================
999 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1000 const char* theName )
1001 throw(SALOME::SALOME_Exception)
1003 Unexpect aCatch(SALOME_SalomeException);
1005 _preMeshInfo->FullLoadFromFile();
1007 SMESH::SMESH_Group_var aNewGroup =
1008 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1010 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1012 SMESH::SMESH_Mesh_var mesh = _this();
1013 SALOMEDS::SObject_wrap aSO =
1014 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1015 if ( !aSO->_is_nil())
1016 // Update Python script
1017 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1018 << theElemType << ", '" << theName << "' )";
1020 return aNewGroup._retn();
1023 //================================================================================
1025 * \brief Create a group based on the given geometry
1027 //================================================================================
1029 SMESH::SMESH_GroupOnGeom_ptr
1030 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1031 const char* theName,
1032 GEOM::GEOM_Object_ptr theGeomObj)
1033 throw(SALOME::SALOME_Exception)
1035 Unexpect aCatch(SALOME_SalomeException);
1037 _preMeshInfo->FullLoadFromFile();
1039 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1041 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1042 if ( !aShape.IsNull() )
1045 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1047 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1049 SMESH::SMESH_Mesh_var mesh = _this();
1050 SALOMEDS::SObject_wrap aSO =
1051 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1052 if ( !aSO->_is_nil())
1053 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1054 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1058 return aNewGroup._retn();
1061 //================================================================================
1063 * \brief Creates a group whose contents is defined by filter
1064 * \param theElemType - group type
1065 * \param theName - group name
1066 * \param theFilter - the filter
1067 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1069 //================================================================================
1071 SMESH::SMESH_GroupOnFilter_ptr
1072 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1073 const char* theName,
1074 SMESH::Filter_ptr theFilter )
1075 throw (SALOME::SALOME_Exception)
1077 Unexpect aCatch(SALOME_SalomeException);
1079 _preMeshInfo->FullLoadFromFile();
1081 if ( CORBA::is_nil( theFilter ))
1082 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1084 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1086 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1088 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1089 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1092 if ( !aNewGroup->_is_nil() )
1093 aNewGroup->SetFilter( theFilter );
1095 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1097 SMESH::SMESH_Mesh_var mesh = _this();
1098 SALOMEDS::SObject_wrap aSO =
1099 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1101 if ( !aSO->_is_nil())
1102 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1103 << theElemType << ", '" << theName << "', " << theFilter << " )";
1105 return aNewGroup._retn();
1108 //================================================================================
1110 * \brief Remove a group
1112 //================================================================================
1114 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1115 throw (SALOME::SALOME_Exception)
1117 if ( theGroup->_is_nil() )
1122 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1126 if ( aGroup->GetMeshServant() != this )
1127 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1128 SALOME::BAD_PARAM );
1130 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1131 if ( !aGroupSO->_is_nil() )
1133 // Update Python script
1134 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1136 // Remove group's SObject
1137 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1138 builder->RemoveObjectWithChildren( aGroupSO );
1140 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1142 // Remove the group from SMESH data structures
1143 removeGroup( aGroup->GetLocalID() );
1145 SMESH_CATCH( SMESH::throwCorbaException );
1148 //=============================================================================
1150 * Remove group with its contents
1152 //=============================================================================
1154 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1155 throw (SALOME::SALOME_Exception)
1159 _preMeshInfo->FullLoadFromFile();
1161 if ( theGroup->_is_nil() )
1164 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1165 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1166 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1169 vector<int> nodeIds; // to remove nodes becoming free
1170 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1171 if ( !isNodal && !theGroup->IsEmpty() )
1173 CORBA::Long elemID = theGroup->GetID( 1 );
1174 int nbElemNodes = GetElemNbNodes( elemID );
1175 if ( nbElemNodes > 0 )
1176 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1179 // Retrieve contents
1180 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1181 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1182 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1183 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1184 elems.assign( elemBeg, elemEnd );
1186 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1189 RemoveGroup( theGroup );
1192 for ( size_t i = 0; i < elems.size(); ++i )
1194 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1198 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1199 nodeIds.push_back( nIt->next()->GetID() );
1201 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1205 _impl->GetMeshDS()->RemoveElement( elems[i] );
1209 // Remove free nodes
1210 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1211 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1212 if ( n->NbInverseElements() == 0 )
1213 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1215 _impl->GetMeshDS()->Modified();
1216 _impl->SetIsModified( true );
1218 // Update Python script (theGroup must be alive for this)
1219 pyDump << SMESH::SMESH_Mesh_var(_this())
1220 << ".RemoveGroupWithContents( " << theGroup << " )";
1222 SMESH_CATCH( SMESH::throwCorbaException );
1225 //================================================================================
1227 * \brief Get the list of groups existing in the mesh
1228 * \retval SMESH::ListOfGroups * - list of groups
1230 //================================================================================
1232 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1234 Unexpect aCatch(SALOME_SalomeException);
1235 if (MYDEBUG) MESSAGE("GetGroups");
1237 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1240 TPythonDump aPythonDump;
1241 if ( !_mapGroups.empty() )
1243 aPythonDump << "[ ";
1245 aList->length( _mapGroups.size() );
1247 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1248 for ( ; it != _mapGroups.end(); it++ ) {
1249 if ( CORBA::is_nil( it->second )) continue;
1250 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1252 if (i > 1) aPythonDump << ", ";
1253 aPythonDump << it->second;
1257 catch(SALOME_Exception & S_ex) {
1258 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1260 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1262 return aList._retn();
1265 //=============================================================================
1267 * Get number of groups existing in the mesh
1269 //=============================================================================
1271 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1273 Unexpect aCatch(SALOME_SalomeException);
1274 return _mapGroups.size();
1277 //=============================================================================
1279 * New group including all mesh elements present in initial groups is created.
1281 //=============================================================================
1283 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1284 SMESH::SMESH_GroupBase_ptr theGroup2,
1285 const char* theName )
1286 throw (SALOME::SALOME_Exception)
1288 SMESH::SMESH_Group_var aResGrp;
1292 _preMeshInfo->FullLoadFromFile();
1294 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1295 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1297 if ( theGroup1->GetType() != theGroup2->GetType() )
1298 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1303 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1304 if ( aResGrp->_is_nil() )
1305 return SMESH::SMESH_Group::_nil();
1307 aResGrp->AddFrom( theGroup1 );
1308 aResGrp->AddFrom( theGroup2 );
1310 // Update Python script
1311 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1312 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1314 SMESH_CATCH( SMESH::throwCorbaException );
1316 return aResGrp._retn();
1319 //=============================================================================
1321 * \brief New group including all mesh elements present in initial groups is created.
1322 * \param theGroups list of groups
1323 * \param theName name of group to be created
1324 * \return pointer to the new group
1326 //=============================================================================
1328 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1329 const char* theName )
1330 throw (SALOME::SALOME_Exception)
1332 SMESH::SMESH_Group_var aResGrp;
1335 _preMeshInfo->FullLoadFromFile();
1338 return SMESH::SMESH_Group::_nil();
1343 SMESH::ElementType aType = SMESH::ALL;
1344 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1346 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1347 if ( CORBA::is_nil( aGrp ) )
1349 if ( aType == SMESH::ALL )
1350 aType = aGrp->GetType();
1351 else if ( aType != aGrp->GetType() )
1352 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1355 if ( aType == SMESH::ALL )
1356 return SMESH::SMESH_Group::_nil();
1361 aResGrp = CreateGroup( aType, theName );
1362 if ( aResGrp->_is_nil() )
1363 return SMESH::SMESH_Group::_nil();
1365 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1366 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1368 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1369 if ( !CORBA::is_nil( aGrp ) )
1371 aResGrp->AddFrom( aGrp );
1372 if ( g > 0 ) pyDump << ", ";
1376 pyDump << " ], '" << theName << "' )";
1378 SMESH_CATCH( SMESH::throwCorbaException );
1380 return aResGrp._retn();
1383 //=============================================================================
1385 * New group is created. All mesh elements that are
1386 * present in both initial groups are added to the new one.
1388 //=============================================================================
1390 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1391 SMESH::SMESH_GroupBase_ptr theGroup2,
1392 const char* theName )
1393 throw (SALOME::SALOME_Exception)
1395 SMESH::SMESH_Group_var aResGrp;
1400 _preMeshInfo->FullLoadFromFile();
1402 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1403 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1405 if ( theGroup1->GetType() != theGroup2->GetType() )
1406 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1410 // Create Intersection
1411 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1412 if ( aResGrp->_is_nil() )
1413 return aResGrp._retn();
1415 SMESHDS_GroupBase* groupDS1 = 0;
1416 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1417 groupDS1 = grp_i->GetGroupDS();
1419 SMESHDS_GroupBase* groupDS2 = 0;
1420 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1421 groupDS2 = grp_i->GetGroupDS();
1423 SMESHDS_Group* resGroupDS = 0;
1424 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1425 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1427 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1429 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1430 while ( elemIt1->more() )
1432 const SMDS_MeshElement* e = elemIt1->next();
1433 if ( groupDS2->Contains( e ))
1434 resGroupDS->SMDSGroup().Add( e );
1437 // Update Python script
1438 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1439 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1441 SMESH_CATCH( SMESH::throwCorbaException );
1443 return aResGrp._retn();
1446 //=============================================================================
1448 \brief Intersect list of groups. New group is created. All mesh elements that
1449 are present in all initial groups simultaneously are added to the new one.
1450 \param theGroups list of groups
1451 \param theName name of group to be created
1452 \return pointer on the group
1454 //=============================================================================
1456 SMESH::SMESH_Group_ptr
1457 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1458 const char* theName )
1459 throw (SALOME::SALOME_Exception)
1461 SMESH::SMESH_Group_var aResGrp;
1466 _preMeshInfo->FullLoadFromFile();
1469 return SMESH::SMESH_Group::_nil();
1471 // check types and get SMESHDS_GroupBase's
1472 SMESH::ElementType aType = SMESH::ALL;
1473 vector< SMESHDS_GroupBase* > groupVec;
1474 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1476 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1477 if ( CORBA::is_nil( aGrp ) )
1479 if ( aType == SMESH::ALL )
1480 aType = aGrp->GetType();
1481 else if ( aType != aGrp->GetType() )
1482 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1485 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1486 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1488 if ( grpDS->IsEmpty() )
1493 groupVec.push_back( grpDS );
1496 if ( aType == SMESH::ALL ) // all groups are nil
1497 return SMESH::SMESH_Group::_nil();
1502 aResGrp = CreateGroup( aType, theName );
1504 SMESHDS_Group* resGroupDS = 0;
1505 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1506 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1507 if ( !resGroupDS || groupVec.empty() )
1508 return aResGrp._retn();
1511 size_t i, nb = groupVec.size();
1512 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1513 while ( elemIt1->more() )
1515 const SMDS_MeshElement* e = elemIt1->next();
1517 for ( i = 1; ( i < nb && inAll ); ++i )
1518 inAll = groupVec[i]->Contains( e );
1521 resGroupDS->SMDSGroup().Add( e );
1524 // Update Python script
1525 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1526 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1528 SMESH_CATCH( SMESH::throwCorbaException );
1530 return aResGrp._retn();
1533 //=============================================================================
1535 * New group is created. All mesh elements that are present in
1536 * a main group but is not present in a tool group are added to the new one
1538 //=============================================================================
1540 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1541 SMESH::SMESH_GroupBase_ptr theGroup2,
1542 const char* theName )
1543 throw (SALOME::SALOME_Exception)
1545 SMESH::SMESH_Group_var aResGrp;
1550 _preMeshInfo->FullLoadFromFile();
1552 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1553 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1555 if ( theGroup1->GetType() != theGroup2->GetType() )
1556 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1560 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1561 if ( aResGrp->_is_nil() )
1562 return aResGrp._retn();
1564 SMESHDS_GroupBase* groupDS1 = 0;
1565 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1566 groupDS1 = grp_i->GetGroupDS();
1568 SMESHDS_GroupBase* groupDS2 = 0;
1569 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1570 groupDS2 = grp_i->GetGroupDS();
1572 SMESHDS_Group* resGroupDS = 0;
1573 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1574 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1576 if ( groupDS1 && groupDS2 && resGroupDS )
1578 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1579 while ( elemIt1->more() )
1581 const SMDS_MeshElement* e = elemIt1->next();
1582 if ( !groupDS2->Contains( e ))
1583 resGroupDS->SMDSGroup().Add( e );
1586 // Update Python script
1587 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1588 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1590 SMESH_CATCH( SMESH::throwCorbaException );
1592 return aResGrp._retn();
1595 //=============================================================================
1597 \brief Cut lists of groups. New group is created. All mesh elements that are
1598 present in main groups but do not present in tool groups are added to the new one
1599 \param theMainGroups list of main groups
1600 \param theToolGroups list of tool groups
1601 \param theName name of group to be created
1602 \return pointer on the group
1604 //=============================================================================
1606 SMESH::SMESH_Group_ptr
1607 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1608 const SMESH::ListOfGroups& theToolGroups,
1609 const char* theName )
1610 throw (SALOME::SALOME_Exception)
1612 SMESH::SMESH_Group_var aResGrp;
1617 _preMeshInfo->FullLoadFromFile();
1620 return SMESH::SMESH_Group::_nil();
1622 // check types and get SMESHDS_GroupBase's
1623 SMESH::ElementType aType = SMESH::ALL;
1624 vector< SMESHDS_GroupBase* > toolGroupVec;
1625 vector< SMDS_ElemIteratorPtr > mainIterVec;
1627 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1629 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1630 if ( CORBA::is_nil( aGrp ) )
1632 if ( aType == SMESH::ALL )
1633 aType = aGrp->GetType();
1634 else if ( aType != aGrp->GetType() )
1635 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1637 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1638 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1639 if ( !grpDS->IsEmpty() )
1640 mainIterVec.push_back( grpDS->GetElements() );
1642 if ( aType == SMESH::ALL ) // all main groups are nil
1643 return SMESH::SMESH_Group::_nil();
1644 if ( mainIterVec.empty() ) // all main groups are empty
1645 return aResGrp._retn();
1647 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1649 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1650 if ( CORBA::is_nil( aGrp ) )
1652 if ( aType != aGrp->GetType() )
1653 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1655 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1656 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1657 toolGroupVec.push_back( grpDS );
1663 aResGrp = CreateGroup( aType, theName );
1665 SMESHDS_Group* resGroupDS = 0;
1666 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1667 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1669 return aResGrp._retn();
1672 size_t i, nb = toolGroupVec.size();
1673 SMDS_ElemIteratorPtr mainElemIt
1674 ( new SMDS_IteratorOnIterators
1675 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1676 while ( mainElemIt->more() )
1678 const SMDS_MeshElement* e = mainElemIt->next();
1680 for ( i = 0; ( i < nb && !isIn ); ++i )
1681 isIn = toolGroupVec[i]->Contains( e );
1684 resGroupDS->SMDSGroup().Add( e );
1687 // Update Python script
1688 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1689 << ".CutListOfGroups( " << theMainGroups << ", "
1690 << theToolGroups << ", '" << theName << "' )";
1692 SMESH_CATCH( SMESH::throwCorbaException );
1694 return aResGrp._retn();
1697 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1699 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1700 bool & toStopChecking )
1702 toStopChecking = ( nbCommon < nbChecked );
1703 return nbCommon == nbNodes;
1705 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1706 bool & toStopChecking )
1708 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1709 return nbCommon == nbCorners;
1711 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1712 bool & toStopChecking )
1714 return nbCommon > 0;
1716 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1717 bool & toStopChecking )
1719 return nbCommon >= (nbNodes+1) / 2;
1723 //=============================================================================
1725 * Create a group of entities basing on nodes of other groups.
1726 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1727 * \param [in] anElemType - a type of elements to include to the new group.
1728 * \param [in] theName - a name of the new group.
1729 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1730 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1731 * new group provided that it is based on nodes of an element of \a aListOfGroups
1732 * \return SMESH_Group - the created group
1734 // IMP 19939, bug 22010, IMP 22635
1735 //=============================================================================
1737 SMESH::SMESH_Group_ptr
1738 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1739 SMESH::ElementType theElemType,
1740 const char* theName,
1741 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1742 CORBA::Boolean theUnderlyingOnly)
1743 throw (SALOME::SALOME_Exception)
1745 SMESH::SMESH_Group_var aResGrp;
1749 _preMeshInfo->FullLoadFromFile();
1751 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1753 if ( !theName || !aMeshDS )
1754 return SMESH::SMESH_Group::_nil();
1756 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1758 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1759 SMESH_Comment nbCoNoStr( "SMESH.");
1760 switch ( theNbCommonNodes ) {
1761 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1762 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1763 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1764 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1765 default: return aResGrp._retn();
1767 int nbChecked, nbCommon, nbNodes, nbCorners;
1773 aResGrp = CreateGroup( theElemType, theName );
1774 if ( aResGrp->_is_nil() )
1775 return SMESH::SMESH_Group::_nil();
1777 SMESHDS_GroupBase* groupBaseDS =
1778 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1779 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1781 vector<bool> isNodeInGroups;
1783 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1785 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1786 if ( CORBA::is_nil( aGrp ) )
1788 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1789 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1792 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1793 if ( !elIt ) continue;
1795 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1797 while ( elIt->more() ) {
1798 const SMDS_MeshElement* el = elIt->next();
1799 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1800 while ( nIt->more() )
1801 resGroupCore.Add( nIt->next() );
1804 // get elements of theElemType based on nodes of every element of group
1805 else if ( theUnderlyingOnly )
1807 while ( elIt->more() )
1809 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1810 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1811 TIDSortedElemSet checkedElems;
1812 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1813 while ( nIt->more() )
1815 const SMDS_MeshNode* n = nIt->next();
1816 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1817 // check nodes of elements of theElemType around el
1818 while ( elOfTypeIt->more() )
1820 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1821 if ( !checkedElems.insert( elOfType ).second ) continue;
1822 nbNodes = elOfType->NbNodes();
1823 nbCorners = elOfType->NbCornerNodes();
1825 bool toStopChecking = false;
1826 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1827 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1828 if ( elNodes.count( nIt2->next() ) &&
1829 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1831 resGroupCore.Add( elOfType );
1838 // get all nodes of elements of groups
1841 while ( elIt->more() )
1843 const SMDS_MeshElement* el = elIt->next(); // an element of group
1844 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1845 while ( nIt->more() )
1847 const SMDS_MeshNode* n = nIt->next();
1848 if ( n->GetID() >= (int) isNodeInGroups.size() )
1849 isNodeInGroups.resize( n->GetID() + 1, false );
1850 isNodeInGroups[ n->GetID() ] = true;
1856 // Get elements of theElemType based on a certain number of nodes of elements of groups
1857 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1859 const SMDS_MeshNode* n;
1860 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1861 const int isNodeInGroupsSize = isNodeInGroups.size();
1862 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1864 if ( !isNodeInGroups[ iN ] ||
1865 !( n = aMeshDS->FindNode( iN )))
1868 // check nodes of elements of theElemType around n
1869 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1870 while ( elOfTypeIt->more() )
1872 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1873 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1878 nbNodes = elOfType->NbNodes();
1879 nbCorners = elOfType->NbCornerNodes();
1881 bool toStopChecking = false;
1882 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1883 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1885 const int nID = nIt->next()->GetID();
1886 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1887 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1889 resGroupCore.Add( elOfType );
1897 // Update Python script
1898 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1899 << ".CreateDimGroup( "
1900 << theGroups << ", " << theElemType << ", '" << theName << "', "
1901 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1903 SMESH_CATCH( SMESH::throwCorbaException );
1905 return aResGrp._retn();
1908 //================================================================================
1910 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1911 * existing 1D elements as group boundaries.
1912 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1913 * adjacent faces is more than \a sharpAngle in degrees.
1914 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1915 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1916 * \return ListOfGroups - the created groups
1918 //================================================================================
1920 SMESH::ListOfGroups*
1921 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1922 CORBA::Boolean theCreateEdges,
1923 CORBA::Boolean theUseExistingEdges )
1924 throw (SALOME::SALOME_Exception)
1926 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1927 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1930 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1936 _preMeshInfo->FullLoadFromFile();
1938 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1940 std::vector< SMESH_MeshAlgos::Edge > edges =
1941 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1943 if ( theCreateEdges )
1945 std::vector<const SMDS_MeshNode *> nodes(2);
1946 for ( size_t i = 0; i < edges.size(); ++i )
1948 nodes[0] = edges[i]._node1;
1949 nodes[1] = edges[i]._node2;
1950 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1952 if ( edges[i]._medium )
1953 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1955 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1959 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1960 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1962 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1964 resultGroups->length( faceGroups.size() );
1965 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1967 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1968 _editor->GenerateGroupName("Group").c_str());
1969 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1971 SMESHDS_GroupBase* groupBaseDS =
1972 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1973 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1975 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1976 for ( size_t i = 0; i < faces.size(); ++i )
1977 groupCore.Add( faces[i] );
1980 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1981 << ".FaceGroupsSeparatedByEdges( "
1982 << TVar( theSharpAngle ) << ", "
1983 << theCreateEdges << ", "
1984 << theUseExistingEdges << " )";
1986 SMESH_CATCH( SMESH::throwCorbaException );
1987 return resultGroups._retn();
1991 //================================================================================
1993 * \brief Remember GEOM group data
1995 //================================================================================
1997 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1998 CORBA::Object_ptr theSmeshObj)
2000 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2003 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2004 if ( groupSO->_is_nil() )
2007 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2008 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2009 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2012 _geomGroupData.push_back( TGeomGroupData() );
2013 TGeomGroupData & groupData = _geomGroupData.back();
2015 CORBA::String_var entry = groupSO->GetID();
2016 groupData._groupEntry = entry.in();
2018 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2019 groupData._indices.insert( ids[i] );
2021 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2022 // shape index in SMESHDS
2023 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2024 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2027 //================================================================================
2029 * Remove GEOM group data relating to removed smesh object
2031 //================================================================================
2033 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2035 list<TGeomGroupData>::iterator
2036 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2037 for ( ; data != dataEnd; ++data ) {
2038 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2039 _geomGroupData.erase( data );
2045 //================================================================================
2047 * \brief Replace a shape in the mesh upon Break Link
2049 //================================================================================
2051 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2052 throw (SALOME::SALOME_Exception)
2054 // check if geometry changed
2055 bool geomChanged = true;
2056 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2057 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2058 geomChanged = ( oldGeom->GetTick() != theNewGeom->GetTick() );
2060 TopoDS_Shape S = _impl->GetShapeToMesh();
2061 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2062 TCollection_AsciiString aIOR;
2063 if ( geomClient->Find( S, aIOR ))
2064 geomClient->RemoveShapeFromBuffer( aIOR );
2066 // clear buffer also for sub-groups
2067 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2068 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2069 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2070 for (; g != groups.end(); ++g)
2071 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2073 const TopoDS_Shape& s = group->GetShape();
2074 if ( geomClient->Find( s, aIOR ))
2075 geomClient->RemoveShapeFromBuffer( aIOR );
2078 // clear buffer also for sub-meshes
2079 std::map<int, SMESH_subMesh_i*>::const_iterator aSubMeshIter = _mapSubMesh_i.cbegin();
2080 for(; aSubMeshIter != _mapSubMesh_i.cend(); aSubMeshIter++) {
2081 int aShapeID = aSubMeshIter->first;
2082 const TopoDS_Shape& aSubShape = meshDS->IndexToShape(aShapeID);
2083 TCollection_AsciiString aShapeIOR;
2084 if ( geomClient->Find( aSubShape, aShapeIOR ))
2085 geomClient->RemoveShapeFromBuffer( aShapeIOR );
2089 int shapeID, fromID, toID; // indices of elements of a sub-mesh
2091 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2092 std::vector< SMDS_PositionPtr > positions; // node positions
2095 // store positions of elements on geometry
2097 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2098 meshDS->MaxElementID() > meshDS->NbElements() )
2101 meshDS->CompactMesh();
2103 positions.resize( meshDS->NbNodes() + 1 );
2104 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2106 const SMDS_MeshNode* n = nodeIt->next();
2107 positions[ n->GetID() ] = n->GetPosition();
2110 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2111 for ( int isNode = 0; isNode < 2; ++isNode )
2113 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2114 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2115 ranges.push_back( TRange{ 0,0,0 });
2116 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2117 while ( elemIt->more() )
2119 const SMDS_MeshElement* e = elemIt->next();
2120 const int elemID = e->GetID();
2121 const int shapeID = e->GetShapeID();
2122 TRange & lastRange = ranges.back();
2123 if ( lastRange.shapeID != shapeID ||
2124 lastRange.toID != elemID )
2125 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2127 lastRange.toID = elemID + 1;
2129 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2131 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2132 else sm->RemoveElement( e );
2139 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2140 SMESH::SMESH_Mesh_var me = _this();
2141 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2142 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2143 if ( !aSO->_is_nil() )
2145 SALOMEDS::SObject_wrap aShapeRefSO;
2146 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2148 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2149 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2150 builder->Addreference( aShapeRefSO, aShapeSO );
2154 // re-assign global hypotheses to the new shape
2155 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2156 CheckGeomModif( true );
2160 // restore positions of elements on geometry
2161 for ( int isNode = 0; isNode < 2; ++isNode )
2163 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2164 for ( size_t i = 1; i < ranges.size(); ++i )
2166 int elemID = ranges[ i ].fromID;
2167 int toID = ranges[ i ].toID;
2168 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2170 for ( ; elemID < toID; ++elemID )
2171 smDS->AddNode( meshDS->FindNode( elemID ));
2173 for ( ; elemID < toID; ++elemID )
2174 smDS->AddElement( meshDS->FindElement( elemID ));
2176 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2177 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2180 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2181 if ( positions[ nodeID ])
2182 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2183 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2186 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2189 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2190 << me <<".GetMesh()), " << entry.in() << ")";
2192 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2196 //================================================================================
2198 * \brief Return new group contents if it has been changed and update group data
2200 //================================================================================
2202 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2204 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2206 TopoDS_Shape newShape;
2207 SALOMEDS::SObject_wrap groupSO;
2209 if ( how == IS_BREAK_LINK )
2211 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2212 SALOMEDS::SObject_wrap geomRefSO;
2213 if ( !meshSO->_is_nil() &&
2214 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2216 geomRefSO->ReferencedObject( groupSO.inout() );
2222 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2225 if ( groupSO->_is_nil() )
2228 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2229 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2230 if ( geomGroup->_is_nil() )
2233 // get indices of group items
2234 set<int> curIndices;
2235 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2236 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2237 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2238 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2239 curIndices.insert( ids[i] );
2241 bool sameIndices = ( groupData._indices == curIndices );
2242 if ( how == ONLY_IF_CHANGED && sameIndices )
2243 return newShape; // group not changed
2246 CORBA::String_var entry = geomGroup->GetStudyEntry();
2247 groupData._groupEntry = entry.in();
2248 groupData._indices = curIndices;
2250 newShape = _gen_i->GeomObjectToShape( geomGroup );
2252 // check if newShape is up-to-date
2253 if ( !newShape.IsNull() && ids->length() > 0 )
2255 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2258 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2259 for ( ; exp.More() && !toUpdate; exp.Next() )
2261 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2262 toUpdate = ( curIndices.erase( ind ) == 0 );
2264 if ( !curIndices.empty() )
2269 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2270 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2271 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2272 newShape = _gen_i->GeomObjectToShape( geomGroup );
2277 // geom group becomes empty - return empty compound
2278 TopoDS_Compound compound;
2279 BRep_Builder().MakeCompound(compound);
2280 newShape = compound;
2288 //-----------------------------------------------------------------------------
2290 * \brief Storage of shape and index used in CheckGeomGroupModif()
2292 struct TIndexedShape
2295 TopoDS_Shape _shape;
2296 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2298 //-----------------------------------------------------------------------------
2300 * \brief Data to re-create a group on geometry
2302 struct TGroupOnGeomData
2305 TopoDS_Shape _shape;
2306 SMDSAbs_ElementType _type;
2308 Quantity_Color _color;
2310 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2312 _oldID = group->GetID();
2313 _type = group->GetType();
2314 _name = group->GetStoreName();
2315 _color = group->GetColor();
2319 //-----------------------------------------------------------------------------
2321 * \brief Check if a filter is still valid after geometry removal
2323 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2325 if ( theFilter->_is_nil() )
2327 SMESH::Filter::Criteria_var criteria;
2328 theFilter->GetCriteria( criteria.out() );
2330 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2332 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2334 switch ( criteria[ iCr ].Type )
2336 case SMESH::FT_BelongToGeom:
2337 case SMESH::FT_BelongToPlane:
2338 case SMESH::FT_BelongToCylinder:
2339 case SMESH::FT_BelongToGenSurface:
2340 case SMESH::FT_LyingOnGeom:
2341 entry = thresholdID;
2343 case SMESH::FT_ConnectedElements:
2346 entry = thresholdID;
2352 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2353 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2354 if ( so->_is_nil() )
2356 CORBA::Object_var obj = so->GetObject();
2357 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2358 if ( gen->GeomObjectToShape( geom ).IsNull() )
2361 } // loop on criteria
2367 //=============================================================================
2369 * \brief Update data if geometry changes
2373 //=============================================================================
2375 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2377 SMESH::SMESH_Mesh_var me = _this();
2378 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2380 TPythonDump dumpNothing; // prevent any dump
2382 //bool removedFromClient = false;
2384 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2386 //removedFromClient = _impl->HasShapeToMesh();
2388 // try to find geometry by study reference
2389 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2390 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2391 if ( !meshSO->_is_nil() &&
2392 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2393 geomRefSO->ReferencedObject( geomSO.inout() ))
2395 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2396 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2399 if ( mainGO->_is_nil() && // geometry removed ==>
2400 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2402 // convert geom dependent groups into standalone ones
2403 CheckGeomGroupModif();
2405 _impl->ShapeToMesh( TopoDS_Shape() );
2407 // remove sub-meshes
2408 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2409 while ( i_sm != _mapSubMeshIor.end() )
2411 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2413 RemoveSubMesh( sm );
2415 // remove all children except groups in the study
2416 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2417 SALOMEDS::SObject_wrap so;
2418 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2419 if ( meshSO->FindSubObject( tag, so.inout() ))
2420 builder->RemoveObjectWithChildren( so );
2422 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2428 if ( !_impl->HasShapeToMesh() ) return;
2431 // Update after group modification
2433 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2434 if ( !theIsBreakLink )
2435 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2437 int nb = NbNodes() + NbElements();
2438 CheckGeomGroupModif();
2439 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2440 _gen_i->UpdateIcons( me );
2444 // Update after shape modification or breakLink w/o geometry change
2446 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2447 if ( !geomClient ) return;
2448 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2449 if ( geomGen->_is_nil() ) return;
2450 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2451 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2453 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2455 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2456 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2458 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2459 geomClient->RemoveShapeFromBuffer( ior.in() );
2460 newShape = _gen_i->GeomObjectToShape( mainGO );
2463 // Update data taking into account that if topology doesn't change
2464 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2467 _preMeshInfo->ForgetAllData();
2469 if ( geomChanged || !isShaper )
2471 if ( newShape.IsNull() )
2474 _mainShapeTick = mainGO->GetTick();
2476 // store data of groups on geometry including new TopoDS_Shape's
2477 std::vector< TGroupOnGeomData > groupsData;
2478 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2479 groupsData.reserve( groups.size() );
2480 TopTools_DataMapOfShapeShape old2newShapeMap;
2481 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2482 for ( ; g != groups.end(); ++g )
2484 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2486 groupsData.push_back( TGroupOnGeomData( group ));
2489 SMESH::SMESH_GroupOnGeom_var gog;
2490 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2491 if ( i_grp != _mapGroups.end() )
2492 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2494 GEOM::GEOM_Object_var geom;
2495 if ( !gog->_is_nil() )
2497 if ( !theIsBreakLink )
2498 geom = gog->GetShape();
2500 if ( theIsBreakLink || geom->_is_nil() )
2502 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2503 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2504 if ( !grpSO->_is_nil() &&
2505 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2506 geomRefSO->ReferencedObject( geomSO.inout() ))
2508 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2509 geom = GEOM::GEOM_Object::_narrow( geomObj );
2513 if ( old2newShapeMap.IsBound( group->GetShape() ))
2515 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2517 else if ( !geom->_is_nil() )
2519 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2520 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2522 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2523 geomClient->RemoveShapeFromBuffer( ior.in() );
2524 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2526 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2531 // store assigned hypotheses
2532 std::vector< pair< int, THypList > > ids2Hyps;
2533 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2534 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2536 const TopoDS_Shape& s = s2hyps.Key();
2537 const THypList& hyps = s2hyps.ChangeValue();
2538 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2541 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2543 // count shapes excluding compounds corresponding to geom groups
2544 int oldNbSubShapes = meshDS->MaxShapeIndex();
2545 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2547 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2548 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2551 std::set<int> subIds;
2552 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2553 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2554 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2557 // check if shape topology changes - save shape type per shape ID
2558 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2559 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2560 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2562 // change shape to mesh
2563 _impl->ShapeToMesh( TopoDS_Shape() );
2564 _impl->ShapeToMesh( newShape );
2566 // check if shape topology changes - check new shape types
2567 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2568 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2570 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2571 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2574 // re-add shapes (compounds) of geom groups
2575 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2576 TIndices2GroupData ii2grData;
2577 std::vector< int > ii;
2578 std::map< int, int > old2newIDs; // group IDs
2579 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2580 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2582 TGeomGroupData* data = &(*dataIt);
2583 ii.reserve( data->_indices.size() );
2584 ii.assign( data->_indices.begin(), data->_indices.end() );
2585 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2586 if ( ii2gd->second != data )
2588 data->_groupEntry = ii2gd->second->_groupEntry;
2589 data->_indices = ii2gd->second->_indices;
2592 const int oldNbSub = data->_indices.size();
2593 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2595 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2596 if ( ii2i != ii2iMap.end() )
2598 oldID = ii2i->second;
2599 ii2iMap.erase( ii2i );
2601 if ( !oldID && oldNbSub == 1 )
2603 if ( old2newIDs.count( oldID ))
2606 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2607 newShape = newGroupShape( *data, how );
2609 if ( !newShape.IsNull() )
2611 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2613 TopoDS_Compound compound;
2614 BRep_Builder().MakeCompound( compound );
2615 BRep_Builder().Add( compound, newShape );
2616 newShape = compound;
2618 int newID = _impl->GetSubMesh( newShape )->GetId();
2619 if ( oldID /*&& oldID != newID*/ )
2620 old2newIDs.insert( std::make_pair( oldID, newID ));
2621 if ( oldNbSub == 1 )
2622 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2626 // re-assign hypotheses
2627 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2629 int sID = ids2Hyps[i].first;
2632 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2633 if ( o2n != old2newIDs.end() )
2635 else if ( !sameTopology )
2638 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2641 const THypList& hyps = ids2Hyps[i].second;
2642 THypList::const_iterator h = hyps.begin();
2643 for ( ; h != hyps.end(); ++h )
2644 _impl->AddHypothesis( s, (*h)->GetID() );
2648 // restore groups on geometry
2649 for ( size_t i = 0; i < groupsData.size(); ++i )
2651 const TGroupOnGeomData& data = groupsData[i];
2652 if ( data._shape.IsNull() )
2655 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2656 if ( i2g == _mapGroups.end() ) continue;
2658 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2659 if ( !gr_i ) continue;
2661 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2663 _mapGroups.erase( i2g );
2665 g->GetGroupDS()->SetColor( data._color );
2668 if ( !sameTopology )
2670 std::map< int, int >::iterator o2n = old2newIDs.begin();
2671 for ( ; o2n != old2newIDs.end(); ++o2n )
2673 int newID = o2n->second, oldID = o2n->first;
2674 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2678 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2679 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2680 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2682 _mapSubMesh. erase(oldID);
2683 _mapSubMesh_i. erase(oldID);
2684 _mapSubMeshIor.erase(oldID);
2686 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2690 // update _mapSubMesh
2691 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2692 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2693 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2696 if ( !sameTopology )
2698 // remove invalid study sub-objects
2699 CheckGeomGroupModif();
2702 _gen_i->UpdateIcons( me );
2704 if ( !theIsBreakLink && isShaper )
2706 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2707 if ( !meshSO->_is_nil() )
2708 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2712 //=============================================================================
2714 * \brief Update objects depending on changed geom groups
2716 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2717 * issue 0020210: Update of a smesh group after modification of the associated geom group
2719 //=============================================================================
2721 void SMESH_Mesh_i::CheckGeomGroupModif()
2723 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2724 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2725 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2726 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2727 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2729 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2730 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2731 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2733 int nbValid = 0, nbRemoved = 0;
2734 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2735 for ( ; chItr->More(); chItr->Next() )
2737 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2738 if ( !smSO->_is_nil() &&
2739 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2740 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2742 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2743 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2744 if ( !geom->_non_existent() )
2747 continue; // keep the sub-mesh
2750 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2751 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2752 if ( !sm->_is_nil() && !sm->_non_existent() )
2754 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2755 if ( smGeom->_is_nil() )
2757 RemoveSubMesh( sm );
2764 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2765 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2769 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2770 builder->RemoveObjectWithChildren( rootSO );
2774 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2775 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2776 while ( i_gr != _mapGroups.end())
2778 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2780 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2781 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2782 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2783 bool isValidGeom = false;
2784 if ( !onGeom->_is_nil() )
2786 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2787 if ( !isValidGeom ) // check reference
2789 isValidGeom = ( ! groupSO->_is_nil() &&
2790 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2791 refSO->ReferencedObject( geomSO.inout() ) &&
2792 ! geomSO->_is_nil() &&
2793 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2796 else if ( !onFilt->_is_nil() )
2798 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2802 isValidGeom = ( !groupSO->_is_nil() &&
2803 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2807 if ( !IsLoaded() || group->IsEmpty() )
2809 RemoveGroup( group );
2811 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2813 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2815 else // is it possible?
2817 builder->RemoveObjectWithChildren( refSO );
2823 if ( !_impl->HasShapeToMesh() ) return;
2825 CORBA::Long nbEntities = NbNodes() + NbElements();
2827 // Check if group contents changed
2829 typedef map< string, TopoDS_Shape > TEntry2Geom;
2830 TEntry2Geom newGroupContents;
2832 list<TGeomGroupData>::iterator
2833 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2834 for ( ; data != dataEnd; ++data )
2836 pair< TEntry2Geom::iterator, bool > it_new =
2837 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2838 bool processedGroup = !it_new.second;
2839 TopoDS_Shape& newShape = it_new.first->second;
2840 if ( !processedGroup )
2841 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2842 if ( newShape.IsNull() )
2843 continue; // no changes
2846 _preMeshInfo->ForgetOrLoad();
2848 if ( processedGroup ) { // update group indices
2849 list<TGeomGroupData>::iterator data2 = data;
2850 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2851 data->_indices = data2->_indices;
2854 // Update SMESH objects according to new GEOM group contents
2856 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2857 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2859 int oldID = submesh->GetId();
2860 if ( !_mapSubMeshIor.count( oldID ))
2862 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2864 // update hypotheses
2865 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2866 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2867 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2869 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2870 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2872 // care of submeshes
2873 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2874 int newID = newSubmesh->GetId();
2875 if ( newID != oldID ) {
2876 _mapSubMesh [ newID ] = newSubmesh;
2877 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2878 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2879 _mapSubMesh. erase(oldID);
2880 _mapSubMesh_i. erase(oldID);
2881 _mapSubMeshIor.erase(oldID);
2882 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2887 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2888 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2889 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2891 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2893 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2894 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2895 ds->SetShape( newShape );
2900 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2901 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2903 // Remove groups and submeshes basing on removed sub-shapes
2905 TopTools_MapOfShape newShapeMap;
2906 TopoDS_Iterator shapeIt( newShape );
2907 for ( ; shapeIt.More(); shapeIt.Next() )
2908 newShapeMap.Add( shapeIt.Value() );
2910 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2911 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2913 if ( newShapeMap.Contains( shapeIt.Value() ))
2915 TopTools_IndexedMapOfShape oldShapeMap;
2916 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2917 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2919 const TopoDS_Shape& oldShape = oldShapeMap(i);
2920 int oldInd = meshDS->ShapeToIndex( oldShape );
2922 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2923 if ( i_smIor != _mapSubMeshIor.end() ) {
2924 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2927 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2928 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2930 // check if a group bases on oldInd shape
2931 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2932 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2933 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2934 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2936 RemoveGroup( i_grp->second ); // several groups can base on same shape
2937 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2942 // Reassign hypotheses and update groups after setting the new shape to mesh
2944 // collect anassigned hypotheses
2945 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2946 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2947 TShapeHypList assignedHyps;
2948 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2950 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2951 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2952 if ( !hyps.empty() ) {
2953 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2954 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2955 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2958 // collect shapes supporting groups
2959 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2960 TShapeTypeList groupData;
2961 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2962 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2963 for ( ; grIt != groups.end(); ++grIt )
2965 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2967 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2969 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2971 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2972 _impl->ShapeToMesh( newShape );
2974 // reassign hypotheses
2975 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2976 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2978 TIndexedShape& geom = indS_hyps->first;
2979 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2980 int oldID = geom._index;
2981 int newID = meshDS->ShapeToIndex( geom._shape );
2982 if ( oldID == 1 ) { // main shape
2984 geom._shape = newShape;
2988 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2989 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2990 // care of sub-meshes
2991 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2992 if ( newID != oldID ) {
2993 _mapSubMesh [ newID ] = newSubmesh;
2994 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2995 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2996 _mapSubMesh. erase(oldID);
2997 _mapSubMesh_i. erase(oldID);
2998 _mapSubMeshIor.erase(oldID);
2999 _mapSubMesh_i [ newID ]->changeLocalId( newID );
3003 TShapeTypeList::iterator geomType = groupData.begin();
3004 for ( ; geomType != groupData.end(); ++geomType )
3006 const TIndexedShape& geom = geomType->first;
3007 int oldID = geom._index;
3008 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
3011 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
3012 CORBA::String_var name = groupSO->GetName();
3014 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
3015 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
3016 /*id=*/-1, geom._shape ))
3017 group_i->changeLocalId( group->GetID() );
3020 break; // everything has been updated
3023 } // loop on group data
3027 CORBA::Long newNbEntities = NbNodes() + NbElements();
3028 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3029 if ( newNbEntities != nbEntities )
3031 // Add all SObjects with icons to soToUpdateIcons
3032 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3034 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3035 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3036 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3038 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3039 i_gr != _mapGroups.end(); ++i_gr ) // groups
3040 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3043 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3044 for ( ; so != soToUpdateIcons.end(); ++so )
3045 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3048 //=============================================================================
3050 * \brief Create standalone group from a group on geometry or filter
3052 //=============================================================================
3054 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3055 throw (SALOME::SALOME_Exception)
3057 SMESH::SMESH_Group_var aGroup;
3062 _preMeshInfo->FullLoadFromFile();
3064 if ( theGroup->_is_nil() )
3065 return aGroup._retn();
3067 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3069 return aGroup._retn();
3071 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3073 const int anId = aGroupToRem->GetLocalID();
3074 if ( !_impl->ConvertToStandalone( anId ) )
3075 return aGroup._retn();
3076 removeGeomGroupData( theGroup );
3078 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3080 // remove old instance of group from own map
3081 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3082 _mapGroups.erase( anId );
3084 SALOMEDS::StudyBuilder_var builder;
3085 SALOMEDS::SObject_wrap aGroupSO;
3086 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3087 if ( !aStudy->_is_nil() ) {
3088 builder = aStudy->NewBuilder();
3089 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3090 if ( !aGroupSO->_is_nil() )
3092 // remove reference to geometry
3093 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3094 for ( ; chItr->More(); chItr->Next() )
3096 // Remove group's child SObject
3097 SALOMEDS::SObject_wrap so = chItr->Value();
3098 builder->RemoveObject( so );
3100 // Update Python script
3101 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3102 << ".ConvertToStandalone( " << aGroupSO << " )";
3104 // change icon of Group on Filter
3107 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3108 // const int isEmpty = ( elemTypes->length() == 0 );
3111 SALOMEDS::GenericAttribute_wrap anAttr =
3112 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3113 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3114 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3120 // remember new group in own map
3121 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3122 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3124 // register CORBA object for persistence
3125 _gen_i->RegisterObject( aGroup );
3127 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3128 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3129 //aGroup->Register();
3130 aGroupToRem->UnRegister();
3132 SMESH_CATCH( SMESH::throwCorbaException );
3134 return aGroup._retn();
3137 //================================================================================
3139 * \brief Create a sub-mesh on a given sub-shape
3141 //================================================================================
3143 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3145 if(MYDEBUG) MESSAGE( "createSubMesh" );
3146 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3147 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3150 SMESH_subMesh_i * subMeshServant;
3153 subMeshId = mySubMesh->GetId();
3154 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3156 else // "invalid sub-mesh"
3158 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3159 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3160 if ( _mapSubMesh.empty() )
3163 subMeshId = _mapSubMesh.begin()->first - 1;
3164 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3167 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3169 _mapSubMesh [subMeshId] = mySubMesh;
3170 _mapSubMesh_i [subMeshId] = subMeshServant;
3171 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3173 subMeshServant->Register();
3175 // register CORBA object for persistence
3176 int nextId = _gen_i->RegisterObject( subMesh );
3177 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3178 else { nextId = 0; } // avoid "unused variable" warning
3180 // to track changes of GEOM groups
3181 if ( subMeshId > 0 )
3182 addGeomGroupData( theSubShapeObject, subMesh );
3184 return subMesh._retn();
3187 //================================================================================
3189 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3191 //================================================================================
3193 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3195 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3196 if ( it == _mapSubMeshIor.end() )
3197 return SMESH::SMESH_subMesh::_nil();
3199 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3202 //================================================================================
3204 * \brief Remove a sub-mesh based on the given sub-shape
3206 //================================================================================
3208 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3209 GEOM::GEOM_Object_ptr theSubShapeObject )
3211 bool isHypChanged = false;
3212 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3213 return isHypChanged;
3215 const int subMeshId = theSubMesh->GetId();
3217 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3220 if (( _mapSubMesh.count( subMeshId )) &&
3221 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3223 TopoDS_Shape S = sm->GetSubShape();
3226 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3227 isHypChanged = !hyps.empty();
3228 if ( isHypChanged && _preMeshInfo )
3229 _preMeshInfo->ForgetOrLoad();
3230 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3231 for ( ; hyp != hyps.end(); ++hyp )
3232 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3239 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3240 isHypChanged = ( aHypList->length() > 0 );
3241 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3242 removeHypothesis( theSubShapeObject, aHypList[i] );
3245 catch( const SALOME::SALOME_Exception& ) {
3246 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3248 removeGeomGroupData( theSubShapeObject );
3252 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3253 if ( id_smi != _mapSubMesh_i.end() )
3254 id_smi->second->UnRegister();
3256 // remove a CORBA object
3257 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3258 if ( id_smptr != _mapSubMeshIor.end() )
3259 SMESH::SMESH_subMesh_var( id_smptr->second );
3261 _mapSubMesh.erase(subMeshId);
3262 _mapSubMesh_i.erase(subMeshId);
3263 _mapSubMeshIor.erase(subMeshId);
3265 return isHypChanged;
3268 //================================================================================
3270 * \brief Create a group. Group type depends on given arguments
3272 //================================================================================
3274 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3275 const char* theName,
3277 const TopoDS_Shape& theShape,
3278 const SMESH_PredicatePtr& thePredicate )
3280 std::string newName;
3281 if ( !theName || !theName[0] )
3283 std::set< std::string > presentNames;
3284 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3285 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3287 CORBA::String_var name = i_gr->second->GetName();
3288 presentNames.insert( name.in() );
3291 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3292 } while ( !presentNames.insert( newName ).second );
3293 theName = newName.c_str();
3295 SMESH::SMESH_GroupBase_var aGroup;
3296 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3297 theID, theShape, thePredicate ))
3299 int anId = g->GetID();
3300 SMESH_GroupBase_i* aGroupImpl;
3301 if ( !theShape.IsNull() )
3302 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3303 else if ( thePredicate )
3304 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3306 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3308 aGroup = aGroupImpl->_this();
3309 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3310 aGroupImpl->Register();
3312 // register CORBA object for persistence
3313 int nextId = _gen_i->RegisterObject( aGroup );
3314 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3315 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3317 // to track changes of GEOM groups
3318 if ( !theShape.IsNull() ) {
3319 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3320 addGeomGroupData( geom, aGroup );
3323 return aGroup._retn();
3326 //=============================================================================
3328 * SMESH_Mesh_i::removeGroup
3330 * Should be called by ~SMESH_Group_i()
3332 //=============================================================================
3334 void SMESH_Mesh_i::removeGroup( const int theId )
3336 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3337 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3338 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3339 _mapGroups.erase( theId );
3340 removeGeomGroupData( group );
3341 if ( !_impl->RemoveGroup( theId ))
3343 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3344 RemoveGroup( group );
3346 group->UnRegister();
3350 //================================================================================
3352 * \brief Return a log that can be used to move another mesh to the same state as this one
3354 //================================================================================
3356 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3357 throw(SALOME::SALOME_Exception)
3359 SMESH::log_array_var aLog;
3363 _preMeshInfo->FullLoadFromFile();
3365 list < SMESHDS_Command * >logDS = _impl->GetLog();
3366 aLog = new SMESH::log_array;
3368 int lg = logDS.size();
3370 list < SMESHDS_Command * >::iterator its = logDS.begin();
3371 while(its != logDS.end()){
3372 SMESHDS_Command *com = *its;
3373 int comType = com->GetType();
3374 int lgcom = com->GetNumber();
3375 const list < int >&intList = com->GetIndexes();
3376 int inum = intList.size();
3377 list < int >::const_iterator ii = intList.begin();
3378 const list < double >&coordList = com->GetCoords();
3379 int rnum = coordList.size();
3380 list < double >::const_iterator ir = coordList.begin();
3381 aLog[indexLog].commandType = comType;
3382 aLog[indexLog].number = lgcom;
3383 aLog[indexLog].coords.length(rnum);
3384 aLog[indexLog].indexes.length(inum);
3385 for(int i = 0; i < rnum; i++){
3386 aLog[indexLog].coords[i] = *ir;
3389 for(int i = 0; i < inum; i++){
3390 aLog[indexLog].indexes[i] = *ii;
3399 SMESH_CATCH( SMESH::throwCorbaException );
3401 return aLog._retn();
3404 //================================================================================
3406 * \brief Remove the log of commands
3408 //================================================================================
3410 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3414 SMESH_CATCH( SMESH::throwCorbaException );
3417 //================================================================================
3419 * \brief Return a mesh ID
3421 //================================================================================
3423 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3428 //=============================================================================
3431 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3432 // issue 0020918: groups removal is caused by hyp modification
3433 // issue 0021208: to forget not loaded mesh data at hyp modification
3434 struct TCallUp_i : public SMESH_Mesh::TCallUp
3436 SMESH_Mesh_i* _mesh;
3437 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3438 void RemoveGroup (const int theGroupID) override { _mesh->removeGroup( theGroupID ); }
3439 void HypothesisModified( int hypID,
3440 bool updIcons) override { _mesh->onHypothesisModified( hypID,
3442 void Load () override { _mesh->Load(); }
3443 bool IsLoaded() override { return _mesh->IsLoaded(); }
3444 TopoDS_Shape GetShapeByEntry(const std::string& entry) override
3446 GEOM::GEOM_Object_var go = SMESH_Gen_i::GetGeomObjectByEntry( entry );
3447 return SMESH_Gen_i::GeomObjectToShape( go );
3452 //================================================================================
3454 * \brief callback from _impl to
3455 * 1) forget not loaded mesh data (issue 0021208)
3456 * 2) mark hypothesis as valid
3458 //================================================================================
3460 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3463 _preMeshInfo->ForgetOrLoad();
3465 if ( theUpdateIcons )
3467 SMESH::SMESH_Mesh_var mesh = _this();
3468 _gen_i->UpdateIcons( mesh );
3471 if ( _nbInvalidHypos != 0 )
3473 // mark a hypothesis as valid after edition
3475 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3476 SALOMEDS::SObject_wrap hypRoot;
3477 if ( !smeshComp->_is_nil() &&
3478 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3480 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3481 for ( ; anIter->More(); anIter->Next() )
3483 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3484 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3485 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3486 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3487 _gen_i->HighLightInvalid( hyp, false );
3489 nbInvalid += _gen_i->IsInvalid( hypSO );
3492 _nbInvalidHypos = nbInvalid;
3496 //================================================================================
3498 * \brief Set mesh implementation
3500 //================================================================================
3502 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3504 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3507 _impl->SetCallUp( new TCallUp_i(this));
3510 //=============================================================================
3512 * Return a mesh implementation
3514 //=============================================================================
3516 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3518 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3522 //=============================================================================
3524 * Return mesh editor
3526 //=============================================================================
3528 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3529 throw (SALOME::SALOME_Exception)
3531 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3535 _preMeshInfo->FullLoadFromFile();
3537 // Create MeshEditor
3539 _editor = new SMESH_MeshEditor_i( this, false );
3540 aMeshEdVar = _editor->_this();
3542 // Update Python script
3543 TPythonDump() << _editor << " = "
3544 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3546 SMESH_CATCH( SMESH::throwCorbaException );
3548 return aMeshEdVar._retn();
3551 //=============================================================================
3553 * Return mesh edition previewer
3555 //=============================================================================
3557 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3558 throw (SALOME::SALOME_Exception)
3560 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3564 _preMeshInfo->FullLoadFromFile();
3566 if ( !_previewEditor )
3567 _previewEditor = new SMESH_MeshEditor_i( this, true );
3568 aMeshEdVar = _previewEditor->_this();
3570 SMESH_CATCH( SMESH::throwCorbaException );
3572 return aMeshEdVar._retn();
3575 //================================================================================
3577 * \brief Return true if the mesh has been edited since a last total re-compute
3578 * and those modifications may prevent successful partial re-compute
3580 //================================================================================
3582 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3584 Unexpect aCatch(SALOME_SalomeException);
3585 return _impl->HasModificationsToDiscard();
3588 //================================================================================
3590 * \brief Return a random unique color
3592 //================================================================================
3594 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3596 const int MAX_ATTEMPTS = 100;
3598 double tolerance = 0.5;
3599 SALOMEDS::Color col;
3603 // generate random color
3604 double red = (double)rand() / RAND_MAX;
3605 double green = (double)rand() / RAND_MAX;
3606 double blue = (double)rand() / RAND_MAX;
3607 // check existence in the list of the existing colors
3608 bool matched = false;
3609 std::list<SALOMEDS::Color>::const_iterator it;
3610 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3611 SALOMEDS::Color color = *it;
3612 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3613 matched = tol < tolerance;
3615 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3616 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3624 //=============================================================================
3626 * Set auto-color mode. If it is on, groups get unique random colors
3628 //=============================================================================
3630 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3632 Unexpect aCatch(SALOME_SalomeException);
3633 _impl->SetAutoColor(theAutoColor);
3635 TPythonDump pyDump; // not to dump group->SetColor() from below code
3636 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3638 std::list<SALOMEDS::Color> aReservedColors;
3639 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3640 for ( ; it != _mapGroups.end(); it++ ) {
3641 if ( CORBA::is_nil( it->second )) continue;
3642 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3643 it->second->SetColor( aColor );
3644 aReservedColors.push_back( aColor );
3648 //=============================================================================
3650 * Return true if auto-color mode is on
3652 //=============================================================================
3654 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3656 Unexpect aCatch(SALOME_SalomeException);
3657 return _impl->GetAutoColor();
3660 //=============================================================================
3662 * Check if there are groups with equal names
3664 //=============================================================================
3666 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3668 return _impl->HasDuplicatedGroupNamesMED();
3671 //================================================================================
3673 * \brief Care of a file before exporting mesh into it
3675 //================================================================================
3677 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3679 SMESH_File aFile( file, false );
3681 if ( aFile.exists() ) {
3682 // existing filesystem node
3683 if ( !aFile.isDirectory() ) {
3684 if ( aFile.openForWriting() ) {
3685 if ( overwrite && ! aFile.remove()) {
3686 msg << "Can't replace " << aFile.getName();
3689 msg << "Can't write into " << aFile.getName();
3692 msg << "Location " << aFile.getName() << " is not a file";
3696 // nonexisting file; check if it can be created
3697 if ( !aFile.openForWriting() ) {
3698 msg << "You cannot create the file "
3700 << ". Check the directory existence and access rights";
3708 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3712 //================================================================================
3714 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3715 * \param file - file name
3716 * \param overwrite - to erase the file or not
3717 * \retval string - mesh name
3719 //================================================================================
3721 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3722 CORBA::Boolean overwrite)
3725 PrepareForWriting(file, overwrite);
3726 string aMeshName = "Mesh";
3727 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3728 if ( !aStudy->_is_nil() ) {
3729 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3730 if ( !aMeshSO->_is_nil() ) {
3731 CORBA::String_var name = aMeshSO->GetName();
3733 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3734 if ( !aStudy->GetProperties()->IsLocked() )
3736 SALOMEDS::GenericAttribute_wrap anAttr;
3737 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3738 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3739 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3740 ASSERT(!aFileName->_is_nil());
3741 aFileName->SetValue(file);
3742 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3743 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3744 ASSERT(!aFileType->_is_nil());
3745 aFileType->SetValue("FICHIERMED");
3749 // Update Python script
3750 // set name of mesh before export
3751 TPythonDump() << _gen_i << ".SetName("
3752 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3754 // check names of groups
3760 //================================================================================
3762 * \brief Export to MED file
3764 //================================================================================
3766 void SMESH_Mesh_i::ExportMED(const char* file,
3767 CORBA::Boolean auto_groups,
3768 CORBA::Long version,
3769 CORBA::Boolean overwrite,
3770 CORBA::Boolean autoDimension)
3771 throw(SALOME::SALOME_Exception)
3773 //MESSAGE("MED minor version: "<< minor);
3776 _preMeshInfo->FullLoadFromFile();
3778 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3779 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3781 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3783 << "auto_groups=" <<auto_groups << ", "
3784 << "version=" << version << ", "
3785 << "overwrite=" << overwrite << ", "
3786 << "meshPart=None, "
3787 << "autoDimension=" << autoDimension << " )";
3789 SMESH_CATCH( SMESH::throwCorbaException );
3792 //================================================================================
3794 * \brief Export a mesh to a SAUV file
3796 //================================================================================
3798 void SMESH_Mesh_i::ExportSAUV (const char* file,
3799 CORBA::Boolean auto_groups)
3800 throw(SALOME::SALOME_Exception)
3802 Unexpect aCatch(SALOME_SalomeException);
3804 _preMeshInfo->FullLoadFromFile();
3806 string aMeshName = prepareMeshNameAndGroups(file, true);
3807 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3808 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3809 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3813 //================================================================================
3815 * \brief Export a mesh to a DAT file
3817 //================================================================================
3819 void SMESH_Mesh_i::ExportDAT (const char *file)
3820 throw(SALOME::SALOME_Exception)
3822 Unexpect aCatch(SALOME_SalomeException);
3824 _preMeshInfo->FullLoadFromFile();
3826 // Update Python script
3827 // check names of groups
3829 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3832 PrepareForWriting(file);
3833 _impl->ExportDAT(file);
3836 //================================================================================
3838 * \brief Export a mesh to an UNV file
3840 //================================================================================
3842 void SMESH_Mesh_i::ExportUNV (const char *file)
3843 throw(SALOME::SALOME_Exception)
3845 Unexpect aCatch(SALOME_SalomeException);
3847 _preMeshInfo->FullLoadFromFile();
3849 // Update Python script
3850 // check names of groups
3852 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3855 PrepareForWriting(file);
3856 _impl->ExportUNV(file);
3859 //================================================================================
3861 * \brief Export a mesh to an STL file
3863 //================================================================================
3865 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3866 throw(SALOME::SALOME_Exception)
3868 Unexpect aCatch(SALOME_SalomeException);
3870 _preMeshInfo->FullLoadFromFile();
3872 // Update Python script
3873 // check names of groups
3875 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3876 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3878 CORBA::String_var name;
3879 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3880 if ( !so->_is_nil() )
3881 name = so->GetName();
3884 PrepareForWriting( file );
3885 _impl->ExportSTL( file, isascii, name.in() );
3888 //================================================================================
3890 * \brief Export a part of mesh to a med file
3892 //================================================================================
3894 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3896 CORBA::Boolean auto_groups,
3897 CORBA::Long version,
3898 CORBA::Boolean overwrite,
3899 CORBA::Boolean autoDimension,
3900 const GEOM::ListOfFields& fields,
3901 const char* geomAssocFields,
3902 CORBA::Double ZTolerance)
3903 throw (SALOME::SALOME_Exception)
3905 MESSAGE("MED version: "<< version);
3908 _preMeshInfo->FullLoadFromFile();
3911 bool have0dField = false;
3912 if ( fields.length() > 0 )
3914 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3915 if ( shapeToMesh->_is_nil() )
3916 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3918 for ( size_t i = 0; i < fields.length(); ++i )
3920 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3921 THROW_SALOME_CORBA_EXCEPTION
3922 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3923 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3924 if ( fieldShape->_is_nil() )
3925 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3926 if ( !fieldShape->IsSame( shapeToMesh ) )
3927 THROW_SALOME_CORBA_EXCEPTION
3928 ( "Field defined not on shape", SALOME::BAD_PARAM);
3929 if ( fields[i]->GetDimension() == 0 )
3932 if ( geomAssocFields )
3933 for ( int i = 0; geomAssocFields[i]; ++i )
3934 switch ( geomAssocFields[i] ) {
3935 case 'v':case 'e':case 'f':case 's': break;
3936 case 'V':case 'E':case 'F':case 'S': break;
3937 default: THROW_SALOME_CORBA_EXCEPTION
3938 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3942 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3946 string aMeshName = "Mesh";
3947 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3948 if ( CORBA::is_nil( meshPart ) ||
3949 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3951 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3952 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3953 0, autoDimension, /*addODOnVertices=*/have0dField,
3955 meshDS = _impl->GetMeshDS();
3960 _preMeshInfo->FullLoadFromFile();
3962 PrepareForWriting(file, overwrite);
3964 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3965 if ( !SO->_is_nil() ) {
3966 CORBA::String_var name = SO->GetName();
3970 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3971 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3972 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3973 meshDS = tmpDSDeleter._obj = partDS;
3978 if ( _impl->HasShapeToMesh() )
3980 DriverMED_W_Field fieldWriter;
3981 fieldWriter.SetFile( file );
3982 fieldWriter.SetMeshName( aMeshName );
3983 fieldWriter.AddODOnVertices( have0dField );
3985 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3989 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3990 goList->length( fields.length() );
3991 for ( size_t i = 0; i < fields.length(); ++i )
3993 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3996 TPythonDump() << _this() << ".ExportPartToMED( "
3997 << meshPart << ", r'"
3999 << auto_groups << ", "
4001 << overwrite << ", "
4002 << autoDimension << ", "
4004 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
4005 << TVar( ZTolerance )
4008 SMESH_CATCH( SMESH::throwCorbaException );
4011 //================================================================================
4013 * Write GEOM fields to MED file
4015 //================================================================================
4017 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
4018 SMESHDS_Mesh* meshDS,
4019 const GEOM::ListOfFields& fields,
4020 const char* geomAssocFields)
4022 #define METH "SMESH_Mesh_i::exportMEDFields() "
4024 if (( fields.length() < 1 ) &&
4025 ( !geomAssocFields || !geomAssocFields[0] ))
4028 std::vector< std::vector< double > > dblVals;
4029 std::vector< std::vector< int > > intVals;
4030 std::vector< int > subIdsByDim[ 4 ];
4031 const double noneDblValue = 0.;
4032 const double noneIntValue = 0;
4034 for ( size_t iF = 0; iF < fields.length(); ++iF )
4038 int dim = fields[ iF ]->GetDimension();
4039 SMDSAbs_ElementType elemType;
4040 TopAbs_ShapeEnum shapeType;
4042 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4043 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4044 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4045 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4047 continue; // skip fields on whole shape
4049 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4050 if ( dataType == GEOM::FDT_String )
4052 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4053 if ( stepIDs->length() < 1 )
4055 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4056 if ( comps->length() < 1 )
4058 CORBA::String_var name = fields[ iF ]->GetName();
4060 if ( !fieldWriter.Set( meshDS,
4064 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4067 for ( size_t iC = 0; iC < comps->length(); ++iC )
4068 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4070 dblVals.resize( comps->length() );
4071 intVals.resize( comps->length() );
4073 // find sub-shape IDs
4075 std::vector< int >& subIds = subIdsByDim[ dim ];
4076 if ( subIds.empty() )
4077 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4078 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4079 subIds.push_back( id );
4083 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4087 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4089 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4090 if ( step->_is_nil() )
4093 CORBA::Long stamp = step->GetStamp();
4094 CORBA::Long id = step->GetID();
4095 fieldWriter.SetDtIt( int( stamp ), int( id ));
4097 // fill dblVals or intVals
4098 for ( size_t iC = 0; iC < comps->length(); ++iC )
4099 if ( dataType == GEOM::FDT_Double )
4101 dblVals[ iC ].clear();
4102 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4106 intVals[ iC ].clear();
4107 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4111 case GEOM::FDT_Double:
4113 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4114 if ( dblStep->_is_nil() ) continue;
4115 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4116 if ( vv->length() != subIds.size() * comps->length() )
4117 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4118 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4119 for ( size_t iC = 0; iC < comps->length(); ++iC )
4120 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4125 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4126 if ( intStep->_is_nil() ) continue;
4127 GEOM::ListOfLong_var vv = intStep->GetValues();
4128 if ( vv->length() != subIds.size() * comps->length() )
4129 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4130 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4131 for ( size_t iC = 0; iC < comps->length(); ++iC )
4132 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4135 case GEOM::FDT_Bool:
4137 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4138 if ( boolStep->_is_nil() ) continue;
4139 GEOM::short_array_var vv = boolStep->GetValues();
4140 if ( vv->length() != subIds.size() * comps->length() )
4141 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4142 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4143 for ( size_t iC = 0; iC < comps->length(); ++iC )
4144 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4150 // pass values to fieldWriter
4151 elemIt = fieldWriter.GetOrderedElems();
4152 if ( dataType == GEOM::FDT_Double )
4153 while ( elemIt->more() )
4155 const SMDS_MeshElement* e = elemIt->next();
4156 const int shapeID = e->getshapeId();
4157 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4158 for ( size_t iC = 0; iC < comps->length(); ++iC )
4159 fieldWriter.AddValue( noneDblValue );
4161 for ( size_t iC = 0; iC < comps->length(); ++iC )
4162 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4165 while ( elemIt->more() )
4167 const SMDS_MeshElement* e = elemIt->next();
4168 const int shapeID = e->getshapeId();
4169 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4170 for ( size_t iC = 0; iC < comps->length(); ++iC )
4171 fieldWriter.AddValue( (double) noneIntValue );
4173 for ( size_t iC = 0; iC < comps->length(); ++iC )
4174 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4178 fieldWriter.Perform();
4179 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4180 if ( res && res->IsKO() )
4182 if ( res->myComment.empty() )
4183 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4185 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4191 if ( !geomAssocFields || !geomAssocFields[0] )
4194 // write geomAssocFields
4196 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4197 shapeDim[ TopAbs_COMPOUND ] = 3;
4198 shapeDim[ TopAbs_COMPSOLID ] = 3;
4199 shapeDim[ TopAbs_SOLID ] = 3;
4200 shapeDim[ TopAbs_SHELL ] = 2;
4201 shapeDim[ TopAbs_FACE ] = 2;
4202 shapeDim[ TopAbs_WIRE ] = 1;
4203 shapeDim[ TopAbs_EDGE ] = 1;
4204 shapeDim[ TopAbs_VERTEX ] = 0;
4205 shapeDim[ TopAbs_SHAPE ] = 3;
4207 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4209 std::vector< std::string > compNames;
4210 switch ( geomAssocFields[ iF ]) {
4212 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4213 compNames.push_back( "dim" );
4216 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4219 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4222 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4226 compNames.push_back( "id" );
4227 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4228 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4230 fieldWriter.SetDtIt( -1, -1 );
4232 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4236 if ( compNames.size() == 2 ) // _vertices_
4237 while ( elemIt->more() )
4239 const SMDS_MeshElement* e = elemIt->next();
4240 const int shapeID = e->getshapeId();
4243 fieldWriter.AddValue( (double) -1 );
4244 fieldWriter.AddValue( (double) -1 );
4248 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4249 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4250 fieldWriter.AddValue( (double) shapeID );
4254 while ( elemIt->more() )
4256 const SMDS_MeshElement* e = elemIt->next();
4257 const int shapeID = e->getshapeId();
4259 fieldWriter.AddValue( (double) -1 );
4261 fieldWriter.AddValue( (double) shapeID );
4265 fieldWriter.Perform();
4266 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4267 if ( res && res->IsKO() )
4269 if ( res->myComment.empty() )
4270 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4272 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4275 } // loop on geomAssocFields
4280 //================================================================================
4282 * \brief Export a part of mesh to a DAT file
4284 //================================================================================
4286 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4288 throw (SALOME::SALOME_Exception)
4290 Unexpect aCatch(SALOME_SalomeException);
4292 _preMeshInfo->FullLoadFromFile();
4294 PrepareForWriting(file);
4296 SMESH_MeshPartDS partDS( meshPart );
4297 _impl->ExportDAT(file,&partDS);
4299 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4300 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4302 //================================================================================
4304 * \brief Export a part of mesh to an UNV file
4306 //================================================================================
4308 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4310 throw (SALOME::SALOME_Exception)
4312 Unexpect aCatch(SALOME_SalomeException);
4314 _preMeshInfo->FullLoadFromFile();
4316 PrepareForWriting(file);
4318 SMESH_MeshPartDS partDS( meshPart );
4319 _impl->ExportUNV(file, &partDS);
4321 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4322 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4324 //================================================================================
4326 * \brief Export a part of mesh to an STL file
4328 //================================================================================
4330 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4332 ::CORBA::Boolean isascii)
4333 throw (SALOME::SALOME_Exception)
4335 Unexpect aCatch(SALOME_SalomeException);
4337 _preMeshInfo->FullLoadFromFile();
4339 PrepareForWriting(file);
4341 CORBA::String_var name;
4342 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4343 if ( !so->_is_nil() )
4344 name = so->GetName();
4346 SMESH_MeshPartDS partDS( meshPart );
4347 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4349 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4350 << meshPart<< ", r'" << file << "', " << isascii << ")";
4353 //================================================================================
4355 * \brief Export a part of mesh to an STL file
4357 //================================================================================
4359 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4361 CORBA::Boolean overwrite,
4362 CORBA::Boolean groupElemsByType)
4363 throw (SALOME::SALOME_Exception)
4366 Unexpect aCatch(SALOME_SalomeException);
4368 _preMeshInfo->FullLoadFromFile();
4370 PrepareForWriting(file,overwrite);
4372 std::string meshName("");
4373 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4374 if ( !so->_is_nil() )
4376 CORBA::String_var name = so->GetName();
4377 meshName = name.in();
4381 SMESH_MeshPartDS partDS( meshPart );
4382 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4384 SMESH_CATCH( SMESH::throwCorbaException );
4386 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4387 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4389 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4393 //================================================================================
4395 * \brief Export a part of mesh to a GMF file
4397 //================================================================================
4399 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4401 bool withRequiredGroups)
4402 throw (SALOME::SALOME_Exception)
4404 Unexpect aCatch(SALOME_SalomeException);
4406 _preMeshInfo->FullLoadFromFile();
4408 PrepareForWriting(file,/*overwrite=*/true);
4410 SMESH_MeshPartDS partDS( meshPart );
4411 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4413 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4414 << meshPart<< ", r'"
4416 << withRequiredGroups << ")";
4419 //=============================================================================
4421 * Return computation progress [0.,1]
4423 //=============================================================================
4425 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4429 return _impl->GetComputeProgress();
4431 SMESH_CATCH( SMESH::doNothing );
4435 //================================================================================
4437 * \brief Return nb of nodes
4439 //================================================================================
4441 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4443 Unexpect aCatch(SALOME_SalomeException);
4445 return _preMeshInfo->NbNodes();
4447 return _impl->NbNodes();
4450 //================================================================================
4452 * \brief Return nb of elements
4454 //================================================================================
4456 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4458 Unexpect aCatch(SALOME_SalomeException);
4460 return _preMeshInfo->NbElements();
4462 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4465 //================================================================================
4467 * \brief Return nb of 0D elements
4469 //================================================================================
4471 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4473 Unexpect aCatch(SALOME_SalomeException);
4475 return _preMeshInfo->Nb0DElements();
4477 return _impl->Nb0DElements();
4480 //================================================================================
4482 * \brief Return nb of BALL elements
4484 //================================================================================
4486 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4488 Unexpect aCatch(SALOME_SalomeException);
4490 return _preMeshInfo->NbBalls();
4492 return _impl->NbBalls();
4495 //================================================================================
4497 * \brief Return nb of 1D elements
4499 //================================================================================
4501 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4503 Unexpect aCatch(SALOME_SalomeException);
4505 return _preMeshInfo->NbEdges();
4507 return _impl->NbEdges();
4510 //================================================================================
4512 * \brief Return nb of edges
4514 //================================================================================
4516 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4517 throw(SALOME::SALOME_Exception)
4519 Unexpect aCatch(SALOME_SalomeException);
4521 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4523 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4526 //================================================================================
4528 * \brief Return nb of faces
4530 //================================================================================
4532 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4534 Unexpect aCatch(SALOME_SalomeException);
4536 return _preMeshInfo->NbFaces();
4538 return _impl->NbFaces();
4541 //================================================================================
4543 * \brief Return nb of tringles
4545 //================================================================================
4547 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4549 Unexpect aCatch(SALOME_SalomeException);
4551 return _preMeshInfo->NbTriangles();
4553 return _impl->NbTriangles();
4556 //================================================================================
4558 * \brief Return nb of bi-quadratic triangles
4560 //================================================================================
4562 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4564 Unexpect aCatch(SALOME_SalomeException);
4566 return _preMeshInfo->NbBiQuadTriangles();
4568 return _impl->NbBiQuadTriangles();
4571 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4573 Unexpect aCatch(SALOME_SalomeException);
4575 return _preMeshInfo->NbQuadrangles();
4577 return _impl->NbQuadrangles();
4580 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4582 Unexpect aCatch(SALOME_SalomeException);
4584 return _preMeshInfo->NbBiQuadQuadrangles();
4586 return _impl->NbBiQuadQuadrangles();
4589 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4591 Unexpect aCatch(SALOME_SalomeException);
4593 return _preMeshInfo->NbPolygons();
4595 return _impl->NbPolygons();
4598 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4600 Unexpect aCatch(SALOME_SalomeException);
4602 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4604 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4607 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4608 throw(SALOME::SALOME_Exception)
4610 Unexpect aCatch(SALOME_SalomeException);
4612 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4614 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4617 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4618 throw(SALOME::SALOME_Exception)
4620 Unexpect aCatch(SALOME_SalomeException);
4622 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4624 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4627 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4628 throw(SALOME::SALOME_Exception)
4630 Unexpect aCatch(SALOME_SalomeException);
4632 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4634 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4637 //=============================================================================
4639 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4641 Unexpect aCatch(SALOME_SalomeException);
4643 return _preMeshInfo->NbVolumes();
4645 return _impl->NbVolumes();
4648 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4650 Unexpect aCatch(SALOME_SalomeException);
4652 return _preMeshInfo->NbTetras();
4654 return _impl->NbTetras();
4657 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4659 Unexpect aCatch(SALOME_SalomeException);
4661 return _preMeshInfo->NbHexas();
4663 return _impl->NbHexas();
4666 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4668 Unexpect aCatch(SALOME_SalomeException);
4670 return _preMeshInfo->NbTriQuadHexas();
4672 return _impl->NbTriQuadraticHexas();
4675 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4677 Unexpect aCatch(SALOME_SalomeException);
4679 return _preMeshInfo->NbPyramids();
4681 return _impl->NbPyramids();
4684 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4686 Unexpect aCatch(SALOME_SalomeException);
4688 return _preMeshInfo->NbPrisms();
4690 return _impl->NbPrisms();
4693 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4695 Unexpect aCatch(SALOME_SalomeException);
4697 return _preMeshInfo->NbHexPrisms();
4699 return _impl->NbHexagonalPrisms();
4702 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4704 Unexpect aCatch(SALOME_SalomeException);
4706 return _preMeshInfo->NbPolyhedrons();
4708 return _impl->NbPolyhedrons();
4711 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4712 throw(SALOME::SALOME_Exception)
4714 Unexpect aCatch(SALOME_SalomeException);
4716 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4718 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4721 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4722 throw(SALOME::SALOME_Exception)
4724 Unexpect aCatch(SALOME_SalomeException);
4726 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4728 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4731 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4732 throw(SALOME::SALOME_Exception)
4734 Unexpect aCatch(SALOME_SalomeException);
4736 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4738 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4741 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4742 throw(SALOME::SALOME_Exception)
4744 Unexpect aCatch(SALOME_SalomeException);
4746 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4748 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4751 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4752 throw(SALOME::SALOME_Exception)
4754 Unexpect aCatch(SALOME_SalomeException);
4756 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4758 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4761 //=============================================================================
4763 * Return nb of published sub-meshes
4765 //=============================================================================
4767 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4769 Unexpect aCatch(SALOME_SalomeException);
4770 return _mapSubMesh_i.size();
4773 //=============================================================================
4775 * Dumps mesh into a string
4777 //=============================================================================
4779 char* SMESH_Mesh_i::Dump()
4783 return CORBA::string_dup( os.str().c_str() );
4786 //=============================================================================
4788 * Method of SMESH_IDSource interface
4790 //=============================================================================
4792 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4794 return GetElementsId();
4797 //=============================================================================
4799 * Return ids of all elements
4801 //=============================================================================
4803 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4804 throw (SALOME::SALOME_Exception)
4806 Unexpect aCatch(SALOME_SalomeException);
4808 _preMeshInfo->FullLoadFromFile();
4810 SMESH::long_array_var aResult = new SMESH::long_array();
4811 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4813 if ( aSMESHDS_Mesh == NULL )
4814 return aResult._retn();
4816 long nbElements = NbElements();
4817 aResult->length( nbElements );
4818 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4819 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4820 aResult[i] = anIt->next()->GetID();
4822 return aResult._retn();
4826 //=============================================================================
4828 * Return ids of all elements of given type
4830 //=============================================================================
4832 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4833 throw (SALOME::SALOME_Exception)
4835 Unexpect aCatch(SALOME_SalomeException);
4837 _preMeshInfo->FullLoadFromFile();
4839 SMESH::long_array_var aResult = new SMESH::long_array();
4840 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4842 if ( aSMESHDS_Mesh == NULL )
4843 return aResult._retn();
4845 long nbElements = NbElements();
4847 // No sense in returning ids of elements along with ids of nodes:
4848 // when theElemType == SMESH::ALL, return node ids only if
4849 // there are no elements
4850 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4851 return GetNodesId();
4853 aResult->length( nbElements );
4857 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4858 while ( i < nbElements && anIt->more() )
4859 aResult[i++] = anIt->next()->GetID();
4861 aResult->length( i );
4863 return aResult._retn();
4866 //=============================================================================
4868 * Return ids of all nodes
4870 //=============================================================================
4872 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4873 throw (SALOME::SALOME_Exception)
4875 Unexpect aCatch(SALOME_SalomeException);
4877 _preMeshInfo->FullLoadFromFile();
4879 SMESH::long_array_var aResult = new SMESH::long_array();
4880 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4882 if ( aMeshDS == NULL )
4883 return aResult._retn();
4885 long nbNodes = NbNodes();
4886 aResult->length( nbNodes );
4887 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4888 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4889 aResult[i] = anIt->next()->GetID();
4891 return aResult._retn();
4894 //=============================================================================
4896 * Return type of the given element
4898 //=============================================================================
4900 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4901 throw (SALOME::SALOME_Exception)
4903 SMESH::ElementType type = SMESH::ALL;
4907 _preMeshInfo->FullLoadFromFile();
4909 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4911 SMESH_CATCH( SMESH::throwCorbaException );
4916 //=============================================================================
4918 * Return geometric type of the given element
4920 //=============================================================================
4922 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4923 throw (SALOME::SALOME_Exception)
4926 _preMeshInfo->FullLoadFromFile();
4928 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4930 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4932 return ( SMESH::EntityType ) e->GetEntityType();
4935 //=============================================================================
4937 * Return type of the given element
4939 //=============================================================================
4941 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4942 throw (SALOME::SALOME_Exception)
4945 _preMeshInfo->FullLoadFromFile();
4947 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4949 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4951 return ( SMESH::GeometryType ) e->GetGeomType();
4954 //=============================================================================
4956 * Return ID of elements for given submesh
4958 //=============================================================================
4960 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4961 throw (SALOME::SALOME_Exception)
4963 SMESH::long_array_var aResult = new SMESH::long_array();
4967 _preMeshInfo->FullLoadFromFile();
4969 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4970 if(!SM) return aResult._retn();
4972 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4973 if(!SDSM) return aResult._retn();
4975 aResult->length(SDSM->NbElements());
4977 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4979 while ( eIt->more() ) {
4980 aResult[i++] = eIt->next()->GetID();
4983 SMESH_CATCH( SMESH::throwCorbaException );
4985 return aResult._retn();
4988 //=============================================================================
4990 * Return ID of nodes for given sub-mesh
4991 * If param all==true - return all nodes, else -
4992 * Return only nodes on shapes.
4994 //=============================================================================
4996 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4998 throw (SALOME::SALOME_Exception)
5000 SMESH::long_array_var aResult = new SMESH::long_array();
5004 _preMeshInfo->FullLoadFromFile();
5006 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5007 if(!SM) return aResult._retn();
5009 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5010 if(!SDSM) return aResult._retn();
5013 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
5014 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
5015 while ( nIt->more() ) {
5016 const SMDS_MeshNode* elem = nIt->next();
5017 theElems.insert( elem->GetID() );
5020 else { // all nodes of submesh elements
5021 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5022 while ( eIt->more() ) {
5023 const SMDS_MeshElement* anElem = eIt->next();
5024 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
5025 while ( nIt->more() ) {
5026 const SMDS_MeshElement* elem = nIt->next();
5027 theElems.insert( elem->GetID() );
5032 aResult->length(theElems.size());
5033 set<int>::iterator itElem;
5035 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
5036 aResult[i++] = *itElem;
5038 SMESH_CATCH( SMESH::throwCorbaException );
5040 return aResult._retn();
5043 //=============================================================================
5045 * Return type of elements for given sub-mesh
5047 //=============================================================================
5049 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
5050 throw (SALOME::SALOME_Exception)
5052 SMESH::ElementType type = SMESH::ALL;
5056 _preMeshInfo->FullLoadFromFile();
5058 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5059 if(!SM) return SMESH::ALL;
5061 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5062 if(!SDSM) return SMESH::ALL;
5064 if(SDSM->NbElements()==0)
5065 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
5067 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5068 const SMDS_MeshElement* anElem = eIt->next();
5070 type = ( SMESH::ElementType ) anElem->GetType();
5072 SMESH_CATCH( SMESH::throwCorbaException );
5078 //=============================================================================
5080 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5082 //=============================================================================
5084 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5087 _preMeshInfo->FullLoadFromFile();
5089 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5090 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5095 //=============================================================================
5097 * Get XYZ coordinates of node as list of double
5098 * If there is not node for given ID - return empty list
5100 //=============================================================================
5102 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5105 _preMeshInfo->FullLoadFromFile();
5107 SMESH::double_array_var aResult = new SMESH::double_array();
5108 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5109 if ( aMeshDS == NULL )
5110 return aResult._retn();
5113 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5115 return aResult._retn();
5119 aResult[0] = aNode->X();
5120 aResult[1] = aNode->Y();
5121 aResult[2] = aNode->Z();
5122 return aResult._retn();
5126 //=============================================================================
5128 * For given node return list of IDs of inverse elements
5129 * If there is not node for given ID - return empty list
5131 //=============================================================================
5133 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5134 SMESH::ElementType elemType)
5137 _preMeshInfo->FullLoadFromFile();
5139 SMESH::long_array_var aResult = new SMESH::long_array();
5140 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5141 if ( aMeshDS == NULL )
5142 return aResult._retn();
5145 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5147 return aResult._retn();
5149 // find inverse elements
5150 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5151 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5152 aResult->length( aNode->NbInverseElements( type ));
5153 for( int i = 0; eIt->more(); ++i )
5155 const SMDS_MeshElement* elem = eIt->next();
5156 aResult[ i ] = elem->GetID();
5158 return aResult._retn();
5161 //=============================================================================
5163 * \brief Return position of a node on shape
5165 //=============================================================================
5167 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5170 _preMeshInfo->FullLoadFromFile();
5172 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5173 aNodePosition->shapeID = 0;
5174 aNodePosition->shapeType = GEOM::SHAPE;
5176 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5177 if ( !mesh ) return aNodePosition;
5179 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5181 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5183 aNodePosition->shapeID = aNode->getshapeId();
5184 switch ( pos->GetTypeOfPosition() ) {
5186 aNodePosition->shapeType = GEOM::EDGE;
5187 aNodePosition->params.length(1);
5188 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5190 case SMDS_TOP_FACE: {
5191 SMDS_FacePositionPtr fPos = pos;
5192 aNodePosition->shapeType = GEOM::FACE;
5193 aNodePosition->params.length(2);
5194 aNodePosition->params[0] = fPos->GetUParameter();
5195 aNodePosition->params[1] = fPos->GetVParameter();
5198 case SMDS_TOP_VERTEX:
5199 aNodePosition->shapeType = GEOM::VERTEX;
5201 case SMDS_TOP_3DSPACE:
5202 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5203 aNodePosition->shapeType = GEOM::SOLID;
5204 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5205 aNodePosition->shapeType = GEOM::SHELL;
5211 return aNodePosition;
5214 //=============================================================================
5216 * \brief Return position of an element on shape
5218 //=============================================================================
5220 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5223 _preMeshInfo->FullLoadFromFile();
5225 SMESH::ElementPosition anElementPosition;
5226 anElementPosition.shapeID = 0;
5227 anElementPosition.shapeType = GEOM::SHAPE;
5229 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5230 if ( !mesh ) return anElementPosition;
5232 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5234 anElementPosition.shapeID = anElem->getshapeId();
5235 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5236 if ( !aSp.IsNull() ) {
5237 switch ( aSp.ShapeType() ) {
5239 anElementPosition.shapeType = GEOM::EDGE;
5242 anElementPosition.shapeType = GEOM::FACE;
5245 anElementPosition.shapeType = GEOM::VERTEX;
5248 anElementPosition.shapeType = GEOM::SOLID;
5251 anElementPosition.shapeType = GEOM::SHELL;
5257 return anElementPosition;
5260 //=============================================================================
5262 * If given element is node return IDs of shape from position
5263 * If there is not node for given ID - return -1
5265 //=============================================================================
5267 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5270 _preMeshInfo->FullLoadFromFile();
5272 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5273 if ( aMeshDS == NULL )
5277 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5279 return aNode->getshapeId();
5286 //=============================================================================
5288 * For given element return ID of result shape after
5289 * ::FindShape() from SMESH_MeshEditor
5290 * If there is not element for given ID - return -1
5292 //=============================================================================
5294 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5297 _preMeshInfo->FullLoadFromFile();
5299 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5300 if ( aMeshDS == NULL )
5303 // try to find element
5304 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5308 ::SMESH_MeshEditor aMeshEditor(_impl);
5309 int index = aMeshEditor.FindShape( elem );
5317 //=============================================================================
5319 * Return number of nodes for given element
5320 * If there is not element for given ID - return -1
5322 //=============================================================================
5324 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5327 _preMeshInfo->FullLoadFromFile();
5329 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5330 if ( aMeshDS == NULL ) return -1;
5331 // try to find element
5332 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5333 if(!elem) return -1;
5334 return elem->NbNodes();
5338 //=============================================================================
5340 * Return ID of node by given index for given element
5341 * If there is not element for given ID - return -1
5342 * If there is not node for given index - return -2
5344 //=============================================================================
5346 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5349 _preMeshInfo->FullLoadFromFile();
5351 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5352 if ( aMeshDS == NULL ) return -1;
5353 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5354 if(!elem) return -1;
5355 if( index>=elem->NbNodes() || index<0 ) return -1;
5356 return elem->GetNode(index)->GetID();
5359 //=============================================================================
5361 * Return IDs of nodes of given element
5363 //=============================================================================
5365 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5368 _preMeshInfo->FullLoadFromFile();
5370 SMESH::long_array_var aResult = new SMESH::long_array();
5371 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5373 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5375 aResult->length( elem->NbNodes() );
5376 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5377 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5378 aResult[ i ] = n->GetID();
5381 return aResult._retn();
5384 //=============================================================================
5386 * Return true if given node is medium node
5387 * in given quadratic element
5389 //=============================================================================
5391 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5394 _preMeshInfo->FullLoadFromFile();
5396 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5397 if ( aMeshDS == NULL ) return false;
5399 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5400 if(!aNode) return false;
5401 // try to find element
5402 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5403 if(!elem) return false;
5405 return elem->IsMediumNode(aNode);
5409 //=============================================================================
5411 * Return true if given node is medium node
5412 * in one of quadratic elements
5414 //=============================================================================
5416 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5417 SMESH::ElementType theElemType)
5420 _preMeshInfo->FullLoadFromFile();
5422 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5423 if ( aMeshDS == NULL ) return false;
5426 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5427 if(!aNode) return false;
5429 SMESH_MesherHelper aHelper( *(_impl) );
5431 SMDSAbs_ElementType aType;
5432 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5433 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5434 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5435 else aType = SMDSAbs_All;
5437 return aHelper.IsMedium(aNode,aType);
5441 //=============================================================================
5443 * Return number of edges for given element
5445 //=============================================================================
5447 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5450 _preMeshInfo->FullLoadFromFile();
5452 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5453 if ( aMeshDS == NULL ) return -1;
5454 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5455 if(!elem) return -1;
5456 return elem->NbEdges();
5460 //=============================================================================
5462 * Return number of faces for given element
5464 //=============================================================================
5466 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5469 _preMeshInfo->FullLoadFromFile();
5471 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5472 if ( aMeshDS == NULL ) return -1;
5473 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5474 if(!elem) return -1;
5475 return elem->NbFaces();
5478 //================================================================================
5480 * \brief Return nodes of given face (counted from zero) for given element.
5482 //================================================================================
5484 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5485 CORBA::Short faceIndex)
5488 _preMeshInfo->FullLoadFromFile();
5490 SMESH::long_array_var aResult = new SMESH::long_array();
5491 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5493 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5495 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5496 if ( faceIndex < vtool.NbFaces() )
5498 aResult->length( vtool.NbFaceNodes( faceIndex ));
5499 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5500 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5501 aResult[ i ] = nn[ i ]->GetID();
5505 return aResult._retn();
5508 //================================================================================
5510 * \brief Return three components of normal of given mesh face.
5512 //================================================================================
5514 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5515 CORBA::Boolean normalized)
5518 _preMeshInfo->FullLoadFromFile();
5520 SMESH::double_array_var aResult = new SMESH::double_array();
5522 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5525 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5527 aResult->length( 3 );
5528 aResult[ 0 ] = normal.X();
5529 aResult[ 1 ] = normal.Y();
5530 aResult[ 2 ] = normal.Z();
5533 return aResult._retn();
5536 //================================================================================
5538 * \brief Return an element based on all given nodes.
5540 //================================================================================
5542 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5545 _preMeshInfo->FullLoadFromFile();
5547 CORBA::Long elemID(0);
5548 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5550 vector< const SMDS_MeshNode * > nn( nodes.length() );
5551 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5552 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5555 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5556 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5557 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5558 _impl->NbVolumes( ORDER_QUADRATIC )))
5559 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5561 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5566 //================================================================================
5568 * \brief Return elements including all given nodes.
5570 //================================================================================
5572 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5573 SMESH::ElementType elemType)
5576 _preMeshInfo->FullLoadFromFile();
5578 SMESH::long_array_var result = new SMESH::long_array();
5580 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5582 vector< const SMDS_MeshNode * > nn( nodes.length() );
5583 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5584 nn[i] = mesh->FindNode( nodes[i] );
5586 std::vector<const SMDS_MeshElement *> elems;
5587 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5588 result->length( elems.size() );
5589 for ( size_t i = 0; i < elems.size(); ++i )
5590 result[i] = elems[i]->GetID();
5592 return result._retn();
5595 //=============================================================================
5597 * Return true if given element is polygon
5599 //=============================================================================
5601 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5604 _preMeshInfo->FullLoadFromFile();
5606 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5607 if ( aMeshDS == NULL ) return false;
5608 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5609 if(!elem) return false;
5610 return elem->IsPoly();
5614 //=============================================================================
5616 * Return true if given element is quadratic
5618 //=============================================================================
5620 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5623 _preMeshInfo->FullLoadFromFile();
5625 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5626 if ( aMeshDS == NULL ) return false;
5627 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5628 if(!elem) return false;
5629 return elem->IsQuadratic();
5632 //=============================================================================
5634 * Return diameter of ball discrete element or zero in case of an invalid \a id
5636 //=============================================================================
5638 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5641 _preMeshInfo->FullLoadFromFile();
5643 if ( const SMDS_BallElement* ball =
5644 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5645 return ball->GetDiameter();
5650 //=============================================================================
5652 * Return bary center for given element
5654 //=============================================================================
5656 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5659 _preMeshInfo->FullLoadFromFile();
5661 SMESH::double_array_var aResult = new SMESH::double_array();
5662 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5663 if ( aMeshDS == NULL )
5664 return aResult._retn();
5666 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5668 return aResult._retn();
5670 if(elem->GetType()==SMDSAbs_Volume) {
5671 SMDS_VolumeTool aTool;
5672 if(aTool.Set(elem)) {
5674 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5679 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5681 double x=0., y=0., z=0.;
5682 for(; anIt->more(); ) {
5684 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5698 return aResult._retn();
5701 //================================================================================
5703 * \brief Create a group of elements preventing computation of a sub-shape
5705 //================================================================================
5707 SMESH::ListOfGroups*
5708 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5709 const char* theGroupName )
5710 throw ( SALOME::SALOME_Exception )
5712 Unexpect aCatch(SALOME_SalomeException);
5714 if ( !theGroupName || strlen( theGroupName) == 0 )
5715 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5717 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5718 ::SMESH_MeshEditor::ElemFeatures elemType;
5720 // submesh by subshape id
5721 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5722 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5725 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5726 if ( error && error->HasBadElems() )
5728 // sort bad elements by type
5729 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5730 const list<const SMDS_MeshElement*>& badElems =
5731 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5732 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5733 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5734 for ( ; elemIt != elemEnd; ++elemIt )
5736 const SMDS_MeshElement* elem = *elemIt;
5737 if ( !elem ) continue;
5739 if ( elem->GetID() < 1 )
5741 // elem is a temporary element, make a real element
5742 vector< const SMDS_MeshNode* > nodes;
5743 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5744 while ( nIt->more() && elem )
5746 nodes.push_back( nIt->next() );
5747 if ( nodes.back()->GetID() < 1 )
5748 elem = 0; // a temporary element on temporary nodes
5752 ::SMESH_MeshEditor editor( _impl );
5753 elem = editor.AddElement( nodes, elemType.Init( elem ));
5757 elemsByType[ elem->GetType() ].push_back( elem );
5760 // how many groups to create?
5762 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5763 nbTypes += int( !elemsByType[ i ].empty() );
5764 groups->length( nbTypes );
5767 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5769 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5770 if ( elems.empty() ) continue;
5772 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5773 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5775 SMESH::SMESH_Mesh_var mesh = _this();
5776 SALOMEDS::SObject_wrap aSO =
5777 _gen_i->PublishGroup( mesh, groups[ iG ],
5778 GEOM::GEOM_Object::_nil(), theGroupName);
5780 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5781 if ( !grp_i ) continue;
5783 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5784 for ( size_t iE = 0; iE < elems.size(); ++iE )
5785 grpDS->SMDSGroup().Add( elems[ iE ]);
5790 return groups._retn();
5793 //=============================================================================
5795 * Create and publish group servants if any groups were imported or created anyhow
5797 //=============================================================================
5799 void SMESH_Mesh_i::CreateGroupServants()
5801 SMESH::SMESH_Mesh_var aMesh = _this();
5804 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5805 while ( groupIt->more() )
5807 ::SMESH_Group* group = groupIt->next();
5808 int anId = group->GetID();
5810 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5811 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5813 addedIDs.insert( anId );
5815 SMESH_GroupBase_i* aGroupImpl;
5817 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5818 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5820 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5821 shape = groupOnGeom->GetShape();
5824 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5827 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5828 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5829 aGroupImpl->Register();
5831 // register CORBA object for persistence
5832 int nextId = _gen_i->RegisterObject( groupVar );
5833 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5834 else { nextId = 0; } // avoid "unused variable" warning in release mode
5836 // publishing the groups in the study
5837 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5838 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5841 if ( !addedIDs.empty() )
5844 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5845 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5847 set<int>::iterator it = addedIDs.find( i_grp->first );
5848 if ( it != addedIDs.end() )
5850 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5851 addedIDs.erase( it );
5852 if ( addedIDs.empty() )
5859 //=============================================================================
5861 * \brief Return true if all sub-meshes are computed OK - to update an icon
5863 //=============================================================================
5865 bool SMESH_Mesh_i::IsComputedOK()
5867 return _impl->IsComputedOK();
5870 //=============================================================================
5872 * \brief Return groups cantained in _mapGroups by their IDs
5874 //=============================================================================
5876 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5878 int nbGroups = groupIDs.size();
5879 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5880 aList->length( nbGroups );
5882 list<int>::const_iterator ids = groupIDs.begin();
5883 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5885 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5886 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5887 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5889 aList->length( nbGroups );
5890 return aList._retn();
5893 //=============================================================================
5895 * \brief Return information about imported file
5897 //=============================================================================
5899 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5901 SMESH::MedFileInfo_var res( _medFileInfo );
5902 if ( !res.operator->() ) {
5903 res = new SMESH::MedFileInfo;
5905 res->fileSize = res->major = res->minor = res->release = -1;
5910 //=======================================================================
5911 //function : FileInfoToString
5912 //purpose : Persistence of file info
5913 //=======================================================================
5915 std::string SMESH_Mesh_i::FileInfoToString()
5918 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5920 s = SMESH_Comment( _medFileInfo->fileSize )
5921 << " " << _medFileInfo->major
5922 << " " << _medFileInfo->minor
5923 << " " << _medFileInfo->release
5924 << " " << _medFileInfo->fileName;
5929 //=======================================================================
5930 //function : FileInfoFromString
5931 //purpose : Persistence of file info
5932 //=======================================================================
5934 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5936 std::string size, major, minor, release, fileName;
5937 std::istringstream is(info);
5938 is >> size >> major >> minor >> release;
5939 fileName = info.data() + ( size.size() + 1 +
5942 release.size()+ 1 );
5944 _medFileInfo = new SMESH::MedFileInfo();
5945 _medFileInfo->fileName = fileName.c_str();
5946 _medFileInfo->fileSize = atoi( size.c_str() );
5947 _medFileInfo->major = atoi( major.c_str() );
5948 _medFileInfo->minor = atoi( minor.c_str() );
5949 _medFileInfo->release = atoi( release.c_str() );
5952 //=============================================================================
5954 * \brief Pass names of mesh groups from study to mesh DS
5956 //=============================================================================
5958 void SMESH_Mesh_i::checkGroupNames()
5960 int nbGrp = NbGroups();
5964 SMESH::ListOfGroups* grpList = 0;
5965 // avoid dump of "GetGroups"
5967 // store python dump into a local variable inside local scope
5968 SMESH::TPythonDump pDump; // do not delete this line of code
5969 grpList = GetGroups();
5972 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5973 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5976 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5977 if ( aGrpSO->_is_nil() )
5979 // correct name of the mesh group if necessary
5980 const char* guiName = aGrpSO->GetName();
5981 if ( strcmp(guiName, aGrp->GetName()) )
5982 aGrp->SetName( guiName );
5986 //=============================================================================
5988 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
5990 //=============================================================================
5991 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5993 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5997 //=============================================================================
5999 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
6001 //=============================================================================
6003 char* SMESH_Mesh_i::GetParameters()
6005 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
6008 //=============================================================================
6010 * \brief Return list of notebook variables used for last Mesh operation
6012 //=============================================================================
6013 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
6015 SMESH::string_array_var aResult = new SMESH::string_array();
6016 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
6018 CORBA::String_var aParameters = GetParameters();
6019 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
6020 if ( aSections->length() > 0 ) {
6021 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
6022 aResult->length( aVars.length() );
6023 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
6024 aResult[i] = CORBA::string_dup( aVars[i] );
6027 return aResult._retn();
6030 //================================================================================
6032 * \brief Return types of elements it contains
6034 //================================================================================
6036 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
6039 return _preMeshInfo->GetTypes();
6041 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
6045 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
6046 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
6047 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
6048 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
6049 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
6050 if (_impl->NbNodes() &&
6051 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
6052 types->length( nbTypes );
6054 return types._retn();
6057 //================================================================================
6059 * \brief Return self
6061 //================================================================================
6063 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
6065 return SMESH::SMESH_Mesh::_duplicate( _this() );
6068 //================================================================================
6070 * \brief Return false if GetMeshInfo() return incorrect information that may
6071 * happen if mesh data is not yet fully loaded from the file of study.
6075 //================================================================================
6077 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6079 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6082 //=============================================================================
6084 * \brief Return number of mesh elements per each \a EntityType
6086 //=============================================================================
6088 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6091 return _preMeshInfo->GetMeshInfo();
6093 SMESH::long_array_var aRes = new SMESH::long_array();
6094 aRes->length(SMESH::Entity_Last);
6095 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6097 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6099 return aRes._retn();
6100 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6101 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6102 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6103 return aRes._retn();
6106 //=============================================================================
6108 * \brief Return number of mesh elements per each \a ElementType
6110 //=============================================================================
6112 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6114 SMESH::long_array_var aRes = new SMESH::long_array();
6115 aRes->length(SMESH::NB_ELEMENT_TYPES);
6116 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6119 const SMDS_MeshInfo* meshInfo = 0;
6121 meshInfo = _preMeshInfo;
6122 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6123 meshInfo = & meshDS->GetMeshInfo();
6126 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6127 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6129 return aRes._retn();
6132 //=============================================================================
6134 * Collect statistic of mesh elements given by iterator
6136 //=============================================================================
6138 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6139 SMESH::long_array& theInfo)
6141 if (!theItr) return;
6142 while (theItr->more())
6143 theInfo[ theItr->next()->GetEntityType() ]++;
6145 //=============================================================================
6147 * Return mesh unstructed grid information.
6149 //=============================================================================
6151 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6153 SALOMEDS::TMPFile_var SeqFile;
6154 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6155 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6157 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6158 aWriter->WriteToOutputStringOn();
6159 aWriter->SetInputData(aGrid);
6160 aWriter->SetFileTypeToBinary();
6162 char* str = aWriter->GetOutputString();
6163 int size = aWriter->GetOutputStringLength();
6165 //Allocate octet buffer of required size
6166 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6167 //Copy ostrstream content to the octet buffer
6168 memcpy(OctetBuf, str, size);
6169 //Create and return TMPFile
6170 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6174 return SeqFile._retn();
6177 //=============================================================================
6178 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6179 * SMESH::ElementType type) */
6181 using namespace SMESH::Controls;
6182 //-----------------------------------------------------------------------------
6183 struct PredicateIterator : public SMDS_ElemIterator
6185 SMDS_ElemIteratorPtr _elemIter;
6186 PredicatePtr _predicate;
6187 const SMDS_MeshElement* _elem;
6188 SMDSAbs_ElementType _type;
6190 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6191 PredicatePtr predicate,
6192 SMDSAbs_ElementType type):
6193 _elemIter(iterator), _predicate(predicate), _type(type)
6201 virtual const SMDS_MeshElement* next()
6203 const SMDS_MeshElement* res = _elem;
6205 while ( _elemIter->more() && !_elem )
6207 if ((_elem = _elemIter->next()) &&
6208 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6209 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6216 //-----------------------------------------------------------------------------
6217 struct IDSourceIterator : public SMDS_ElemIterator
6219 const CORBA::Long* _idPtr;
6220 const CORBA::Long* _idEndPtr;
6221 SMESH::long_array_var _idArray;
6222 const SMDS_Mesh* _mesh;
6223 const SMDSAbs_ElementType _type;
6224 const SMDS_MeshElement* _elem;
6226 IDSourceIterator( const SMDS_Mesh* mesh,
6227 const CORBA::Long* ids,
6229 SMDSAbs_ElementType type):
6230 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6232 if ( _idPtr && nbIds && _mesh )
6235 IDSourceIterator( const SMDS_Mesh* mesh,
6236 SMESH::long_array* idArray,
6237 SMDSAbs_ElementType type):
6238 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6240 if ( idArray && _mesh )
6242 _idPtr = &_idArray[0];
6243 _idEndPtr = _idPtr + _idArray->length();
6251 virtual const SMDS_MeshElement* next()
6253 const SMDS_MeshElement* res = _elem;
6255 while ( _idPtr < _idEndPtr && !_elem )
6257 if ( _type == SMDSAbs_Node )
6259 _elem = _mesh->FindNode( *_idPtr++ );
6261 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6262 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6270 //-----------------------------------------------------------------------------
6272 struct NodeOfElemIterator : public SMDS_ElemIterator
6274 TColStd_MapOfInteger _checkedNodeIDs;
6275 SMDS_ElemIteratorPtr _elemIter;
6276 SMDS_ElemIteratorPtr _nodeIter;
6277 const SMDS_MeshElement* _node;
6279 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6281 if ( _elemIter && _elemIter->more() )
6283 _nodeIter = _elemIter->next()->nodesIterator();
6291 virtual const SMDS_MeshElement* next()
6293 const SMDS_MeshElement* res = _node;
6295 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6297 if ( _nodeIter->more() )
6299 _node = _nodeIter->next();
6300 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6305 _nodeIter = _elemIter->next()->nodesIterator();
6313 //=============================================================================
6315 * Return iterator on elements of given type in given object
6317 //=============================================================================
6319 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6320 SMESH::ElementType theType)
6322 SMDS_ElemIteratorPtr elemIt;
6323 bool typeOK = ( theType == SMESH::ALL );
6324 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6326 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6327 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6328 if ( !mesh_i ) return elemIt;
6329 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6331 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6333 elemIt = meshDS->elementsIterator( elemType );
6336 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6338 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6341 elemIt = sm->GetElements();
6342 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6344 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6345 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6349 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6351 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6352 if ( groupDS && ( elemType == groupDS->GetType() ||
6353 elemType == SMDSAbs_Node ||
6354 elemType == SMDSAbs_All ))
6356 elemIt = groupDS->GetElements();
6357 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6360 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6362 if ( filter_i->GetElementType() == theType ||
6363 filter_i->GetElementType() == SMESH::ALL ||
6364 elemType == SMDSAbs_Node ||
6365 elemType == SMDSAbs_All)
6367 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6368 if ( pred_i && pred_i->GetPredicate() )
6370 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6371 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6372 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6373 elemIt = SMDS_ElemIteratorPtr
6374 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6375 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6381 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6382 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6383 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6385 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6386 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6389 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6390 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6394 SMESH::long_array_var ids = theObject->GetIDs();
6395 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6397 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6400 if ( elemIt && elemIt->more() && !typeOK )
6402 if ( elemType == SMDSAbs_Node )
6404 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6408 elemIt = SMDS_ElemIteratorPtr();
6414 //=============================================================================
6415 namespace // Finding concurrent hypotheses
6416 //=============================================================================
6420 * \brief mapping of mesh dimension into shape type
6422 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6424 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6426 case 0: aType = TopAbs_VERTEX; break;
6427 case 1: aType = TopAbs_EDGE; break;
6428 case 2: aType = TopAbs_FACE; break;
6430 default:aType = TopAbs_SOLID; break;
6435 //-----------------------------------------------------------------------------
6437 * \brief Internal structure used to find concurrent submeshes
6439 * It represents a pair < submesh, concurrent dimension >, where
6440 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6441 * with another submesh. In other words, it is dimension of a hypothesis assigned
6448 int _dim; //!< a dimension the algo can build (concurrent dimension)
6449 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6450 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6451 const SMESH_subMesh* _subMesh;
6452 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6454 //-----------------------------------------------------------------------------
6455 // Return the algorithm
6456 const SMESH_Algo* GetAlgo() const
6457 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6459 //-----------------------------------------------------------------------------
6461 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6463 const TopoDS_Shape& theShape)
6465 _subMesh = theSubMesh;
6466 SetShape( theDim, theShape );
6469 //-----------------------------------------------------------------------------
6471 void SetShape(const int theDim,
6472 const TopoDS_Shape& theShape)
6475 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6476 if (_dim >= _ownDim)
6477 _shapeMap.Add( theShape );
6479 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6480 for( ; anExp.More(); anExp.Next() )
6481 _shapeMap.Add( anExp.Current() );
6485 //-----------------------------------------------------------------------------
6486 //! Check sharing of sub-shapes
6487 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6488 const TopTools_MapOfShape& theToFind,
6489 const TopAbs_ShapeEnum theType)
6491 bool isShared = false;
6492 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6493 for (; !isShared && anItr.More(); anItr.Next() )
6495 const TopoDS_Shape aSubSh = anItr.Key();
6496 // check for case when concurrent dimensions are same
6497 isShared = theToFind.Contains( aSubSh );
6498 // check for sub-shape with concurrent dimension
6499 TopExp_Explorer anExp( aSubSh, theType );
6500 for ( ; !isShared && anExp.More(); anExp.Next() )
6501 isShared = theToFind.Contains( anExp.Current() );
6506 //-----------------------------------------------------------------------------
6507 //! check algorithms
6508 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6509 const SMESHDS_Hypothesis* theA2)
6511 if ( !theA1 || !theA2 ||
6512 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6513 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6514 return false; // one of the hypothesis is not algorithm
6515 // check algorithm names (should be equal)
6516 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6520 //-----------------------------------------------------------------------------
6521 //! Check if sub-shape hypotheses are concurrent
6522 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6524 if ( _subMesh == theOther->_subMesh )
6525 return false; // same sub-shape - should not be
6527 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6528 // any of the two submeshes is not on COMPOUND shape )
6529 // -> no concurrency
6530 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6531 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6532 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6533 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6534 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6537 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6538 if ( !checkSubShape )
6541 // check algorithms to be same
6542 const SMESH_Algo* a1 = this->GetAlgo();
6543 const SMESH_Algo* a2 = theOther->GetAlgo();
6544 bool isSame = checkAlgo( a1, a2 );
6548 // commented off for IPAL54678
6549 // if ( !a1 || !a2 )
6550 // return false; // pb?
6551 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6554 // check hypothesises for concurrence (skip first as algorithm)
6556 // pointers should be same, because it is referened from mesh hypothesis partition
6557 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6558 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6559 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6560 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6562 // the submeshes are concurrent if their algorithms has different parameters
6563 return nbSame != theOther->_hypotheses.size() - 1;
6566 // Return true if algorithm of this SMESH_DimHyp is used if no
6567 // sub-mesh order is imposed by the user
6568 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6570 // NeedDiscreteBoundary() algo has a higher priority
6571 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6572 theOther->GetAlgo()->NeedDiscreteBoundary() )
6573 return !this->GetAlgo()->NeedDiscreteBoundary();
6575 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6578 }; // end of SMESH_DimHyp
6579 //-----------------------------------------------------------------------------
6581 typedef list<const SMESH_DimHyp*> TDimHypList;
6583 //-----------------------------------------------------------------------------
6585 void addDimHypInstance(const int theDim,
6586 const TopoDS_Shape& theShape,
6587 const SMESH_Algo* theAlgo,
6588 const SMESH_subMesh* theSubMesh,
6589 const list <const SMESHDS_Hypothesis*>& theHypList,
6590 TDimHypList* theDimHypListArr )
6592 if ( !theAlgo->NeedDiscreteBoundary() &&
6593 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6595 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6596 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6598 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6599 dimHyp->_hypotheses.push_front(theAlgo);
6600 listOfdimHyp.push_back( dimHyp );
6603 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6604 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6605 theHypList.begin(), theHypList.end() );
6608 //-----------------------------------------------------------------------------
6609 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6610 TDimHypList& theListOfConcurr)
6612 if ( theListOfConcurr.empty() )
6614 theListOfConcurr.push_back( theDimHyp );
6618 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6619 while ( hypIt != theListOfConcurr.end() &&
6620 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6622 theListOfConcurr.insert( hypIt, theDimHyp );
6626 //-----------------------------------------------------------------------------
6627 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6628 const TDimHypList& theListOfDimHyp,
6629 TDimHypList& theListOfConcurrHyp,
6630 set<int>& theSetOfConcurrId )
6632 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6633 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6635 const SMESH_DimHyp* curDimHyp = *rIt;
6636 if ( curDimHyp == theDimHyp )
6637 break; // meet own dimHyp pointer in same dimension
6639 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6640 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6642 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6647 //-----------------------------------------------------------------------------
6648 void unionLists(TListOfInt& theListOfId,
6649 TListOfListOfInt& theListOfListOfId,
6652 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6653 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6656 continue; //skip already treated lists
6657 // check if other list has any same submesh object
6658 TListOfInt& otherListOfId = *it;
6659 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6660 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6663 // union two lists (from source into target)
6664 TListOfInt::iterator it2 = otherListOfId.begin();
6665 for ( ; it2 != otherListOfId.end(); it2++ ) {
6666 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6667 theListOfId.push_back(*it2);
6669 // clear source list
6670 otherListOfId.clear();
6673 //-----------------------------------------------------------------------------
6675 //! free memory allocated for dimension-hypothesis objects
6676 void removeDimHyps( TDimHypList* theArrOfList )
6678 for (int i = 0; i < 4; i++ ) {
6679 TDimHypList& listOfdimHyp = theArrOfList[i];
6680 TDimHypList::const_iterator it = listOfdimHyp.begin();
6681 for ( ; it != listOfdimHyp.end(); it++ )
6686 //-----------------------------------------------------------------------------
6688 * \brief find common submeshes with given submesh
6689 * \param theSubMeshList list of already collected submesh to check
6690 * \param theSubMesh given submesh to intersect with other
6691 * \param theCommonSubMeshes collected common submeshes
6693 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6694 const SMESH_subMesh* theSubMesh,
6695 set<const SMESH_subMesh*>& theCommon )
6699 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6700 for ( ; it != theSubMeshList.end(); it++ )
6701 theSubMesh->FindIntersection( *it, theCommon );
6702 theSubMeshList.push_back( theSubMesh );
6703 //theCommon.insert( theSubMesh );
6706 //-----------------------------------------------------------------------------
6707 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6709 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6710 for ( ; listsIt != smLists.end(); ++listsIt )
6712 const TListOfInt& smIDs = *listsIt;
6713 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6721 //=============================================================================
6723 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6725 //=============================================================================
6727 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6729 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6730 if ( isSubMeshInList( submeshID, anOrder ))
6733 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6734 return isSubMeshInList( submeshID, allConurrent );
6737 //=============================================================================
6739 * \brief Return sub-mesh objects list in meshing order
6741 //=============================================================================
6743 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6745 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6747 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6749 return aResult._retn();
6751 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6752 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6753 anOrder.splice( anOrder.end(), allConurrent );
6756 TListOfListOfInt::iterator listIt = anOrder.begin();
6757 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6758 unionLists( *listIt, anOrder, listIndx + 1 );
6760 // convert submesh ids into interface instances
6761 // and dump command into python
6762 convertMeshOrder( anOrder, aResult, false );
6764 return aResult._retn();
6767 //=============================================================================
6769 * \brief Finds concurrent sub-meshes
6771 //=============================================================================
6773 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6775 TListOfListOfInt anOrder;
6776 ::SMESH_Mesh& mesh = GetImpl();
6778 // collect submeshes and detect concurrent algorithms and hypothesises
6779 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6781 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6782 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6784 ::SMESH_subMesh* sm = (*i_sm).second;
6786 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6788 // list of assigned hypothesises
6789 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6790 // Find out dimensions where the submesh can be concurrent.
6791 // We define the dimensions by algo of each of hypotheses in hypList
6792 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6793 for( ; hypIt != hypList.end(); hypIt++ )
6795 SMESH_Algo* anAlgo = 0;
6796 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6797 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6798 // hyp it-self is algo
6799 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6801 // try to find algorithm with help of sub-shapes
6802 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6803 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6804 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6807 continue; // no algorithm assigned to a current submesh
6809 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6810 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6811 // and !anAlgo->NeedLowerHyps( dim ))
6813 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6814 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6815 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6817 } // end iterations on submesh
6819 // iterate on created dimension-hypotheses and check for concurrents
6820 for ( int i = 0; i < 4; i++ )
6822 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6823 // check for concurrents in own and other dimensions (step-by-step)
6824 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6825 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6827 const SMESH_DimHyp* dimHyp = *dhIt;
6828 TDimHypList listOfConcurr;
6829 set<int> setOfConcurrIds;
6830 // looking for concurrents and collect into own list
6831 for ( int j = i; j < 4; j++ )
6832 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6833 // check if any concurrents found
6834 if ( listOfConcurr.size() > 0 )
6836 // add own submesh to list of concurrent
6837 addInOrderOfPriority( dimHyp, listOfConcurr );
6838 list<int> listOfConcurrIds;
6839 TDimHypList::iterator hypIt = listOfConcurr.begin();
6840 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6841 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6842 anOrder.push_back( listOfConcurrIds );
6847 removeDimHyps(dimHypListArr);
6849 // now, minimize the number of concurrent groups
6850 // Here we assume that lists of submeshes can have same submesh
6851 // in case of multi-dimension algorithms, as result
6852 // list with common submesh has to be united into one list
6854 TListOfListOfInt::iterator listIt = anOrder.begin();
6855 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6856 unionLists( *listIt, anOrder, listIndx + 1 );
6861 //=============================================================================
6863 * \brief Set submesh object order
6864 * \param theSubMeshArray submesh array order
6866 //=============================================================================
6868 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6871 _preMeshInfo->ForgetOrLoad();
6874 ::SMESH_Mesh& mesh = GetImpl();
6876 TPythonDump aPythonDump; // prevent dump of called methods
6877 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6879 TListOfListOfInt subMeshOrder;
6880 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6882 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6883 TListOfInt subMeshIds;
6885 aPythonDump << ", ";
6886 aPythonDump << "[ ";
6887 // Collect subMeshes which should be clear
6888 // do it list-by-list, because modification of submesh order
6889 // take effect between concurrent submeshes only
6890 set<const SMESH_subMesh*> subMeshToClear;
6891 list<const SMESH_subMesh*> subMeshList;
6892 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6894 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6896 aPythonDump << ", ";
6897 aPythonDump << subMesh;
6898 subMeshIds.push_back( subMesh->GetId() );
6899 // detect common parts of submeshes
6900 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6901 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6903 aPythonDump << " ]";
6904 subMeshOrder.push_back( subMeshIds );
6906 // clear collected sub-meshes
6907 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6908 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6909 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6911 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6912 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6913 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6916 aPythonDump << " ])";
6918 mesh.SetMeshOrder( subMeshOrder );
6921 SMESH::SMESH_Mesh_var me = _this();
6922 _gen_i->UpdateIcons( me );
6927 //=============================================================================
6929 * \brief Convert submesh ids into submesh interfaces
6931 //=============================================================================
6933 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6934 SMESH::submesh_array_array& theResOrder,
6935 const bool theIsDump)
6937 int nbSet = theIdsOrder.size();
6938 TPythonDump aPythonDump; // prevent dump of called methods
6940 aPythonDump << "[ ";
6941 theResOrder.length(nbSet);
6942 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6944 for( ; it != theIdsOrder.end(); it++ )
6946 // translate submesh identificators into submesh objects
6947 // takeing into account real number of concurrent lists
6948 const TListOfInt& aSubOrder = (*it);
6949 if (!aSubOrder.size())
6952 aPythonDump << "[ ";
6953 // convert shape indices into interfaces
6954 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6955 aResSubSet->length(aSubOrder.size());
6956 TListOfInt::const_iterator subIt = aSubOrder.begin();
6958 for( j = 0; subIt != aSubOrder.end(); subIt++ )
6960 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6962 SMESH::SMESH_subMesh_var subMesh =
6963 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6966 aPythonDump << ", ";
6967 aPythonDump << subMesh;
6969 aResSubSet[ j++ ] = subMesh;
6972 aPythonDump << " ]";
6974 theResOrder[ listIndx++ ] = aResSubSet;
6976 // correct number of lists
6977 theResOrder.length( listIndx );
6980 // finilise python dump
6981 aPythonDump << " ]";
6982 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6986 namespace // utils used by SMESH_MeshPartDS
6989 * \brief Class used to access to protected data of SMDS_MeshInfo
6991 struct TMeshInfo : public SMDS_MeshInfo
6993 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6996 * \brief Element holing its ID only
6998 struct TElemID : public SMDS_LinearEdge
7000 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
7004 //================================================================================
7006 // Implementation of SMESH_MeshPartDS
7008 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
7009 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
7011 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
7012 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
7015 _meshDS = mesh_i->GetImpl().GetMeshDS();
7017 SetPersistentId( _meshDS->GetPersistentId() );
7019 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
7021 // <meshPart> is the whole mesh
7022 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
7024 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
7025 myGroupSet = _meshDS->GetGroups();
7030 SMESH::long_array_var anIDs = meshPart->GetIDs();
7031 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
7032 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
7034 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7035 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
7036 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7041 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7042 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
7043 if ( _elements[ e->GetType() ].insert( e ).second )
7046 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7047 while ( nIt->more() )
7049 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7050 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7057 ShapeToMesh( _meshDS->ShapeToMesh() );
7059 _meshDS = 0; // to enforce iteration on _elements and _nodes
7062 // -------------------------------------------------------------------------------------
7063 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
7064 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
7067 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
7068 for ( ; partIt != meshPart.end(); ++partIt )
7069 if ( const SMDS_MeshElement * e = *partIt )
7070 if ( _elements[ e->GetType() ].insert( e ).second )
7073 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7074 while ( nIt->more() )
7076 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7077 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7083 // -------------------------------------------------------------------------------------
7084 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7086 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7088 TElemID elem( IDelem );
7089 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7090 if ( !_elements[ iType ].empty() )
7092 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7093 if ( it != _elements[ iType ].end() )
7098 // -------------------------------------------------------------------------------------
7099 bool SMESH_MeshPartDS::HasNumerationHoles()
7101 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7103 return ( MinNodeID() != 1 ||
7104 MaxNodeID() != NbNodes() ||
7105 MinElementID() != 1 ||
7106 MaxElementID() != NbElements() );
7108 // -------------------------------------------------------------------------------------
7109 int SMESH_MeshPartDS::MaxNodeID() const
7111 if ( _meshDS ) return _meshDS->MaxNodeID();
7112 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7114 // -------------------------------------------------------------------------------------
7115 int SMESH_MeshPartDS::MinNodeID() const
7117 if ( _meshDS ) return _meshDS->MinNodeID();
7118 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7120 // -------------------------------------------------------------------------------------
7121 int SMESH_MeshPartDS::MaxElementID() const
7123 if ( _meshDS ) return _meshDS->MaxElementID();
7125 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7126 if ( !_elements[ iType ].empty() )
7127 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7130 // -------------------------------------------------------------------------------------
7131 int SMESH_MeshPartDS::MinElementID() const
7133 if ( _meshDS ) return _meshDS->MinElementID();
7135 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7136 if ( !_elements[ iType ].empty() )
7137 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7140 // -------------------------------------------------------------------------------------
7141 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7143 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7145 typedef SMDS_SetIterator
7146 <const SMDS_MeshElement*,
7147 TIDSortedElemSet::const_iterator,
7148 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7149 SMDS_MeshElement::GeomFilter
7152 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7154 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7155 _elements[type].end(),
7156 SMDS_MeshElement::GeomFilter( geomType )));
7158 // -------------------------------------------------------------------------------------
7159 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7161 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7163 typedef SMDS_SetIterator
7164 <const SMDS_MeshElement*,
7165 TIDSortedElemSet::const_iterator,
7166 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7167 SMDS_MeshElement::EntityFilter
7170 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7172 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7173 _elements[type].end(),
7174 SMDS_MeshElement::EntityFilter( entity )));
7176 // -------------------------------------------------------------------------------------
7177 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7179 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7180 if ( type == SMDSAbs_All && !_meshDS )
7182 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7184 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7185 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7187 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7189 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7190 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7192 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7193 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7195 // -------------------------------------------------------------------------------------
7196 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7197 iterType SMESH_MeshPartDS::methName() const \
7199 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7200 return _meshDS ? _meshDS->methName() : iterType \
7201 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7203 // -------------------------------------------------------------------------------------
7204 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7205 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7206 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7207 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7208 #undef _GET_ITER_DEFINE
7210 // END Implementation of SMESH_MeshPartDS
7212 //================================================================================