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 )
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief Return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 Unexpect aCatch(SALOME_SalomeException);
212 res = _impl->HasShapeToMesh();
214 catch(SALOME_Exception & S_ex) {
215 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
220 //================================================================================
222 * \brief Return the shape to mesh
224 //================================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 Unexpect aCatch(SALOME_SalomeException);
229 GEOM::GEOM_Object_var aShapeObj;
231 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
234 aShapeObj = _gen_i->ShapeToGeomObject( S );
235 if ( aShapeObj->_is_nil() )
237 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
238 // find GEOM_Object by entry (IPAL52735)
239 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
240 for ( ; data != _geomGroupData.end(); ++data )
241 if ( data->_smeshObject->_is_equivalent( _this() ))
243 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
244 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
245 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
251 catch(SALOME_Exception & S_ex) {
252 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
254 return aShapeObj._retn();
257 //================================================================================
259 * \brief Return false if the mesh is not yet fully loaded from the study file
261 //================================================================================
263 CORBA::Boolean SMESH_Mesh_i::IsLoaded()
265 Unexpect aCatch(SALOME_SalomeException);
266 return !_preMeshInfo;
269 //================================================================================
271 * \brief Load full mesh data from the study file
273 //================================================================================
275 void SMESH_Mesh_i::Load()
277 Unexpect aCatch(SALOME_SalomeException);
279 _preMeshInfo->FullLoadFromFile();
282 //================================================================================
284 * \brief Remove all nodes and elements
286 //================================================================================
288 void SMESH_Mesh_i::Clear()
290 Unexpect aCatch(SALOME_SalomeException);
292 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
296 //CheckGeomGroupModif(); // issue 20145
298 catch(SALOME_Exception & S_ex) {
299 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
302 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
304 SMESH::SMESH_Mesh_var mesh = _this();
305 _gen_i->UpdateIcons( mesh );
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Import mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 Unexpect aCatch(SALOME_SalomeException);
397 status = _impl->MEDToMesh( theFileName, theMeshName );
399 catch( SALOME_Exception& S_ex ) {
400 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
403 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
406 CreateGroupServants();
408 int major, minor, release;
409 major = minor = release = 0;
410 MED::GetMEDVersion(theFileName, major, minor, release);
411 _medFileInfo = new SMESH::MedFileInfo();
412 _medFileInfo->fileName = theFileName;
413 _medFileInfo->fileSize = 0;
414 _medFileInfo->major = major;
415 _medFileInfo->minor = minor;
416 _medFileInfo->release = release;
417 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
419 return ConvertDriverMEDReadStatus(status);
422 //================================================================================
424 * \brief Import mesh data from the CGNS file
426 //================================================================================
428 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
429 const int theMeshIndex,
430 std::string& theMeshName )
432 Unexpect aCatch(SALOME_SalomeException);
435 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
437 catch( SALOME_Exception& S_ex ) {
438 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
441 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
444 CreateGroupServants();
446 _medFileInfo = new SMESH::MedFileInfo();
447 _medFileInfo->fileName = theFileName;
448 _medFileInfo->major = 0;
449 _medFileInfo->minor = 0;
450 _medFileInfo->release = 0;
451 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
453 return ConvertDriverMEDReadStatus(status);
456 //================================================================================
458 * \brief Return string representation of a MED file version comprising nbDigits
460 //================================================================================
462 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
464 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
466 return CORBA::string_dup( ver.c_str() );
469 //================================================================================
471 * Return the list of med versions compatibles for write/append,
472 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
474 //================================================================================
476 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
478 SMESH::long_array_var aResult = new SMESH::long_array();
479 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
480 long nbver = mvok.size();
481 aResult->length( nbver );
482 for ( int i = 0; i < nbver; i++ )
483 aResult[i] = mvok[i];
484 return aResult._retn();
487 //=============================================================================
491 * Import mesh data from MED file
493 //=============================================================================
495 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
499 // Read mesh with name = <theMeshName> into SMESH_Mesh
500 _impl->UNVToMesh( theFileName );
502 CreateGroupServants();
504 _medFileInfo = new SMESH::MedFileInfo();
505 _medFileInfo->fileName = theFileName;
506 _medFileInfo->major = 0;
507 _medFileInfo->minor = 0;
508 _medFileInfo->release = 0;
509 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
511 SMESH_CATCH( SMESH::throwCorbaException );
516 //=============================================================================
520 * Import mesh data from STL file
522 //=============================================================================
524 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
528 // Read mesh with name = <theMeshName> into SMESH_Mesh
529 std::string name = _impl->STLToMesh( theFileName );
532 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
533 _gen_i->SetName( meshSO, name.c_str() );
535 _medFileInfo = new SMESH::MedFileInfo();
536 _medFileInfo->fileName = theFileName;
537 _medFileInfo->major = 0;
538 _medFileInfo->minor = 0;
539 _medFileInfo->release = 0;
540 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
542 SMESH_CATCH( SMESH::throwCorbaException );
547 //================================================================================
549 * \brief Function used in SMESH_CATCH by ImportGMFFile()
551 //================================================================================
555 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
557 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
561 //================================================================================
563 * \brief Import data from a GMF file and return an error description
565 //================================================================================
567 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
568 bool theMakeRequiredGroups )
570 SMESH_ComputeErrorPtr error;
573 #define SMESH_CAUGHT error =
576 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
578 _medFileInfo = new SMESH::MedFileInfo();
579 _medFileInfo->fileName = theFileName;
580 _medFileInfo->major = 0;
581 _medFileInfo->minor = 0;
582 _medFileInfo->release = 0;
583 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
585 SMESH_CATCH( exceptionToComputeError );
589 CreateGroupServants();
591 return ConvertComputeError( error );
594 //=============================================================================
596 * \brief Convert SMESH_Hypothesis::Hypothesis_Status into SMESH::Hypothesis_Status
598 //=============================================================================
600 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
602 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
603 (SMESH_Hypothesis::Hypothesis_Status theStatus)
606 RETURNCASE( HYP_OK );
607 RETURNCASE( HYP_MISSING );
608 RETURNCASE( HYP_CONCURRENT );
609 RETURNCASE( HYP_BAD_PARAMETER );
610 RETURNCASE( HYP_HIDDEN_ALGO );
611 RETURNCASE( HYP_HIDING_ALGO );
612 RETURNCASE( HYP_UNKNOWN_FATAL );
613 RETURNCASE( HYP_INCOMPATIBLE );
614 RETURNCASE( HYP_NOTCONFORM );
615 RETURNCASE( HYP_ALREADY_EXIST );
616 RETURNCASE( HYP_BAD_DIM );
617 RETURNCASE( HYP_BAD_SUBSHAPE );
618 RETURNCASE( HYP_BAD_GEOMETRY );
619 RETURNCASE( HYP_NEED_SHAPE );
620 RETURNCASE( HYP_INCOMPAT_HYPS );
623 return SMESH::HYP_UNKNOWN_FATAL;
626 //=============================================================================
630 * Call internal addHypothesis() and then add a reference to <anHyp> under
631 * the SObject actually having a reference to <aSubShape>.
632 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
634 //=============================================================================
636 SMESH::Hypothesis_Status
637 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
638 SMESH::SMESH_Hypothesis_ptr anHyp,
639 CORBA::String_out anErrorText)
641 Unexpect aCatch(SALOME_SalomeException);
643 _preMeshInfo->ForgetOrLoad();
645 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
648 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
649 anErrorText = error.c_str();
651 SMESH::SMESH_Mesh_var mesh( _this() );
652 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
654 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
656 //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
657 if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ )
658 _gen_i->UpdateIcons( mesh );
660 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
662 // Update Python script
663 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
664 << aSubShape << ", " << anHyp << " )";
666 return ConvertHypothesisStatus(status);
669 //================================================================================
671 * \brief Create a sub-mesh and add a hypothesis to it
673 //================================================================================
675 SMESH_Hypothesis::Hypothesis_Status
676 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
677 SMESH::SMESH_Hypothesis_ptr anHyp,
678 std::string* anErrorText)
680 if(MYDEBUG) MESSAGE("addHypothesis");
682 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
683 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
685 if (CORBA::is_nil( anHyp ))
686 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
688 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
691 TopoDS_Shape myLocSubShape;
692 //use PseudoShape in case if mesh has no shape
694 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
696 myLocSubShape = _impl->GetShapeToMesh();
698 const int hypId = anHyp->GetId();
700 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
701 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
703 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
705 // assure there is a corresponding submesh
706 if ( !_impl->IsMainShape( myLocSubShape )) {
707 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
708 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
709 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
712 else if ( anErrorText )
714 *anErrorText = error;
717 catch(SALOME_Exception & S_ex)
719 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
724 //================================================================================
726 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
728 //================================================================================
730 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
731 SMESH::SMESH_Hypothesis_ptr anHyp)
733 Unexpect aCatch(SALOME_SalomeException);
735 _preMeshInfo->ForgetOrLoad();
737 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
738 SMESH::SMESH_Mesh_var mesh = _this();
740 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
742 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
743 _gen_i->UpdateIcons( mesh );
745 // Update Python script
746 if(_impl->HasShapeToMesh())
747 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
748 << aSubShape << ", " << anHyp << " )";
750 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
753 return ConvertHypothesisStatus(status);
756 //=============================================================================
758 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
760 //=============================================================================
762 SMESH_Hypothesis::Hypothesis_Status
763 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
764 SMESH::SMESH_Hypothesis_ptr anHyp)
766 if(MYDEBUG) MESSAGE("removeHypothesis()");
768 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
769 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
771 if (CORBA::is_nil( anHyp ))
772 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
775 _preMeshInfo->ForgetOrLoad();
777 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
780 TopoDS_Shape myLocSubShape;
781 //use PseudoShape in case if mesh has no shape
782 if( _impl->HasShapeToMesh() )
783 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
785 myLocSubShape = _impl->GetShapeToMesh();
787 const int hypId = anHyp->GetId();
788 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
789 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
791 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
795 catch(SALOME_Exception & S_ex)
797 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
802 //================================================================================
804 * \brief Return hypotheses assigned to a given sub-shape
806 //================================================================================
808 SMESH::ListOfHypothesis *
809 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
811 Unexpect aCatch(SALOME_SalomeException);
812 if (MYDEBUG) MESSAGE("GetHypothesisList");
813 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
814 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
816 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
819 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
820 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
821 myLocSubShape = _impl->GetShapeToMesh();
822 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
823 int i = 0, n = aLocalList.size();
826 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
827 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
828 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
830 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
831 if ( id_hypptr != _mapHypo.end() )
832 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
836 catch(SALOME_Exception & S_ex) {
837 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
840 return aList._retn();
843 //================================================================================
845 * \brief Return sub-meshes
847 //================================================================================
849 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes()
851 Unexpect aCatch(SALOME_SalomeException);
852 if (MYDEBUG) MESSAGE("GetSubMeshes");
854 SMESH::submesh_array_var aList = new SMESH::submesh_array();
857 TPythonDump aPythonDump;
858 if ( !_mapSubMeshIor.empty() )
862 aList->length( _mapSubMeshIor.size() );
864 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
865 for ( ; it != _mapSubMeshIor.end(); it++ ) {
866 if ( CORBA::is_nil( it->second )) continue;
867 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
869 if (i > 1) aPythonDump << ", ";
870 aPythonDump << it->second;
874 catch(SALOME_Exception & S_ex) {
875 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
878 // Update Python script
879 if ( !_mapSubMeshIor.empty() )
880 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
882 return aList._retn();
885 //================================================================================
887 * \brief Create and return a sub-mesh on the given sub-shape
889 //================================================================================
891 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
892 const char* theName )
894 Unexpect aCatch(SALOME_SalomeException);
895 if (CORBA::is_nil(aSubShape))
896 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
898 SMESH::SMESH_subMesh_var subMesh;
899 SMESH::SMESH_Mesh_var aMesh = _this();
901 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
903 //Get or Create the SMESH_subMesh object implementation
905 TopoDS_Iterator it( myLocSubShape );
906 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
907 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
908 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
909 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
913 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
915 subMesh = getSubMesh( subMeshId );
917 // create a new subMesh object servant if there is none for the shape
918 if ( subMesh->_is_nil() )
919 subMesh = createSubMesh( aSubShape );
920 if ( _gen_i->CanPublishInStudy( subMesh ))
922 SALOMEDS::SObject_wrap aSO =
923 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
924 if ( !aSO->_is_nil()) {
925 // Update Python script
926 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
927 << aSubShape << ", '" << theName << "' )";
931 catch(SALOME_Exception & S_ex) {
932 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
934 return subMesh._retn();
937 //================================================================================
939 * \brief Remove a sub-mesh
941 //================================================================================
943 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
947 if ( theSubMesh->_is_nil() )
950 GEOM::GEOM_Object_var aSubShape;
951 // Remove submesh's SObject
952 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
953 if ( !anSO->_is_nil() ) {
954 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
955 SALOMEDS::SObject_wrap anObj, aRef;
956 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
957 anObj->ReferencedObject( aRef.inout() ))
959 CORBA::Object_var obj = aRef->GetObject();
960 aSubShape = GEOM::GEOM_Object::_narrow( obj );
962 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
963 // aSubShape = theSubMesh->GetSubShape();
965 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
966 builder->RemoveObjectWithChildren( anSO );
968 // Update Python script
969 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
972 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
974 _preMeshInfo->ForgetOrLoad();
976 SMESH_CATCH( SMESH::throwCorbaException );
979 //================================================================================
981 * \brief Create a standalone group
983 //================================================================================
985 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
986 const char* theName )
988 Unexpect aCatch(SALOME_SalomeException);
990 _preMeshInfo->FullLoadFromFile();
992 SMESH::SMESH_Group_var aNewGroup =
993 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
995 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
997 SMESH::SMESH_Mesh_var mesh = _this();
998 SALOMEDS::SObject_wrap aSO =
999 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1000 if ( !aSO->_is_nil())
1001 // Update Python script
1002 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1003 << theElemType << ", '" << theName << "' )";
1005 return aNewGroup._retn();
1008 //================================================================================
1010 * \brief Create a group based on the given geometry
1012 //================================================================================
1014 SMESH::SMESH_GroupOnGeom_ptr
1015 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1016 const char* theName,
1017 GEOM::GEOM_Object_ptr theGeomObj)
1019 Unexpect aCatch(SALOME_SalomeException);
1021 _preMeshInfo->FullLoadFromFile();
1023 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1025 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1026 if ( !aShape.IsNull() )
1029 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1031 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1033 SMESH::SMESH_Mesh_var mesh = _this();
1034 SALOMEDS::SObject_wrap aSO =
1035 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1036 if ( !aSO->_is_nil())
1037 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1038 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1042 return aNewGroup._retn();
1045 //================================================================================
1047 * \brief Creates a group whose contents is defined by filter
1048 * \param theElemType - group type
1049 * \param theName - group name
1050 * \param theFilter - the filter
1051 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1053 //================================================================================
1055 SMESH::SMESH_GroupOnFilter_ptr
1056 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1057 const char* theName,
1058 SMESH::Filter_ptr theFilter )
1060 Unexpect aCatch(SALOME_SalomeException);
1062 _preMeshInfo->FullLoadFromFile();
1064 if ( CORBA::is_nil( theFilter ))
1065 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1067 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1069 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1071 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1072 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1075 if ( !aNewGroup->_is_nil() )
1076 aNewGroup->SetFilter( theFilter );
1078 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1080 SMESH::SMESH_Mesh_var mesh = _this();
1081 SALOMEDS::SObject_wrap aSO =
1082 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1084 if ( !aSO->_is_nil())
1085 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1086 << theElemType << ", '" << theName << "', " << theFilter << " )";
1088 return aNewGroup._retn();
1091 //================================================================================
1093 * \brief Remove a group
1095 //================================================================================
1097 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1099 if ( theGroup->_is_nil() )
1104 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1108 if ( aGroup->GetMeshServant() != this )
1109 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1110 SALOME::BAD_PARAM );
1112 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1113 if ( !aGroupSO->_is_nil() )
1115 // Update Python script
1116 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1118 // Remove group's SObject
1119 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1120 builder->RemoveObjectWithChildren( aGroupSO );
1122 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1124 // Remove the group from SMESH data structures
1125 removeGroup( aGroup->GetLocalID() );
1127 SMESH_CATCH( SMESH::throwCorbaException );
1130 //=============================================================================
1132 * Remove group with its contents
1134 //=============================================================================
1136 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1140 _preMeshInfo->FullLoadFromFile();
1142 if ( theGroup->_is_nil() )
1145 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1146 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1147 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1150 vector<int> nodeIds; // to remove nodes becoming free
1151 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1152 if ( !isNodal && !theGroup->IsEmpty() )
1154 CORBA::Long elemID = theGroup->GetID( 1 );
1155 int nbElemNodes = GetElemNbNodes( elemID );
1156 if ( nbElemNodes > 0 )
1157 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1160 // Retrieve contents
1161 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1162 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1163 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1164 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1165 elems.assign( elemBeg, elemEnd );
1167 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1170 RemoveGroup( theGroup );
1173 for ( size_t i = 0; i < elems.size(); ++i )
1175 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1179 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1180 nodeIds.push_back( nIt->next()->GetID() );
1182 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1186 _impl->GetMeshDS()->RemoveElement( elems[i] );
1190 // Remove free nodes
1191 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1192 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1193 if ( n->NbInverseElements() == 0 )
1194 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1196 // Update Python script (theGroup must be alive for this)
1197 pyDump << SMESH::SMESH_Mesh_var(_this())
1198 << ".RemoveGroupWithContents( " << theGroup << " )";
1200 SMESH_CATCH( SMESH::throwCorbaException );
1203 //================================================================================
1205 * \brief Get the list of groups existing in the mesh
1206 * \retval SMESH::ListOfGroups * - list of groups
1208 //================================================================================
1210 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups()
1212 Unexpect aCatch(SALOME_SalomeException);
1213 if (MYDEBUG) MESSAGE("GetGroups");
1215 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1218 TPythonDump aPythonDump;
1219 if ( !_mapGroups.empty() )
1221 aPythonDump << "[ ";
1223 aList->length( _mapGroups.size() );
1225 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1226 for ( ; it != _mapGroups.end(); it++ ) {
1227 if ( CORBA::is_nil( it->second )) continue;
1228 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1230 if (i > 1) aPythonDump << ", ";
1231 aPythonDump << it->second;
1235 catch(SALOME_Exception & S_ex) {
1236 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1238 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1240 return aList._retn();
1243 //=============================================================================
1245 * Get number of groups existing in the mesh
1247 //=============================================================================
1249 CORBA::Long SMESH_Mesh_i::NbGroups()
1251 Unexpect aCatch(SALOME_SalomeException);
1252 return _mapGroups.size();
1255 //=============================================================================
1257 * New group including all mesh elements present in initial groups is created.
1259 //=============================================================================
1261 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1262 SMESH::SMESH_GroupBase_ptr theGroup2,
1263 const char* theName )
1265 SMESH::SMESH_Group_var aResGrp;
1269 _preMeshInfo->FullLoadFromFile();
1271 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1272 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1274 if ( theGroup1->GetType() != theGroup2->GetType() )
1275 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1280 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1281 if ( aResGrp->_is_nil() )
1282 return SMESH::SMESH_Group::_nil();
1284 aResGrp->AddFrom( theGroup1 );
1285 aResGrp->AddFrom( theGroup2 );
1287 // Update Python script
1288 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1289 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1291 SMESH_CATCH( SMESH::throwCorbaException );
1293 return aResGrp._retn();
1296 //=============================================================================
1298 * \brief New group including all mesh elements present in initial groups is created.
1299 * \param theGroups list of groups
1300 * \param theName name of group to be created
1301 * \return pointer to the new group
1303 //=============================================================================
1305 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1306 const char* theName )
1308 SMESH::SMESH_Group_var aResGrp;
1311 _preMeshInfo->FullLoadFromFile();
1314 return SMESH::SMESH_Group::_nil();
1319 SMESH::ElementType aType = SMESH::ALL;
1320 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1322 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1323 if ( CORBA::is_nil( aGrp ) )
1325 if ( aType == SMESH::ALL )
1326 aType = aGrp->GetType();
1327 else if ( aType != aGrp->GetType() )
1328 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1331 if ( aType == SMESH::ALL )
1332 return SMESH::SMESH_Group::_nil();
1337 aResGrp = CreateGroup( aType, theName );
1338 if ( aResGrp->_is_nil() )
1339 return SMESH::SMESH_Group::_nil();
1341 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1342 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1344 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1345 if ( !CORBA::is_nil( aGrp ) )
1347 aResGrp->AddFrom( aGrp );
1348 if ( g > 0 ) pyDump << ", ";
1352 pyDump << " ], '" << theName << "' )";
1354 SMESH_CATCH( SMESH::throwCorbaException );
1356 return aResGrp._retn();
1359 //=============================================================================
1361 * New group is created. All mesh elements that are
1362 * present in both initial groups are added to the new one.
1364 //=============================================================================
1366 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1367 SMESH::SMESH_GroupBase_ptr theGroup2,
1368 const char* theName )
1370 SMESH::SMESH_Group_var aResGrp;
1375 _preMeshInfo->FullLoadFromFile();
1377 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1378 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1380 if ( theGroup1->GetType() != theGroup2->GetType() )
1381 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1385 // Create Intersection
1386 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1387 if ( aResGrp->_is_nil() )
1388 return aResGrp._retn();
1390 SMESHDS_GroupBase* groupDS1 = 0;
1391 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1392 groupDS1 = grp_i->GetGroupDS();
1394 SMESHDS_GroupBase* groupDS2 = 0;
1395 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1396 groupDS2 = grp_i->GetGroupDS();
1398 SMESHDS_Group* resGroupDS = 0;
1399 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1400 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1402 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1404 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1405 while ( elemIt1->more() )
1407 const SMDS_MeshElement* e = elemIt1->next();
1408 if ( groupDS2->Contains( e ))
1409 resGroupDS->SMDSGroup().Add( e );
1412 // Update Python script
1413 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1414 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1416 SMESH_CATCH( SMESH::throwCorbaException );
1418 return aResGrp._retn();
1421 //=============================================================================
1423 \brief Intersect list of groups. New group is created. All mesh elements that
1424 are present in all initial groups simultaneously are added to the new one.
1425 \param theGroups list of groups
1426 \param theName name of group to be created
1427 \return pointer on the group
1429 //=============================================================================
1431 SMESH::SMESH_Group_ptr
1432 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1433 const char* theName )
1435 SMESH::SMESH_Group_var aResGrp;
1440 _preMeshInfo->FullLoadFromFile();
1443 return SMESH::SMESH_Group::_nil();
1445 // check types and get SMESHDS_GroupBase's
1446 SMESH::ElementType aType = SMESH::ALL;
1447 vector< SMESHDS_GroupBase* > groupVec;
1448 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1450 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1451 if ( CORBA::is_nil( aGrp ) )
1453 if ( aType == SMESH::ALL )
1454 aType = aGrp->GetType();
1455 else if ( aType != aGrp->GetType() )
1456 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1459 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1460 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1462 if ( grpDS->IsEmpty() )
1467 groupVec.push_back( grpDS );
1470 if ( aType == SMESH::ALL ) // all groups are nil
1471 return SMESH::SMESH_Group::_nil();
1476 aResGrp = CreateGroup( aType, theName );
1478 SMESHDS_Group* resGroupDS = 0;
1479 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1480 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1481 if ( !resGroupDS || groupVec.empty() )
1482 return aResGrp._retn();
1485 size_t i, nb = groupVec.size();
1486 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1487 while ( elemIt1->more() )
1489 const SMDS_MeshElement* e = elemIt1->next();
1491 for ( i = 1; ( i < nb && inAll ); ++i )
1492 inAll = groupVec[i]->Contains( e );
1495 resGroupDS->SMDSGroup().Add( e );
1498 // Update Python script
1499 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1500 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1502 SMESH_CATCH( SMESH::throwCorbaException );
1504 return aResGrp._retn();
1507 //=============================================================================
1509 * New group is created. All mesh elements that are present in
1510 * a main group but is not present in a tool group are added to the new one
1512 //=============================================================================
1514 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1515 SMESH::SMESH_GroupBase_ptr theGroup2,
1516 const char* theName )
1518 SMESH::SMESH_Group_var aResGrp;
1523 _preMeshInfo->FullLoadFromFile();
1525 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1526 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1528 if ( theGroup1->GetType() != theGroup2->GetType() )
1529 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1533 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1534 if ( aResGrp->_is_nil() )
1535 return aResGrp._retn();
1537 SMESHDS_GroupBase* groupDS1 = 0;
1538 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1539 groupDS1 = grp_i->GetGroupDS();
1541 SMESHDS_GroupBase* groupDS2 = 0;
1542 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1543 groupDS2 = grp_i->GetGroupDS();
1545 SMESHDS_Group* resGroupDS = 0;
1546 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1547 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1549 if ( groupDS1 && groupDS2 && resGroupDS )
1551 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1552 while ( elemIt1->more() )
1554 const SMDS_MeshElement* e = elemIt1->next();
1555 if ( !groupDS2->Contains( e ))
1556 resGroupDS->SMDSGroup().Add( e );
1559 // Update Python script
1560 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1561 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1563 SMESH_CATCH( SMESH::throwCorbaException );
1565 return aResGrp._retn();
1568 //=============================================================================
1570 \brief Cut lists of groups. New group is created. All mesh elements that are
1571 present in main groups but do not present in tool groups are added to the new one
1572 \param theMainGroups list of main groups
1573 \param theToolGroups list of tool groups
1574 \param theName name of group to be created
1575 \return pointer on the group
1577 //=============================================================================
1579 SMESH::SMESH_Group_ptr
1580 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1581 const SMESH::ListOfGroups& theToolGroups,
1582 const char* theName )
1584 SMESH::SMESH_Group_var aResGrp;
1589 _preMeshInfo->FullLoadFromFile();
1592 return SMESH::SMESH_Group::_nil();
1594 // check types and get SMESHDS_GroupBase's
1595 SMESH::ElementType aType = SMESH::ALL;
1596 vector< SMESHDS_GroupBase* > toolGroupVec;
1597 vector< SMDS_ElemIteratorPtr > mainIterVec;
1599 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1601 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1602 if ( CORBA::is_nil( aGrp ) )
1604 if ( aType == SMESH::ALL )
1605 aType = aGrp->GetType();
1606 else if ( aType != aGrp->GetType() )
1607 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1609 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1610 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1611 if ( !grpDS->IsEmpty() )
1612 mainIterVec.push_back( grpDS->GetElements() );
1614 if ( aType == SMESH::ALL ) // all main groups are nil
1615 return SMESH::SMESH_Group::_nil();
1616 if ( mainIterVec.empty() ) // all main groups are empty
1617 return aResGrp._retn();
1619 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1621 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1622 if ( CORBA::is_nil( aGrp ) )
1624 if ( aType != aGrp->GetType() )
1625 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1627 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1628 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1629 toolGroupVec.push_back( grpDS );
1635 aResGrp = CreateGroup( aType, theName );
1637 SMESHDS_Group* resGroupDS = 0;
1638 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1639 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1641 return aResGrp._retn();
1644 size_t i, nb = toolGroupVec.size();
1645 SMDS_ElemIteratorPtr mainElemIt
1646 ( new SMDS_IteratorOnIterators
1647 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1648 while ( mainElemIt->more() )
1650 const SMDS_MeshElement* e = mainElemIt->next();
1652 for ( i = 0; ( i < nb && !isIn ); ++i )
1653 isIn = toolGroupVec[i]->Contains( e );
1656 resGroupDS->SMDSGroup().Add( e );
1659 // Update Python script
1660 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1661 << ".CutListOfGroups( " << theMainGroups << ", "
1662 << theToolGroups << ", '" << theName << "' )";
1664 SMESH_CATCH( SMESH::throwCorbaException );
1666 return aResGrp._retn();
1669 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1671 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int /*nbCorners*/,
1672 bool & toStopChecking )
1674 toStopChecking = ( nbCommon < nbChecked );
1675 return nbCommon == nbNodes;
1677 bool isMainNodesCommon(int nbChecked, int nbCommon, int /*nbNodes*/, int nbCorners,
1678 bool & toStopChecking )
1680 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1681 return nbCommon == nbCorners;
1683 bool isAtLeastOneNodeCommon(int /*nbChecked*/, int nbCommon, int /*nbNodes*/, int /*nbCorners*/,
1684 bool & /*toStopChecking*/ )
1686 return nbCommon > 0;
1688 bool isMajorityOfNodesCommon(int /*nbChecked*/, int nbCommon, int nbNodes, int /*nbCorners*/,
1689 bool & /*toStopChecking*/ )
1691 return nbCommon >= (nbNodes+1) / 2;
1695 //=============================================================================
1697 * Create a group of entities basing on nodes of other groups.
1698 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1699 * \param [in] anElemType - a type of elements to include to the new group.
1700 * \param [in] theName - a name of the new group.
1701 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1702 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1703 * new group provided that it is based on nodes of an element of \a aListOfGroups
1704 * \return SMESH_Group - the created group
1706 // IMP 19939, bug 22010, IMP 22635
1707 //=============================================================================
1709 SMESH::SMESH_Group_ptr
1710 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1711 SMESH::ElementType theElemType,
1712 const char* theName,
1713 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1714 CORBA::Boolean theUnderlyingOnly)
1716 SMESH::SMESH_Group_var aResGrp;
1720 _preMeshInfo->FullLoadFromFile();
1722 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1724 if ( !theName || !aMeshDS )
1725 return SMESH::SMESH_Group::_nil();
1727 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1729 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1730 SMESH_Comment nbCoNoStr( "SMESH.");
1731 switch ( theNbCommonNodes ) {
1732 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1733 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1734 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1735 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1736 default: return aResGrp._retn();
1738 int nbChecked, nbCommon, nbNodes, nbCorners;
1744 aResGrp = CreateGroup( theElemType, theName );
1745 if ( aResGrp->_is_nil() )
1746 return SMESH::SMESH_Group::_nil();
1748 SMESHDS_GroupBase* groupBaseDS =
1749 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1750 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1752 vector<bool> isNodeInGroups;
1754 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1756 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1757 if ( CORBA::is_nil( aGrp ) )
1759 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1760 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1763 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1764 if ( !elIt ) continue;
1766 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1768 while ( elIt->more() ) {
1769 const SMDS_MeshElement* el = elIt->next();
1770 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1771 while ( nIt->more() )
1772 resGroupCore.Add( nIt->next() );
1775 // get elements of theElemType based on nodes of every element of group
1776 else if ( theUnderlyingOnly )
1778 while ( elIt->more() )
1780 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1781 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1782 TIDSortedElemSet checkedElems;
1783 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1784 while ( nIt->more() )
1786 const SMDS_MeshNode* n = nIt->next();
1787 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1788 // check nodes of elements of theElemType around el
1789 while ( elOfTypeIt->more() )
1791 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1792 if ( !checkedElems.insert( elOfType ).second ) continue;
1793 nbNodes = elOfType->NbNodes();
1794 nbCorners = elOfType->NbCornerNodes();
1796 bool toStopChecking = false;
1797 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1798 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1799 if ( elNodes.count( nIt2->next() ) &&
1800 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1802 resGroupCore.Add( elOfType );
1809 // get all nodes of elements of groups
1812 while ( elIt->more() )
1814 const SMDS_MeshElement* el = elIt->next(); // an element of group
1815 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1816 while ( nIt->more() )
1818 const SMDS_MeshNode* n = nIt->next();
1819 if ( n->GetID() >= (int) isNodeInGroups.size() )
1820 isNodeInGroups.resize( n->GetID() + 1, false );
1821 isNodeInGroups[ n->GetID() ] = true;
1827 // Get elements of theElemType based on a certain number of nodes of elements of groups
1828 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1830 const SMDS_MeshNode* n;
1831 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1832 const int isNodeInGroupsSize = isNodeInGroups.size();
1833 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1835 if ( !isNodeInGroups[ iN ] ||
1836 !( n = aMeshDS->FindNode( iN )))
1839 // check nodes of elements of theElemType around n
1840 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1841 while ( elOfTypeIt->more() )
1843 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1844 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1849 nbNodes = elOfType->NbNodes();
1850 nbCorners = elOfType->NbCornerNodes();
1852 bool toStopChecking = false;
1853 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1854 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1856 const int nID = nIt->next()->GetID();
1857 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1858 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1860 resGroupCore.Add( elOfType );
1868 // Update Python script
1869 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1870 << ".CreateDimGroup( "
1871 << theGroups << ", " << theElemType << ", '" << theName << "', "
1872 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1874 SMESH_CATCH( SMESH::throwCorbaException );
1876 return aResGrp._retn();
1879 //================================================================================
1881 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1882 * existing 1D elements as group boundaries.
1883 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1884 * adjacent faces is more than \a sharpAngle in degrees.
1885 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1886 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1887 * \return ListOfGroups - the created groups
1889 //================================================================================
1891 SMESH::ListOfGroups*
1892 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1893 CORBA::Boolean theCreateEdges,
1894 CORBA::Boolean theUseExistingEdges )
1896 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1897 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1900 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1906 _preMeshInfo->FullLoadFromFile();
1908 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1910 std::vector< SMESH_MeshAlgos::Edge > edges =
1911 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1913 if ( theCreateEdges )
1915 std::vector<const SMDS_MeshNode *> nodes(2);
1916 for ( size_t i = 0; i < edges.size(); ++i )
1918 nodes[0] = edges[i]._node1;
1919 nodes[1] = edges[i]._node2;
1920 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1922 if ( edges[i]._medium )
1923 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1925 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1929 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1930 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1932 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1934 resultGroups->length( faceGroups.size() );
1935 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1937 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1938 _editor->GenerateGroupName("Group").c_str());
1939 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1941 SMESHDS_GroupBase* groupBaseDS =
1942 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1943 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1945 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1946 for ( size_t i = 0; i < faces.size(); ++i )
1947 groupCore.Add( faces[i] );
1950 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1951 << ".FaceGroupsSeparatedByEdges( "
1952 << TVar( theSharpAngle ) << ", "
1953 << theCreateEdges << ", "
1954 << theUseExistingEdges << " )";
1956 SMESH_CATCH( SMESH::throwCorbaException );
1957 return resultGroups._retn();
1961 //================================================================================
1963 * \brief Remember GEOM group data
1965 //================================================================================
1967 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1968 CORBA::Object_ptr theSmeshObj)
1970 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1973 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1974 if ( groupSO->_is_nil() )
1977 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
1978 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
1979 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1982 _geomGroupData.push_back( TGeomGroupData() );
1983 TGeomGroupData & groupData = _geomGroupData.back();
1985 CORBA::String_var entry = groupSO->GetID();
1986 groupData._groupEntry = entry.in();
1988 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1989 groupData._indices.insert( ids[i] );
1991 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1992 // shape index in SMESHDS
1993 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1994 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1997 //================================================================================
1999 * Remove GEOM group data relating to removed smesh object
2001 //================================================================================
2003 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2005 list<TGeomGroupData>::iterator
2006 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2007 for ( ; data != dataEnd; ++data ) {
2008 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2009 _geomGroupData.erase( data );
2015 //================================================================================
2017 * \brief Replace a shape in the mesh upon Break Link
2019 //================================================================================
2021 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2023 // check if geometry changed
2024 bool geomChanged = true;
2025 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2026 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2027 geomChanged = ( //oldGeom->_is_equivalent( theNewGeom ) ||
2028 oldGeom->GetTick() < theNewGeom->GetTick() );
2030 TopoDS_Shape S = _impl->GetShapeToMesh();
2031 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2032 TCollection_AsciiString aIOR;
2033 CORBA::String_var ior;
2034 if ( geomClient->Find( S, aIOR ))
2035 geomClient->RemoveShapeFromBuffer( aIOR );
2037 // clear buffer also for sub-groups
2038 const std::set<SMESHDS_GroupBase*>& groups = _impl->GetMeshDS()->GetGroups();
2039 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2040 for (; g != groups.end(); ++g)
2041 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2043 const TopoDS_Shape& s = group->GetShape();
2044 if ( geomClient->Find( s, aIOR ))
2045 geomClient->RemoveShapeFromBuffer( aIOR );
2049 int shapeID, fromID, toID; // indices of elements of a sub-mesh
2051 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2052 std::vector< SMDS_PositionPtr > positions; // node positions
2053 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2056 // store positions of elements on geometry
2058 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2059 meshDS->MaxElementID() > meshDS->NbElements() )
2062 meshDS->CompactMesh();
2064 positions.resize( meshDS->NbNodes() + 1 );
2065 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2067 const SMDS_MeshNode* n = nodeIt->next();
2068 positions[ n->GetID() ] = n->GetPosition();
2071 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2072 for ( int isNode = 0; isNode < 2; ++isNode )
2074 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2075 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2076 ranges.push_back( TRange{ 0,0,0 });
2077 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2078 while ( elemIt->more() )
2080 const SMDS_MeshElement* e = elemIt->next();
2081 const int elemID = e->GetID();
2082 const int shapeID = e->GetShapeID();
2083 TRange & lastRange = ranges.back();
2084 if ( lastRange.shapeID != shapeID ||
2085 lastRange.toID != elemID )
2086 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2088 lastRange.toID = elemID + 1;
2090 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2092 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2093 else sm->RemoveElement( e );
2100 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2101 SMESH::SMESH_Mesh_var me = _this();
2102 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2103 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2104 if ( !aSO->_is_nil() )
2106 SALOMEDS::SObject_wrap aShapeRefSO;
2107 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2109 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2110 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2111 builder->Addreference( aShapeRefSO, aShapeSO );
2115 // re-assign global hypotheses to the new shape
2116 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2117 CheckGeomModif( true );
2121 // restore positions of elements on geometry
2122 for ( int isNode = 0; isNode < 2; ++isNode )
2124 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2125 for ( size_t i = 1; i < ranges.size(); ++i )
2127 int elemID = ranges[ i ].fromID;
2128 int toID = ranges[ i ].toID;
2129 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2131 for ( ; elemID < toID; ++elemID )
2132 smDS->AddNode( meshDS->FindNode( elemID ));
2134 for ( ; elemID < toID; ++elemID )
2135 smDS->AddElement( meshDS->FindElement( elemID ));
2137 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2138 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2141 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2142 if ( positions[ nodeID ])
2143 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2144 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2147 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2150 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2151 << me <<".GetMesh()), " << entry.in() << ")";
2153 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2157 //================================================================================
2159 * \brief Return new group contents if it has been changed and update group data
2161 //================================================================================
2163 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2165 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2167 TopoDS_Shape newShape;
2168 SALOMEDS::SObject_wrap groupSO;
2170 if ( how == IS_BREAK_LINK )
2172 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2173 SALOMEDS::SObject_wrap geomRefSO;
2174 if ( !meshSO->_is_nil() &&
2175 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2177 geomRefSO->ReferencedObject( groupSO.inout() );
2183 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2186 if ( groupSO->_is_nil() )
2189 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2190 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2191 if ( geomGroup->_is_nil() )
2194 // get indices of group items
2195 set<int> curIndices;
2196 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2197 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2198 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2199 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2200 curIndices.insert( ids[i] );
2202 bool sameIndices = ( groupData._indices == curIndices );
2203 if ( how == ONLY_IF_CHANGED && sameIndices )
2204 return newShape; // group not changed
2207 CORBA::String_var entry = geomGroup->GetStudyEntry();
2208 groupData._groupEntry = entry.in();
2209 groupData._indices = curIndices;
2211 newShape = _gen_i->GeomObjectToShape( geomGroup );
2213 // check if newShape is up-to-date
2214 if ( !newShape.IsNull() && ids->length() > 0 )
2216 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2219 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2220 for ( ; exp.More() && !toUpdate; exp.Next() )
2222 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2223 toUpdate = ( curIndices.erase( ind ) == 0 );
2225 if ( !curIndices.empty() )
2230 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2231 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2232 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2233 newShape = _gen_i->GeomObjectToShape( geomGroup );
2238 // geom group becomes empty - return empty compound
2239 TopoDS_Compound compound;
2240 BRep_Builder().MakeCompound(compound);
2241 newShape = compound;
2249 //-----------------------------------------------------------------------------
2251 * \brief Storage of shape and index used in CheckGeomGroupModif()
2253 struct TIndexedShape
2256 TopoDS_Shape _shape;
2257 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2259 //-----------------------------------------------------------------------------
2261 * \brief Data to re-create a group on geometry
2263 struct TGroupOnGeomData
2266 TopoDS_Shape _shape;
2267 SMDSAbs_ElementType _type;
2269 Quantity_Color _color;
2271 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2273 _oldID = group->GetID();
2274 _type = group->GetType();
2275 _name = group->GetStoreName();
2276 _color = group->GetColor();
2280 //-----------------------------------------------------------------------------
2282 * \brief Check if a filter is still valid after geometry removal
2284 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2286 if ( theFilter->_is_nil() )
2288 SMESH::Filter::Criteria_var criteria;
2289 theFilter->GetCriteria( criteria.out() );
2291 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2293 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2295 switch ( criteria[ iCr ].Type )
2297 case SMESH::FT_BelongToGeom:
2298 case SMESH::FT_BelongToPlane:
2299 case SMESH::FT_BelongToCylinder:
2300 case SMESH::FT_BelongToGenSurface:
2301 case SMESH::FT_LyingOnGeom:
2302 entry = thresholdID;
2304 case SMESH::FT_ConnectedElements:
2307 entry = thresholdID;
2313 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2314 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2315 if ( so->_is_nil() )
2317 CORBA::Object_var obj = so->GetObject();
2318 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2319 if ( gen->GeomObjectToShape( geom ).IsNull() )
2322 } // loop on criteria
2328 //=============================================================================
2330 * \brief Update data if geometry changes
2334 //=============================================================================
2336 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2338 SMESH::SMESH_Mesh_var me = _this();
2339 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2341 TPythonDump dumpNothing; // prevent any dump
2343 //bool removedFromClient = false;
2345 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2347 //removedFromClient = _impl->HasShapeToMesh();
2349 // try to find geometry by study reference
2350 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2351 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2352 if ( !meshSO->_is_nil() &&
2353 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2354 geomRefSO->ReferencedObject( geomSO.inout() ))
2356 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2357 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2360 if ( mainGO->_is_nil() && // geometry removed ==>
2361 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2363 // convert geom dependent groups into standalone ones
2364 CheckGeomGroupModif();
2366 _impl->ShapeToMesh( TopoDS_Shape() );
2368 // remove sub-meshes
2369 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2370 while ( i_sm != _mapSubMeshIor.end() )
2372 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2374 RemoveSubMesh( sm );
2376 // remove all children except groups in the study
2377 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2378 SALOMEDS::SObject_wrap so;
2379 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2380 if ( meshSO->FindSubObject( tag, so.inout() ))
2381 builder->RemoveObjectWithChildren( so );
2383 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2389 if ( !_impl->HasShapeToMesh() ) return;
2392 // Update after group modification
2394 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2395 if ( !theIsBreakLink )
2396 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2398 int nb = NbNodes() + NbElements();
2399 CheckGeomGroupModif();
2400 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2401 _gen_i->UpdateIcons( me );
2405 // Update after shape modification or breakLink w/o geometry change
2407 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2408 if ( !geomClient ) return;
2409 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2410 if ( geomGen->_is_nil() ) return;
2411 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2412 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2414 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2416 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2417 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2419 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2420 geomClient->RemoveShapeFromBuffer( ior.in() );
2421 newShape = _gen_i->GeomObjectToShape( mainGO );
2424 // Update data taking into account that if topology doesn't change
2425 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2428 _preMeshInfo->ForgetAllData();
2430 if ( geomChanged || !isShaper )
2432 if ( newShape.IsNull() )
2435 _mainShapeTick = mainGO->GetTick();
2437 // store data of groups on geometry including new TopoDS_Shape's
2438 std::vector< TGroupOnGeomData > groupsData;
2439 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2440 groupsData.reserve( groups.size() );
2441 TopTools_DataMapOfShapeShape old2newShapeMap;
2442 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2443 for ( ; g != groups.end(); ++g )
2445 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2447 groupsData.push_back( TGroupOnGeomData( group ));
2450 SMESH::SMESH_GroupOnGeom_var gog;
2451 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2452 if ( i_grp != _mapGroups.end() )
2453 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2455 GEOM::GEOM_Object_var geom;
2456 if ( !gog->_is_nil() )
2458 if ( !theIsBreakLink )
2459 geom = gog->GetShape();
2461 if ( theIsBreakLink || geom->_is_nil() )
2463 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2464 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2465 if ( !grpSO->_is_nil() &&
2466 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2467 geomRefSO->ReferencedObject( geomSO.inout() ))
2469 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2470 geom = GEOM::GEOM_Object::_narrow( geomObj );
2474 if ( old2newShapeMap.IsBound( group->GetShape() ))
2476 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2478 else if ( !geom->_is_nil() )
2480 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2481 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2483 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2484 geomClient->RemoveShapeFromBuffer( ior.in() );
2485 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2487 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2492 // store assigned hypotheses
2493 std::vector< pair< int, THypList > > ids2Hyps;
2494 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2495 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2497 const TopoDS_Shape& s = s2hyps.Key();
2498 const THypList& hyps = s2hyps.ChangeValue();
2499 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2502 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2504 // count shapes excluding compounds corresponding to geom groups
2505 int oldNbSubShapes = meshDS->MaxShapeIndex();
2506 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2508 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2509 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2512 std::set<int> subIds;
2513 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2514 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2515 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2518 // check if shape topology changes - save shape type per shape ID
2519 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2520 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2521 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2523 // change shape to mesh
2524 _impl->ShapeToMesh( TopoDS_Shape() );
2525 _impl->ShapeToMesh( newShape );
2527 // check if shape topology changes - check new shape types
2528 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2529 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2531 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2532 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2535 // re-add shapes (compounds) of geom groups
2536 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2537 TIndices2GroupData ii2grData;
2538 std::vector< int > ii;
2539 std::map< int, int > old2newIDs; // group IDs
2540 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2541 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2543 TGeomGroupData* data = &(*dataIt);
2544 ii.reserve( data->_indices.size() );
2545 ii.assign( data->_indices.begin(), data->_indices.end() );
2546 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2547 if ( ii2gd->second != data )
2549 data->_groupEntry = ii2gd->second->_groupEntry;
2550 data->_indices = ii2gd->second->_indices;
2553 const int oldNbSub = data->_indices.size();
2554 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2556 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2557 if ( ii2i != ii2iMap.end() )
2559 oldID = ii2i->second;
2560 ii2iMap.erase( ii2i );
2562 if ( !oldID && oldNbSub == 1 )
2564 if ( old2newIDs.count( oldID ))
2567 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2568 newShape = newGroupShape( *data, how );
2570 if ( !newShape.IsNull() )
2572 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2574 TopoDS_Compound compound;
2575 BRep_Builder().MakeCompound( compound );
2576 BRep_Builder().Add( compound, newShape );
2577 newShape = compound;
2579 int newID = _impl->GetSubMesh( newShape )->GetId();
2580 if ( oldID /*&& oldID != newID*/ )
2581 old2newIDs.insert( std::make_pair( oldID, newID ));
2582 if ( oldNbSub == 1 )
2583 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2587 // re-assign hypotheses
2588 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2590 int sID = ids2Hyps[i].first;
2593 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2594 if ( o2n != old2newIDs.end() )
2596 else if ( !sameTopology )
2599 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2602 const THypList& hyps = ids2Hyps[i].second;
2603 THypList::const_iterator h = hyps.begin();
2604 for ( ; h != hyps.end(); ++h )
2605 _impl->AddHypothesis( s, (*h)->GetID() );
2609 // restore groups on geometry
2610 for ( size_t i = 0; i < groupsData.size(); ++i )
2612 const TGroupOnGeomData& data = groupsData[i];
2613 if ( data._shape.IsNull() )
2616 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2617 if ( i2g == _mapGroups.end() ) continue;
2619 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2620 if ( !gr_i ) continue;
2622 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2624 _mapGroups.erase( i2g );
2626 g->GetGroupDS()->SetColor( data._color );
2629 if ( !sameTopology )
2631 std::map< int, int >::iterator o2n = old2newIDs.begin();
2632 for ( ; o2n != old2newIDs.end(); ++o2n )
2634 int newID = o2n->second, oldID = o2n->first;
2635 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2639 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2640 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2641 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2643 _mapSubMesh. erase(oldID);
2644 _mapSubMesh_i. erase(oldID);
2645 _mapSubMeshIor.erase(oldID);
2647 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2651 // update _mapSubMesh
2652 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2653 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2654 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2657 if ( !sameTopology )
2659 // remove invalid study sub-objects
2660 CheckGeomGroupModif();
2663 _gen_i->UpdateIcons( me );
2665 if ( !theIsBreakLink && isShaper )
2667 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2668 if ( !meshSO->_is_nil() )
2669 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2673 //=============================================================================
2675 * \brief Update objects depending on changed geom groups
2677 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2678 * issue 0020210: Update of a smesh group after modification of the associated geom group
2680 //=============================================================================
2682 void SMESH_Mesh_i::CheckGeomGroupModif()
2684 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2685 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2686 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2687 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2688 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2690 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2691 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2692 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2694 int nbValid = 0, nbRemoved = 0;
2695 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2696 for ( ; chItr->More(); chItr->Next() )
2698 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2699 if ( !smSO->_is_nil() &&
2700 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2701 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2703 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2704 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2705 if ( !geom->_non_existent() )
2708 continue; // keep the sub-mesh
2711 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2712 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2713 if ( !sm->_is_nil() && !sm->_non_existent() )
2715 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2716 if ( smGeom->_is_nil() )
2718 RemoveSubMesh( sm );
2725 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2726 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2730 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2731 builder->RemoveObjectWithChildren( rootSO );
2735 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2736 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2737 while ( i_gr != _mapGroups.end())
2739 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2741 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2742 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2743 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2744 bool isValidGeom = false;
2745 if ( !onGeom->_is_nil() )
2747 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2748 if ( !isValidGeom ) // check reference
2750 isValidGeom = ( ! groupSO->_is_nil() &&
2751 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2752 refSO->ReferencedObject( geomSO.inout() ) &&
2753 ! geomSO->_is_nil() &&
2754 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2757 else if ( !onFilt->_is_nil() )
2759 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2763 isValidGeom = ( !groupSO->_is_nil() &&
2764 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2768 if ( !IsLoaded() || group->IsEmpty() )
2770 RemoveGroup( group );
2772 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2774 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2776 else // is it possible?
2778 builder->RemoveObjectWithChildren( refSO );
2784 if ( !_impl->HasShapeToMesh() ) return;
2786 CORBA::Long nbEntities = NbNodes() + NbElements();
2788 // Check if group contents changed
2790 typedef map< string, TopoDS_Shape > TEntry2Geom;
2791 TEntry2Geom newGroupContents;
2793 list<TGeomGroupData>::iterator
2794 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2795 for ( ; data != dataEnd; ++data )
2797 pair< TEntry2Geom::iterator, bool > it_new =
2798 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2799 bool processedGroup = !it_new.second;
2800 TopoDS_Shape& newShape = it_new.first->second;
2801 if ( !processedGroup )
2802 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2803 if ( newShape.IsNull() )
2804 continue; // no changes
2807 _preMeshInfo->ForgetOrLoad();
2809 if ( processedGroup ) { // update group indices
2810 list<TGeomGroupData>::iterator data2 = data;
2811 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2812 data->_indices = data2->_indices;
2815 // Update SMESH objects according to new GEOM group contents
2817 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2818 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2820 int oldID = submesh->GetId();
2821 if ( !_mapSubMeshIor.count( oldID ))
2823 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2825 // update hypotheses
2826 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2827 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2828 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2830 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2831 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2833 // care of submeshes
2834 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2835 int newID = newSubmesh->GetId();
2836 if ( newID != oldID ) {
2837 _mapSubMesh [ newID ] = newSubmesh;
2838 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2839 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2840 _mapSubMesh. erase(oldID);
2841 _mapSubMesh_i. erase(oldID);
2842 _mapSubMeshIor.erase(oldID);
2843 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2848 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2849 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2850 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2852 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2854 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2855 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2856 ds->SetShape( newShape );
2861 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2862 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2864 // Remove groups and submeshes basing on removed sub-shapes
2866 TopTools_MapOfShape newShapeMap;
2867 TopoDS_Iterator shapeIt( newShape );
2868 for ( ; shapeIt.More(); shapeIt.Next() )
2869 newShapeMap.Add( shapeIt.Value() );
2871 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2872 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2874 if ( newShapeMap.Contains( shapeIt.Value() ))
2876 TopTools_IndexedMapOfShape oldShapeMap;
2877 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2878 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2880 const TopoDS_Shape& oldShape = oldShapeMap(i);
2881 int oldInd = meshDS->ShapeToIndex( oldShape );
2883 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2884 if ( i_smIor != _mapSubMeshIor.end() ) {
2885 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2888 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2889 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2891 // check if a group bases on oldInd shape
2892 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2893 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2894 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2895 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2897 RemoveGroup( i_grp->second ); // several groups can base on same shape
2898 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2903 // Reassign hypotheses and update groups after setting the new shape to mesh
2905 // collect anassigned hypotheses
2906 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2907 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2908 TShapeHypList assignedHyps;
2909 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2911 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2912 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2913 if ( !hyps.empty() ) {
2914 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2915 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2916 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2919 // collect shapes supporting groups
2920 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2921 TShapeTypeList groupData;
2922 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2923 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2924 for ( ; grIt != groups.end(); ++grIt )
2926 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2928 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2930 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2932 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2933 _impl->ShapeToMesh( newShape );
2935 // reassign hypotheses
2936 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2937 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2939 TIndexedShape& geom = indS_hyps->first;
2940 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2941 int oldID = geom._index;
2942 int newID = meshDS->ShapeToIndex( geom._shape );
2943 if ( oldID == 1 ) { // main shape
2945 geom._shape = newShape;
2949 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2950 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2951 // care of sub-meshes
2952 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2953 if ( newID != oldID ) {
2954 _mapSubMesh [ newID ] = newSubmesh;
2955 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2956 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2957 _mapSubMesh. erase(oldID);
2958 _mapSubMesh_i. erase(oldID);
2959 _mapSubMeshIor.erase(oldID);
2960 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2964 TShapeTypeList::iterator geomType = groupData.begin();
2965 for ( ; geomType != groupData.end(); ++geomType )
2967 const TIndexedShape& geom = geomType->first;
2968 int oldID = geom._index;
2969 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2972 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2973 CORBA::String_var name = groupSO->GetName();
2975 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2976 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2977 /*id=*/-1, geom._shape ))
2978 group_i->changeLocalId( group->GetID() );
2981 break; // everything has been updated
2984 } // loop on group data
2988 CORBA::Long newNbEntities = NbNodes() + NbElements();
2989 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2990 if ( newNbEntities != nbEntities )
2992 // Add all SObjects with icons to soToUpdateIcons
2993 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2995 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2996 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2997 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2999 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3000 i_gr != _mapGroups.end(); ++i_gr ) // groups
3001 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3004 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3005 for ( ; so != soToUpdateIcons.end(); ++so )
3006 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3009 //=============================================================================
3011 * \brief Create standalone group from a group on geometry or filter
3013 //=============================================================================
3015 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3017 SMESH::SMESH_Group_var aGroup;
3022 _preMeshInfo->FullLoadFromFile();
3024 if ( theGroup->_is_nil() )
3025 return aGroup._retn();
3027 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3029 return aGroup._retn();
3031 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3033 const int anId = aGroupToRem->GetLocalID();
3034 if ( !_impl->ConvertToStandalone( anId ) )
3035 return aGroup._retn();
3036 removeGeomGroupData( theGroup );
3038 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3040 // remove old instance of group from own map
3041 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3042 _mapGroups.erase( anId );
3044 SALOMEDS::StudyBuilder_var builder;
3045 SALOMEDS::SObject_wrap aGroupSO;
3046 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3047 if ( !aStudy->_is_nil() ) {
3048 builder = aStudy->NewBuilder();
3049 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3050 if ( !aGroupSO->_is_nil() )
3052 // remove reference to geometry
3053 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3054 for ( ; chItr->More(); chItr->Next() )
3056 // Remove group's child SObject
3057 SALOMEDS::SObject_wrap so = chItr->Value();
3058 builder->RemoveObject( so );
3060 // Update Python script
3061 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3062 << ".ConvertToStandalone( " << aGroupSO << " )";
3064 // change icon of Group on Filter
3067 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3068 // const int isEmpty = ( elemTypes->length() == 0 );
3071 SALOMEDS::GenericAttribute_wrap anAttr =
3072 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3073 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3074 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3080 // remember new group in own map
3081 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3082 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3084 // register CORBA object for persistence
3085 _gen_i->RegisterObject( aGroup );
3087 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3088 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3089 //aGroup->Register();
3090 aGroupToRem->UnRegister();
3092 SMESH_CATCH( SMESH::throwCorbaException );
3094 return aGroup._retn();
3097 //================================================================================
3099 * \brief Create a sub-mesh on a given sub-shape
3101 //================================================================================
3103 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3105 if(MYDEBUG) MESSAGE( "createSubMesh" );
3106 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3107 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3110 SMESH_subMesh_i * subMeshServant;
3113 subMeshId = mySubMesh->GetId();
3114 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3116 else // "invalid sub-mesh"
3118 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3119 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3120 if ( _mapSubMesh.empty() )
3123 subMeshId = _mapSubMesh.begin()->first - 1;
3124 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3127 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3129 _mapSubMesh [subMeshId] = mySubMesh;
3130 _mapSubMesh_i [subMeshId] = subMeshServant;
3131 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3133 subMeshServant->Register();
3135 // register CORBA object for persistence
3136 int nextId = _gen_i->RegisterObject( subMesh );
3137 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3138 else { nextId = 0; } // avoid "unused variable" warning
3140 // to track changes of GEOM groups
3141 if ( subMeshId > 0 )
3142 addGeomGroupData( theSubShapeObject, subMesh );
3144 return subMesh._retn();
3147 //================================================================================
3149 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3151 //================================================================================
3153 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3155 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3156 if ( it == _mapSubMeshIor.end() )
3157 return SMESH::SMESH_subMesh::_nil();
3159 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3162 //================================================================================
3164 * \brief Remove a sub-mesh based on the given sub-shape
3166 //================================================================================
3168 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3169 GEOM::GEOM_Object_ptr theSubShapeObject )
3171 bool isHypChanged = false;
3172 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3173 return isHypChanged;
3175 const int subMeshId = theSubMesh->GetId();
3177 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3180 if (( _mapSubMesh.count( subMeshId )) &&
3181 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3183 TopoDS_Shape S = sm->GetSubShape();
3186 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3187 isHypChanged = !hyps.empty();
3188 if ( isHypChanged && _preMeshInfo )
3189 _preMeshInfo->ForgetOrLoad();
3190 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3191 for ( ; hyp != hyps.end(); ++hyp )
3192 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3199 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3200 isHypChanged = ( aHypList->length() > 0 );
3201 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3202 removeHypothesis( theSubShapeObject, aHypList[i] );
3205 catch( const SALOME::SALOME_Exception& ) {
3206 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3208 removeGeomGroupData( theSubShapeObject );
3212 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3213 if ( id_smi != _mapSubMesh_i.end() )
3214 id_smi->second->UnRegister();
3216 // remove a CORBA object
3217 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3218 if ( id_smptr != _mapSubMeshIor.end() )
3219 SMESH::SMESH_subMesh_var( id_smptr->second );
3221 _mapSubMesh.erase(subMeshId);
3222 _mapSubMesh_i.erase(subMeshId);
3223 _mapSubMeshIor.erase(subMeshId);
3225 return isHypChanged;
3228 //================================================================================
3230 * \brief Create a group. Group type depends on given arguments
3232 //================================================================================
3234 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3235 const char* theName,
3237 const TopoDS_Shape& theShape,
3238 const SMESH_PredicatePtr& thePredicate )
3240 std::string newName;
3241 if ( !theName || !theName[0] )
3243 std::set< std::string > presentNames;
3244 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3245 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3247 CORBA::String_var name = i_gr->second->GetName();
3248 presentNames.insert( name.in() );
3251 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3252 } while ( !presentNames.insert( newName ).second );
3253 theName = newName.c_str();
3255 SMESH::SMESH_GroupBase_var aGroup;
3256 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3257 theID, theShape, thePredicate ))
3259 int anId = g->GetID();
3260 SMESH_GroupBase_i* aGroupImpl;
3261 if ( !theShape.IsNull() )
3262 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3263 else if ( thePredicate )
3264 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3266 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3268 aGroup = aGroupImpl->_this();
3269 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3270 aGroupImpl->Register();
3272 // register CORBA object for persistence
3273 int nextId = _gen_i->RegisterObject( aGroup );
3274 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3275 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3277 // to track changes of GEOM groups
3278 if ( !theShape.IsNull() ) {
3279 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3280 addGeomGroupData( geom, aGroup );
3283 return aGroup._retn();
3286 //=============================================================================
3288 * SMESH_Mesh_i::removeGroup
3290 * Should be called by ~SMESH_Group_i()
3292 //=============================================================================
3294 void SMESH_Mesh_i::removeGroup( const int theId )
3296 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3297 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3298 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3299 _mapGroups.erase( theId );
3300 removeGeomGroupData( group );
3301 if ( !_impl->RemoveGroup( theId ))
3303 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3304 RemoveGroup( group );
3306 group->UnRegister();
3310 //================================================================================
3312 * \brief Return a log that can be used to move another mesh to the same state as this one
3314 //================================================================================
3316 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3318 SMESH::log_array_var aLog;
3322 _preMeshInfo->FullLoadFromFile();
3324 list < SMESHDS_Command * >logDS = _impl->GetLog();
3325 aLog = new SMESH::log_array;
3327 int lg = logDS.size();
3329 list < SMESHDS_Command * >::iterator its = logDS.begin();
3330 while(its != logDS.end()){
3331 SMESHDS_Command *com = *its;
3332 int comType = com->GetType();
3333 int lgcom = com->GetNumber();
3334 const list < int >&intList = com->GetIndexes();
3335 int inum = intList.size();
3336 list < int >::const_iterator ii = intList.begin();
3337 const list < double >&coordList = com->GetCoords();
3338 int rnum = coordList.size();
3339 list < double >::const_iterator ir = coordList.begin();
3340 aLog[indexLog].commandType = comType;
3341 aLog[indexLog].number = lgcom;
3342 aLog[indexLog].coords.length(rnum);
3343 aLog[indexLog].indexes.length(inum);
3344 for(int i = 0; i < rnum; i++){
3345 aLog[indexLog].coords[i] = *ir;
3348 for(int i = 0; i < inum; i++){
3349 aLog[indexLog].indexes[i] = *ii;
3358 SMESH_CATCH( SMESH::throwCorbaException );
3360 return aLog._retn();
3363 //================================================================================
3365 * \brief Remove the log of commands
3367 //================================================================================
3369 void SMESH_Mesh_i::ClearLog()
3373 SMESH_CATCH( SMESH::throwCorbaException );
3376 //================================================================================
3378 * \brief Return a mesh ID
3380 //================================================================================
3382 CORBA::Long SMESH_Mesh_i::GetId()
3387 //=============================================================================
3390 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3391 // issue 0020918: groups removal is caused by hyp modification
3392 // issue 0021208: to forget not loaded mesh data at hyp modification
3393 struct TCallUp_i : public SMESH_Mesh::TCallUp
3395 SMESH_Mesh_i* _mesh;
3396 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3397 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3398 virtual void HypothesisModified( int hypID,
3399 bool updIcons) { _mesh->onHypothesisModified( hypID,
3401 virtual void Load () { _mesh->Load(); }
3402 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3406 //================================================================================
3408 * \brief callback from _impl to
3409 * 1) forget not loaded mesh data (issue 0021208)
3410 * 2) mark hypothesis as valid
3412 //================================================================================
3414 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3417 _preMeshInfo->ForgetOrLoad();
3419 if ( theUpdateIcons )
3421 SMESH::SMESH_Mesh_var mesh = _this();
3422 _gen_i->UpdateIcons( mesh );
3425 if ( _nbInvalidHypos != 0 )
3427 // mark a hypothesis as valid after edition
3429 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3430 SALOMEDS::SObject_wrap hypRoot;
3431 if ( !smeshComp->_is_nil() &&
3432 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3434 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3435 for ( ; anIter->More(); anIter->Next() )
3437 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3438 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3439 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3440 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3441 _gen_i->HighLightInvalid( hyp, false );
3443 nbInvalid += _gen_i->IsInvalid( hypSO );
3446 _nbInvalidHypos = nbInvalid;
3450 //================================================================================
3452 * \brief Set mesh implementation
3454 //================================================================================
3456 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3458 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3461 _impl->SetCallUp( new TCallUp_i(this));
3464 //=============================================================================
3466 * Return a mesh implementation
3468 //=============================================================================
3470 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3472 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3476 //=============================================================================
3478 * Return mesh editor
3480 //=============================================================================
3482 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3484 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3488 _preMeshInfo->FullLoadFromFile();
3490 // Create MeshEditor
3492 _editor = new SMESH_MeshEditor_i( this, false );
3493 aMeshEdVar = _editor->_this();
3495 // Update Python script
3496 TPythonDump() << _editor << " = "
3497 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3499 SMESH_CATCH( SMESH::throwCorbaException );
3501 return aMeshEdVar._retn();
3504 //=============================================================================
3506 * Return mesh edition previewer
3508 //=============================================================================
3510 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3512 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3516 _preMeshInfo->FullLoadFromFile();
3518 if ( !_previewEditor )
3519 _previewEditor = new SMESH_MeshEditor_i( this, true );
3520 aMeshEdVar = _previewEditor->_this();
3522 SMESH_CATCH( SMESH::throwCorbaException );
3524 return aMeshEdVar._retn();
3527 //================================================================================
3529 * \brief Return true if the mesh has been edited since a last total re-compute
3530 * and those modifications may prevent successful partial re-compute
3532 //================================================================================
3534 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard()
3536 Unexpect aCatch(SALOME_SalomeException);
3537 return _impl->HasModificationsToDiscard();
3540 //================================================================================
3542 * \brief Return a random unique color
3544 //================================================================================
3546 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3548 const int MAX_ATTEMPTS = 100;
3550 double tolerance = 0.5;
3551 SALOMEDS::Color col;
3555 // generate random color
3556 double red = (double)rand() / RAND_MAX;
3557 double green = (double)rand() / RAND_MAX;
3558 double blue = (double)rand() / RAND_MAX;
3559 // check existence in the list of the existing colors
3560 bool matched = false;
3561 std::list<SALOMEDS::Color>::const_iterator it;
3562 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3563 SALOMEDS::Color color = *it;
3564 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3565 matched = tol < tolerance;
3567 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3568 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3576 //=============================================================================
3578 * Set auto-color mode. If it is on, groups get unique random colors
3580 //=============================================================================
3582 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor)
3584 Unexpect aCatch(SALOME_SalomeException);
3585 _impl->SetAutoColor(theAutoColor);
3587 TPythonDump pyDump; // not to dump group->SetColor() from below code
3588 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3590 std::list<SALOMEDS::Color> aReservedColors;
3591 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3592 for ( ; it != _mapGroups.end(); it++ ) {
3593 if ( CORBA::is_nil( it->second )) continue;
3594 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3595 it->second->SetColor( aColor );
3596 aReservedColors.push_back( aColor );
3600 //=============================================================================
3602 * Return true if auto-color mode is on
3604 //=============================================================================
3606 CORBA::Boolean SMESH_Mesh_i::GetAutoColor()
3608 Unexpect aCatch(SALOME_SalomeException);
3609 return _impl->GetAutoColor();
3612 //=============================================================================
3614 * Check if there are groups with equal names
3616 //=============================================================================
3618 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3620 return _impl->HasDuplicatedGroupNamesMED();
3623 //================================================================================
3625 * \brief Care of a file before exporting mesh into it
3627 //================================================================================
3629 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3631 SMESH_File aFile( file, false );
3633 if ( aFile.exists() ) {
3634 // existing filesystem node
3635 if ( !aFile.isDirectory() ) {
3636 if ( aFile.openForWriting() ) {
3637 if ( overwrite && ! aFile.remove()) {
3638 msg << "Can't replace " << aFile.getName();
3641 msg << "Can't write into " << aFile.getName();
3644 msg << "Location " << aFile.getName() << " is not a file";
3648 // nonexisting file; check if it can be created
3649 if ( !aFile.openForWriting() ) {
3650 msg << "You cannot create the file "
3652 << ". Check the directory existence and access rights";
3660 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3664 //================================================================================
3666 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3667 * \param file - file name
3668 * \param overwrite - to erase the file or not
3669 * \retval string - mesh name
3671 //================================================================================
3673 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3674 CORBA::Boolean overwrite)
3677 PrepareForWriting(file, overwrite);
3678 string aMeshName = "Mesh";
3679 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3680 if ( !aStudy->_is_nil() ) {
3681 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3682 if ( !aMeshSO->_is_nil() ) {
3683 CORBA::String_var name = aMeshSO->GetName();
3685 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3686 if ( !aStudy->GetProperties()->IsLocked() )
3688 SALOMEDS::GenericAttribute_wrap anAttr;
3689 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3690 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3691 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3692 ASSERT(!aFileName->_is_nil());
3693 aFileName->SetValue(file);
3694 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3695 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3696 ASSERT(!aFileType->_is_nil());
3697 aFileType->SetValue("FICHIERMED");
3701 // Update Python script
3702 // set name of mesh before export
3703 TPythonDump() << _gen_i << ".SetName("
3704 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3706 // check names of groups
3712 //================================================================================
3714 * \brief Export to MED file
3716 //================================================================================
3718 void SMESH_Mesh_i::ExportMED(const char* file,
3719 CORBA::Boolean auto_groups,
3720 CORBA::Long version,
3721 CORBA::Boolean overwrite,
3722 CORBA::Boolean autoDimension)
3724 //MESSAGE("MED minor version: "<< minor);
3727 _preMeshInfo->FullLoadFromFile();
3729 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3730 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3732 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3734 << "auto_groups=" <<auto_groups << ", "
3735 << "minor=" << version << ", "
3736 << "overwrite=" << overwrite << ", "
3737 << "meshPart=None, "
3738 << "autoDimension=" << autoDimension << " )";
3740 SMESH_CATCH( SMESH::throwCorbaException );
3743 //================================================================================
3745 * \brief Export a mesh to a SAUV file
3747 //================================================================================
3749 void SMESH_Mesh_i::ExportSAUV (const char* file,
3750 CORBA::Boolean auto_groups)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 _preMeshInfo->FullLoadFromFile();
3756 string aMeshName = prepareMeshNameAndGroups(file, true);
3757 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3758 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3759 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3763 //================================================================================
3765 * \brief Export a mesh to a DAT file
3767 //================================================================================
3769 void SMESH_Mesh_i::ExportDAT (const char *file)
3771 Unexpect aCatch(SALOME_SalomeException);
3773 _preMeshInfo->FullLoadFromFile();
3775 // Update Python script
3776 // check names of groups
3778 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3781 PrepareForWriting(file);
3782 _impl->ExportDAT(file);
3785 //================================================================================
3787 * \brief Export a mesh to an UNV file
3789 //================================================================================
3791 void SMESH_Mesh_i::ExportUNV (const char *file)
3793 Unexpect aCatch(SALOME_SalomeException);
3795 _preMeshInfo->FullLoadFromFile();
3797 // Update Python script
3798 // check names of groups
3800 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3803 PrepareForWriting(file);
3804 _impl->ExportUNV(file);
3807 //================================================================================
3809 * \brief Export a mesh to an STL file
3811 //================================================================================
3813 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3815 Unexpect aCatch(SALOME_SalomeException);
3817 _preMeshInfo->FullLoadFromFile();
3819 // Update Python script
3820 // check names of groups
3822 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3823 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3825 CORBA::String_var name;
3826 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3827 if ( !so->_is_nil() )
3828 name = so->GetName();
3831 PrepareForWriting( file );
3832 _impl->ExportSTL( file, isascii, name.in() );
3835 //================================================================================
3837 * \brief Export a part of mesh to a med file
3839 //================================================================================
3841 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3843 CORBA::Boolean auto_groups,
3844 CORBA::Long version,
3845 CORBA::Boolean overwrite,
3846 CORBA::Boolean autoDimension,
3847 const GEOM::ListOfFields& fields,
3848 const char* geomAssocFields,
3849 CORBA::Double ZTolerance)
3851 MESSAGE("MED version: "<< version);
3854 _preMeshInfo->FullLoadFromFile();
3857 bool have0dField = false;
3858 if ( fields.length() > 0 )
3860 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3861 if ( shapeToMesh->_is_nil() )
3862 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3864 for ( size_t i = 0; i < fields.length(); ++i )
3866 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3867 THROW_SALOME_CORBA_EXCEPTION
3868 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3869 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3870 if ( fieldShape->_is_nil() )
3871 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3872 if ( !fieldShape->IsSame( shapeToMesh ) )
3873 THROW_SALOME_CORBA_EXCEPTION
3874 ( "Field defined not on shape", SALOME::BAD_PARAM);
3875 if ( fields[i]->GetDimension() == 0 )
3878 if ( geomAssocFields )
3879 for ( int i = 0; geomAssocFields[i]; ++i )
3880 switch ( geomAssocFields[i] ) {
3881 case 'v':case 'e':case 'f':case 's': break;
3882 case 'V':case 'E':case 'F':case 'S': break;
3883 default: THROW_SALOME_CORBA_EXCEPTION
3884 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3888 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3892 string aMeshName = "Mesh";
3893 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3894 if ( CORBA::is_nil( meshPart ) ||
3895 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3897 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3898 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3899 0, autoDimension, /*addODOnVertices=*/have0dField,
3901 meshDS = _impl->GetMeshDS();
3906 _preMeshInfo->FullLoadFromFile();
3908 PrepareForWriting(file, overwrite);
3910 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3911 if ( !SO->_is_nil() ) {
3912 CORBA::String_var name = SO->GetName();
3916 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3917 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3918 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3919 meshDS = tmpDSDeleter._obj = partDS;
3924 if ( _impl->HasShapeToMesh() )
3926 DriverMED_W_Field fieldWriter;
3927 fieldWriter.SetFile( file );
3928 fieldWriter.SetMeshName( aMeshName );
3929 fieldWriter.AddODOnVertices( have0dField );
3931 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3935 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3936 goList->length( fields.length() );
3937 for ( size_t i = 0; i < fields.length(); ++i )
3939 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3942 TPythonDump() << _this() << ".ExportPartToMED( "
3943 << meshPart << ", r'"
3945 << auto_groups << ", "
3947 << overwrite << ", "
3948 << autoDimension << ", "
3950 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3951 << TVar( ZTolerance )
3954 SMESH_CATCH( SMESH::throwCorbaException );
3957 //================================================================================
3959 * Write GEOM fields to MED file
3961 //================================================================================
3963 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3964 SMESHDS_Mesh* meshDS,
3965 const GEOM::ListOfFields& fields,
3966 const char* geomAssocFields)
3968 #define METH "SMESH_Mesh_i::exportMEDFields() "
3970 if (( fields.length() < 1 ) &&
3971 ( !geomAssocFields || !geomAssocFields[0] ))
3974 std::vector< std::vector< double > > dblVals;
3975 std::vector< std::vector< int > > intVals;
3976 std::vector< int > subIdsByDim[ 4 ];
3977 const double noneDblValue = 0.;
3978 const double noneIntValue = 0;
3980 for ( size_t iF = 0; iF < fields.length(); ++iF )
3984 int dim = fields[ iF ]->GetDimension();
3985 SMDSAbs_ElementType elemType;
3986 TopAbs_ShapeEnum shapeType;
3988 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3989 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3990 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3991 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3993 continue; // skip fields on whole shape
3995 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3996 if ( dataType == GEOM::FDT_String )
3998 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3999 if ( stepIDs->length() < 1 )
4001 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4002 if ( comps->length() < 1 )
4004 CORBA::String_var name = fields[ iF ]->GetName();
4006 if ( !fieldWriter.Set( meshDS,
4010 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4013 for ( size_t iC = 0; iC < comps->length(); ++iC )
4014 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4016 dblVals.resize( comps->length() );
4017 intVals.resize( comps->length() );
4019 // find sub-shape IDs
4021 std::vector< int >& subIds = subIdsByDim[ dim ];
4022 if ( subIds.empty() )
4023 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4024 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4025 subIds.push_back( id );
4029 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4033 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4035 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4036 if ( step->_is_nil() )
4039 CORBA::Long stamp = step->GetStamp();
4040 CORBA::Long id = step->GetID();
4041 fieldWriter.SetDtIt( int( stamp ), int( id ));
4043 // fill dblVals or intVals
4044 for ( size_t iC = 0; iC < comps->length(); ++iC )
4045 if ( dataType == GEOM::FDT_Double )
4047 dblVals[ iC ].clear();
4048 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4052 intVals[ iC ].clear();
4053 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4057 case GEOM::FDT_Double:
4059 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4060 if ( dblStep->_is_nil() ) continue;
4061 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4062 if ( vv->length() != subIds.size() * comps->length() )
4063 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4064 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4065 for ( size_t iC = 0; iC < comps->length(); ++iC )
4066 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4071 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4072 if ( intStep->_is_nil() ) continue;
4073 GEOM::ListOfLong_var vv = intStep->GetValues();
4074 if ( vv->length() != subIds.size() * comps->length() )
4075 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4076 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4077 for ( size_t iC = 0; iC < comps->length(); ++iC )
4078 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4081 case GEOM::FDT_Bool:
4083 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4084 if ( boolStep->_is_nil() ) continue;
4085 GEOM::short_array_var vv = boolStep->GetValues();
4086 if ( vv->length() != subIds.size() * comps->length() )
4087 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4088 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4089 for ( size_t iC = 0; iC < comps->length(); ++iC )
4090 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4096 // pass values to fieldWriter
4097 elemIt = fieldWriter.GetOrderedElems();
4098 if ( dataType == GEOM::FDT_Double )
4099 while ( elemIt->more() )
4101 const SMDS_MeshElement* e = elemIt->next();
4102 const int shapeID = e->getshapeId();
4103 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4104 for ( size_t iC = 0; iC < comps->length(); ++iC )
4105 fieldWriter.AddValue( noneDblValue );
4107 for ( size_t iC = 0; iC < comps->length(); ++iC )
4108 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4111 while ( elemIt->more() )
4113 const SMDS_MeshElement* e = elemIt->next();
4114 const int shapeID = e->getshapeId();
4115 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4116 for ( size_t iC = 0; iC < comps->length(); ++iC )
4117 fieldWriter.AddValue( (double) noneIntValue );
4119 for ( size_t iC = 0; iC < comps->length(); ++iC )
4120 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4124 fieldWriter.Perform();
4125 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4126 if ( res && res->IsKO() )
4128 if ( res->myComment.empty() )
4129 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4131 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4137 if ( !geomAssocFields || !geomAssocFields[0] )
4140 // write geomAssocFields
4142 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4143 shapeDim[ TopAbs_COMPOUND ] = 3;
4144 shapeDim[ TopAbs_COMPSOLID ] = 3;
4145 shapeDim[ TopAbs_SOLID ] = 3;
4146 shapeDim[ TopAbs_SHELL ] = 2;
4147 shapeDim[ TopAbs_FACE ] = 2;
4148 shapeDim[ TopAbs_WIRE ] = 1;
4149 shapeDim[ TopAbs_EDGE ] = 1;
4150 shapeDim[ TopAbs_VERTEX ] = 0;
4151 shapeDim[ TopAbs_SHAPE ] = 3;
4153 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4155 std::vector< std::string > compNames;
4156 switch ( geomAssocFields[ iF ]) {
4158 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4159 compNames.push_back( "dim" );
4162 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4165 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4168 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4172 compNames.push_back( "id" );
4173 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4174 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4176 fieldWriter.SetDtIt( -1, -1 );
4178 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4182 if ( compNames.size() == 2 ) // _vertices_
4183 while ( elemIt->more() )
4185 const SMDS_MeshElement* e = elemIt->next();
4186 const int shapeID = e->getshapeId();
4189 fieldWriter.AddValue( (double) -1 );
4190 fieldWriter.AddValue( (double) -1 );
4194 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4195 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4196 fieldWriter.AddValue( (double) shapeID );
4200 while ( elemIt->more() )
4202 const SMDS_MeshElement* e = elemIt->next();
4203 const int shapeID = e->getshapeId();
4205 fieldWriter.AddValue( (double) -1 );
4207 fieldWriter.AddValue( (double) shapeID );
4211 fieldWriter.Perform();
4212 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4213 if ( res && res->IsKO() )
4215 if ( res->myComment.empty() )
4216 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4218 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4221 } // loop on geomAssocFields
4226 //================================================================================
4228 * \brief Export a part of mesh to a DAT file
4230 //================================================================================
4232 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4235 Unexpect aCatch(SALOME_SalomeException);
4237 _preMeshInfo->FullLoadFromFile();
4239 PrepareForWriting(file);
4241 SMESH_MeshPartDS partDS( meshPart );
4242 _impl->ExportDAT(file,&partDS);
4244 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4245 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4247 //================================================================================
4249 * \brief Export a part of mesh to an UNV file
4251 //================================================================================
4253 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4256 Unexpect aCatch(SALOME_SalomeException);
4258 _preMeshInfo->FullLoadFromFile();
4260 PrepareForWriting(file);
4262 SMESH_MeshPartDS partDS( meshPart );
4263 _impl->ExportUNV(file, &partDS);
4265 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4266 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4268 //================================================================================
4270 * \brief Export a part of mesh to an STL file
4272 //================================================================================
4274 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4276 ::CORBA::Boolean isascii)
4278 Unexpect aCatch(SALOME_SalomeException);
4280 _preMeshInfo->FullLoadFromFile();
4282 PrepareForWriting(file);
4284 CORBA::String_var name;
4285 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4286 if ( !so->_is_nil() )
4287 name = so->GetName();
4289 SMESH_MeshPartDS partDS( meshPart );
4290 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4292 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4293 << meshPart<< ", r'" << file << "', " << isascii << ")";
4296 //================================================================================
4298 * \brief Export a part of mesh to an STL file
4300 //================================================================================
4302 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4304 CORBA::Boolean overwrite,
4305 CORBA::Boolean groupElemsByType)
4308 Unexpect aCatch(SALOME_SalomeException);
4310 _preMeshInfo->FullLoadFromFile();
4312 PrepareForWriting(file,overwrite);
4314 std::string meshName("");
4315 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4316 if ( !so->_is_nil() )
4318 CORBA::String_var name = so->GetName();
4319 meshName = name.in();
4323 SMESH_MeshPartDS partDS( meshPart );
4324 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4326 SMESH_CATCH( SMESH::throwCorbaException );
4328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4329 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4331 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4335 //================================================================================
4337 * \brief Export a part of mesh to a GMF file
4339 //================================================================================
4341 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4343 bool withRequiredGroups)
4345 Unexpect aCatch(SALOME_SalomeException);
4347 _preMeshInfo->FullLoadFromFile();
4349 PrepareForWriting(file,/*overwrite=*/true);
4351 SMESH_MeshPartDS partDS( meshPart );
4352 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4354 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4355 << meshPart<< ", r'"
4357 << withRequiredGroups << ")";
4360 //=============================================================================
4362 * Return computation progress [0.,1]
4364 //=============================================================================
4366 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4370 return _impl->GetComputeProgress();
4372 SMESH_CATCH( SMESH::doNothing );
4376 //================================================================================
4378 * \brief Return nb of nodes
4380 //================================================================================
4382 CORBA::Long SMESH_Mesh_i::NbNodes()
4384 Unexpect aCatch(SALOME_SalomeException);
4386 return _preMeshInfo->NbNodes();
4388 return _impl->NbNodes();
4391 //================================================================================
4393 * \brief Return nb of elements
4395 //================================================================================
4397 CORBA::Long SMESH_Mesh_i::NbElements()
4399 Unexpect aCatch(SALOME_SalomeException);
4401 return _preMeshInfo->NbElements();
4403 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4406 //================================================================================
4408 * \brief Return nb of 0D elements
4410 //================================================================================
4412 CORBA::Long SMESH_Mesh_i::Nb0DElements()
4414 Unexpect aCatch(SALOME_SalomeException);
4416 return _preMeshInfo->Nb0DElements();
4418 return _impl->Nb0DElements();
4421 //================================================================================
4423 * \brief Return nb of BALL elements
4425 //================================================================================
4427 CORBA::Long SMESH_Mesh_i::NbBalls()
4429 Unexpect aCatch(SALOME_SalomeException);
4431 return _preMeshInfo->NbBalls();
4433 return _impl->NbBalls();
4436 //================================================================================
4438 * \brief Return nb of 1D elements
4440 //================================================================================
4442 CORBA::Long SMESH_Mesh_i::NbEdges()
4444 Unexpect aCatch(SALOME_SalomeException);
4446 return _preMeshInfo->NbEdges();
4448 return _impl->NbEdges();
4451 //================================================================================
4453 * \brief Return nb of edges
4455 //================================================================================
4457 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4459 Unexpect aCatch(SALOME_SalomeException);
4461 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4463 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4466 //================================================================================
4468 * \brief Return nb of faces
4470 //================================================================================
4472 CORBA::Long SMESH_Mesh_i::NbFaces()
4474 Unexpect aCatch(SALOME_SalomeException);
4476 return _preMeshInfo->NbFaces();
4478 return _impl->NbFaces();
4481 //================================================================================
4483 * \brief Return nb of tringles
4485 //================================================================================
4487 CORBA::Long SMESH_Mesh_i::NbTriangles()
4489 Unexpect aCatch(SALOME_SalomeException);
4491 return _preMeshInfo->NbTriangles();
4493 return _impl->NbTriangles();
4496 //================================================================================
4498 * \brief Return nb of bi-quadratic triangles
4500 //================================================================================
4502 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()
4504 Unexpect aCatch(SALOME_SalomeException);
4506 return _preMeshInfo->NbBiQuadTriangles();
4508 return _impl->NbBiQuadTriangles();
4511 CORBA::Long SMESH_Mesh_i::NbQuadrangles()
4513 Unexpect aCatch(SALOME_SalomeException);
4515 return _preMeshInfo->NbQuadrangles();
4517 return _impl->NbQuadrangles();
4520 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()
4522 Unexpect aCatch(SALOME_SalomeException);
4524 return _preMeshInfo->NbBiQuadQuadrangles();
4526 return _impl->NbBiQuadQuadrangles();
4529 CORBA::Long SMESH_Mesh_i::NbPolygons()
4531 Unexpect aCatch(SALOME_SalomeException);
4533 return _preMeshInfo->NbPolygons();
4535 return _impl->NbPolygons();
4538 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order)
4540 Unexpect aCatch(SALOME_SalomeException);
4542 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4544 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4547 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4549 Unexpect aCatch(SALOME_SalomeException);
4551 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4553 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4556 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4558 Unexpect aCatch(SALOME_SalomeException);
4560 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4562 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4565 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4567 Unexpect aCatch(SALOME_SalomeException);
4569 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4571 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4574 //=============================================================================
4576 CORBA::Long SMESH_Mesh_i::NbVolumes()
4578 Unexpect aCatch(SALOME_SalomeException);
4580 return _preMeshInfo->NbVolumes();
4582 return _impl->NbVolumes();
4585 CORBA::Long SMESH_Mesh_i::NbTetras()
4587 Unexpect aCatch(SALOME_SalomeException);
4589 return _preMeshInfo->NbTetras();
4591 return _impl->NbTetras();
4594 CORBA::Long SMESH_Mesh_i::NbHexas()
4596 Unexpect aCatch(SALOME_SalomeException);
4598 return _preMeshInfo->NbHexas();
4600 return _impl->NbHexas();
4603 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()
4605 Unexpect aCatch(SALOME_SalomeException);
4607 return _preMeshInfo->NbTriQuadHexas();
4609 return _impl->NbTriQuadraticHexas();
4612 CORBA::Long SMESH_Mesh_i::NbPyramids()
4614 Unexpect aCatch(SALOME_SalomeException);
4616 return _preMeshInfo->NbPyramids();
4618 return _impl->NbPyramids();
4621 CORBA::Long SMESH_Mesh_i::NbPrisms()
4623 Unexpect aCatch(SALOME_SalomeException);
4625 return _preMeshInfo->NbPrisms();
4627 return _impl->NbPrisms();
4630 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()
4632 Unexpect aCatch(SALOME_SalomeException);
4634 return _preMeshInfo->NbHexPrisms();
4636 return _impl->NbHexagonalPrisms();
4639 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()
4641 Unexpect aCatch(SALOME_SalomeException);
4643 return _preMeshInfo->NbPolyhedrons();
4645 return _impl->NbPolyhedrons();
4648 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4650 Unexpect aCatch(SALOME_SalomeException);
4652 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4654 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4657 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4659 Unexpect aCatch(SALOME_SalomeException);
4661 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4663 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4666 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4668 Unexpect aCatch(SALOME_SalomeException);
4670 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4672 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4675 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4677 Unexpect aCatch(SALOME_SalomeException);
4679 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4681 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4684 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4686 Unexpect aCatch(SALOME_SalomeException);
4688 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4690 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4693 //=============================================================================
4695 * Return nb of published sub-meshes
4697 //=============================================================================
4699 CORBA::Long SMESH_Mesh_i::NbSubMesh()
4701 Unexpect aCatch(SALOME_SalomeException);
4702 return _mapSubMesh_i.size();
4705 //=============================================================================
4707 * Dumps mesh into a string
4709 //=============================================================================
4711 char* SMESH_Mesh_i::Dump()
4715 return CORBA::string_dup( os.str().c_str() );
4718 //=============================================================================
4720 * Method of SMESH_IDSource interface
4722 //=============================================================================
4724 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4726 return GetElementsId();
4729 //=============================================================================
4731 * Return ids of all elements
4733 //=============================================================================
4735 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4737 Unexpect aCatch(SALOME_SalomeException);
4739 _preMeshInfo->FullLoadFromFile();
4741 SMESH::long_array_var aResult = new SMESH::long_array();
4742 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4744 if ( aSMESHDS_Mesh == NULL )
4745 return aResult._retn();
4747 long nbElements = NbElements();
4748 aResult->length( nbElements );
4749 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4750 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4751 aResult[i] = anIt->next()->GetID();
4753 return aResult._retn();
4757 //=============================================================================
4759 * Return ids of all elements of given type
4761 //=============================================================================
4763 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4765 Unexpect aCatch(SALOME_SalomeException);
4767 _preMeshInfo->FullLoadFromFile();
4769 SMESH::long_array_var aResult = new SMESH::long_array();
4770 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4772 if ( aSMESHDS_Mesh == NULL )
4773 return aResult._retn();
4775 long nbElements = NbElements();
4777 // No sense in returning ids of elements along with ids of nodes:
4778 // when theElemType == SMESH::ALL, return node ids only if
4779 // there are no elements
4780 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4781 return GetNodesId();
4783 aResult->length( nbElements );
4787 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4788 while ( i < nbElements && anIt->more() )
4789 aResult[i++] = anIt->next()->GetID();
4791 aResult->length( i );
4793 return aResult._retn();
4796 //=============================================================================
4798 * Return ids of all nodes
4800 //=============================================================================
4802 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4804 Unexpect aCatch(SALOME_SalomeException);
4806 _preMeshInfo->FullLoadFromFile();
4808 SMESH::long_array_var aResult = new SMESH::long_array();
4809 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4811 if ( aMeshDS == NULL )
4812 return aResult._retn();
4814 long nbNodes = NbNodes();
4815 aResult->length( nbNodes );
4816 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4817 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4818 aResult[i] = anIt->next()->GetID();
4820 return aResult._retn();
4823 //=============================================================================
4825 * Return type of the given element
4827 //=============================================================================
4829 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4831 SMESH::ElementType type = SMESH::ALL;
4835 _preMeshInfo->FullLoadFromFile();
4837 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4839 SMESH_CATCH( SMESH::throwCorbaException );
4844 //=============================================================================
4846 * Return geometric type of the given element
4848 //=============================================================================
4850 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4853 _preMeshInfo->FullLoadFromFile();
4855 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4857 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4859 return ( SMESH::EntityType ) e->GetEntityType();
4862 //=============================================================================
4864 * Return type of the given element
4866 //=============================================================================
4868 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4871 _preMeshInfo->FullLoadFromFile();
4873 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4875 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4877 return ( SMESH::GeometryType ) e->GetGeomType();
4880 //=============================================================================
4882 * Return ID of elements for given submesh
4884 //=============================================================================
4886 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4888 SMESH::long_array_var aResult = new SMESH::long_array();
4892 _preMeshInfo->FullLoadFromFile();
4894 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4895 if(!SM) return aResult._retn();
4897 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4898 if(!SDSM) return aResult._retn();
4900 aResult->length(SDSM->NbElements());
4902 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4904 while ( eIt->more() ) {
4905 aResult[i++] = eIt->next()->GetID();
4908 SMESH_CATCH( SMESH::throwCorbaException );
4910 return aResult._retn();
4913 //=============================================================================
4915 * Return ID of nodes for given sub-mesh
4916 * If param all==true - return all nodes, else -
4917 * Return only nodes on shapes.
4919 //=============================================================================
4921 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4924 SMESH::long_array_var aResult = new SMESH::long_array();
4928 _preMeshInfo->FullLoadFromFile();
4930 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4931 if(!SM) return aResult._retn();
4933 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4934 if(!SDSM) return aResult._retn();
4937 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4938 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4939 while ( nIt->more() ) {
4940 const SMDS_MeshNode* elem = nIt->next();
4941 theElems.insert( elem->GetID() );
4944 else { // all nodes of submesh elements
4945 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4946 while ( eIt->more() ) {
4947 const SMDS_MeshElement* anElem = eIt->next();
4948 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4949 while ( nIt->more() ) {
4950 const SMDS_MeshElement* elem = nIt->next();
4951 theElems.insert( elem->GetID() );
4956 aResult->length(theElems.size());
4957 set<int>::iterator itElem;
4959 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4960 aResult[i++] = *itElem;
4962 SMESH_CATCH( SMESH::throwCorbaException );
4964 return aResult._retn();
4967 //=============================================================================
4969 * Return type of elements for given sub-mesh
4971 //=============================================================================
4973 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4975 SMESH::ElementType type = SMESH::ALL;
4979 _preMeshInfo->FullLoadFromFile();
4981 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4982 if(!SM) return SMESH::ALL;
4984 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4985 if(!SDSM) return SMESH::ALL;
4987 if(SDSM->NbElements()==0)
4988 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4990 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4991 const SMDS_MeshElement* anElem = eIt->next();
4993 type = ( SMESH::ElementType ) anElem->GetType();
4995 SMESH_CATCH( SMESH::throwCorbaException );
5001 //=============================================================================
5003 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5005 //=============================================================================
5007 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5010 _preMeshInfo->FullLoadFromFile();
5012 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5013 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5018 //=============================================================================
5020 * Get XYZ coordinates of node as list of double
5021 * If there is not node for given ID - return empty list
5023 //=============================================================================
5025 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5028 _preMeshInfo->FullLoadFromFile();
5030 SMESH::double_array_var aResult = new SMESH::double_array();
5031 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5032 if ( aMeshDS == NULL )
5033 return aResult._retn();
5036 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5038 return aResult._retn();
5042 aResult[0] = aNode->X();
5043 aResult[1] = aNode->Y();
5044 aResult[2] = aNode->Z();
5045 return aResult._retn();
5049 //=============================================================================
5051 * For given node return list of IDs of inverse elements
5052 * If there is not node for given ID - return empty list
5054 //=============================================================================
5056 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5057 SMESH::ElementType elemType)
5060 _preMeshInfo->FullLoadFromFile();
5062 SMESH::long_array_var aResult = new SMESH::long_array();
5063 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5064 if ( aMeshDS == NULL )
5065 return aResult._retn();
5068 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5070 return aResult._retn();
5072 // find inverse elements
5073 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5074 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5075 aResult->length( aNode->NbInverseElements( type ));
5076 for( int i = 0; eIt->more(); ++i )
5078 const SMDS_MeshElement* elem = eIt->next();
5079 aResult[ i ] = elem->GetID();
5081 return aResult._retn();
5084 //=============================================================================
5086 * \brief Return position of a node on shape
5088 //=============================================================================
5090 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5093 _preMeshInfo->FullLoadFromFile();
5095 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5096 aNodePosition->shapeID = 0;
5097 aNodePosition->shapeType = GEOM::SHAPE;
5099 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5100 if ( !mesh ) return aNodePosition;
5102 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5104 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5106 aNodePosition->shapeID = aNode->getshapeId();
5107 switch ( pos->GetTypeOfPosition() ) {
5109 aNodePosition->shapeType = GEOM::EDGE;
5110 aNodePosition->params.length(1);
5111 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5113 case SMDS_TOP_FACE: {
5114 SMDS_FacePositionPtr fPos = pos;
5115 aNodePosition->shapeType = GEOM::FACE;
5116 aNodePosition->params.length(2);
5117 aNodePosition->params[0] = fPos->GetUParameter();
5118 aNodePosition->params[1] = fPos->GetVParameter();
5121 case SMDS_TOP_VERTEX:
5122 aNodePosition->shapeType = GEOM::VERTEX;
5124 case SMDS_TOP_3DSPACE:
5125 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5126 aNodePosition->shapeType = GEOM::SOLID;
5127 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5128 aNodePosition->shapeType = GEOM::SHELL;
5134 return aNodePosition;
5137 //=============================================================================
5139 * \brief Return position of an element on shape
5141 //=============================================================================
5143 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5146 _preMeshInfo->FullLoadFromFile();
5148 SMESH::ElementPosition anElementPosition;
5149 anElementPosition.shapeID = 0;
5150 anElementPosition.shapeType = GEOM::SHAPE;
5152 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5153 if ( !mesh ) return anElementPosition;
5155 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5157 anElementPosition.shapeID = anElem->getshapeId();
5158 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5159 if ( !aSp.IsNull() ) {
5160 switch ( aSp.ShapeType() ) {
5162 anElementPosition.shapeType = GEOM::EDGE;
5165 anElementPosition.shapeType = GEOM::FACE;
5168 anElementPosition.shapeType = GEOM::VERTEX;
5171 anElementPosition.shapeType = GEOM::SOLID;
5174 anElementPosition.shapeType = GEOM::SHELL;
5180 return anElementPosition;
5183 //=============================================================================
5185 * If given element is node return IDs of shape from position
5186 * If there is not node for given ID - return -1
5188 //=============================================================================
5190 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5193 _preMeshInfo->FullLoadFromFile();
5195 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5196 if ( aMeshDS == NULL )
5200 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5202 return aNode->getshapeId();
5209 //=============================================================================
5211 * For given element return ID of result shape after
5212 * ::FindShape() from SMESH_MeshEditor
5213 * If there is not element for given ID - return -1
5215 //=============================================================================
5217 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5220 _preMeshInfo->FullLoadFromFile();
5222 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5223 if ( aMeshDS == NULL )
5226 // try to find element
5227 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5231 ::SMESH_MeshEditor aMeshEditor(_impl);
5232 int index = aMeshEditor.FindShape( elem );
5240 //=============================================================================
5242 * Return number of nodes for given element
5243 * If there is not element for given ID - return -1
5245 //=============================================================================
5247 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5250 _preMeshInfo->FullLoadFromFile();
5252 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5253 if ( aMeshDS == NULL ) return -1;
5254 // try to find element
5255 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5256 if(!elem) return -1;
5257 return elem->NbNodes();
5261 //=============================================================================
5263 * Return ID of node by given index for given element
5264 * If there is not element for given ID - return -1
5265 * If there is not node for given index - return -2
5267 //=============================================================================
5269 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5272 _preMeshInfo->FullLoadFromFile();
5274 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5275 if ( aMeshDS == NULL ) return -1;
5276 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5277 if(!elem) return -1;
5278 if( index>=elem->NbNodes() || index<0 ) return -1;
5279 return elem->GetNode(index)->GetID();
5282 //=============================================================================
5284 * Return IDs of nodes of given element
5286 //=============================================================================
5288 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5291 _preMeshInfo->FullLoadFromFile();
5293 SMESH::long_array_var aResult = new SMESH::long_array();
5294 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5296 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5298 aResult->length( elem->NbNodes() );
5299 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5300 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5301 aResult[ i ] = n->GetID();
5304 return aResult._retn();
5307 //=============================================================================
5309 * Return true if given node is medium node
5310 * in given quadratic element
5312 //=============================================================================
5314 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5317 _preMeshInfo->FullLoadFromFile();
5319 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5320 if ( aMeshDS == NULL ) return false;
5322 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5323 if(!aNode) return false;
5324 // try to find element
5325 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5326 if(!elem) return false;
5328 return elem->IsMediumNode(aNode);
5332 //=============================================================================
5334 * Return true if given node is medium node
5335 * in one of quadratic elements
5337 //=============================================================================
5339 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5340 SMESH::ElementType theElemType)
5343 _preMeshInfo->FullLoadFromFile();
5345 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5346 if ( aMeshDS == NULL ) return false;
5349 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5350 if(!aNode) return false;
5352 SMESH_MesherHelper aHelper( *(_impl) );
5354 SMDSAbs_ElementType aType;
5355 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5356 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5357 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5358 else aType = SMDSAbs_All;
5360 return aHelper.IsMedium(aNode,aType);
5364 //=============================================================================
5366 * Return number of edges for given element
5368 //=============================================================================
5370 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5373 _preMeshInfo->FullLoadFromFile();
5375 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5376 if ( aMeshDS == NULL ) return -1;
5377 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5378 if(!elem) return -1;
5379 return elem->NbEdges();
5383 //=============================================================================
5385 * Return number of faces for given element
5387 //=============================================================================
5389 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5392 _preMeshInfo->FullLoadFromFile();
5394 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5395 if ( aMeshDS == NULL ) return -1;
5396 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5397 if(!elem) return -1;
5398 return elem->NbFaces();
5401 //================================================================================
5403 * \brief Return nodes of given face (counted from zero) for given element.
5405 //================================================================================
5407 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5408 CORBA::Short faceIndex)
5411 _preMeshInfo->FullLoadFromFile();
5413 SMESH::long_array_var aResult = new SMESH::long_array();
5414 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5416 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5418 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5419 if ( faceIndex < vtool.NbFaces() )
5421 aResult->length( vtool.NbFaceNodes( faceIndex ));
5422 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5423 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5424 aResult[ i ] = nn[ i ]->GetID();
5428 return aResult._retn();
5431 //================================================================================
5433 * \brief Return three components of normal of given mesh face.
5435 //================================================================================
5437 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5438 CORBA::Boolean normalized)
5441 _preMeshInfo->FullLoadFromFile();
5443 SMESH::double_array_var aResult = new SMESH::double_array();
5445 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5448 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5450 aResult->length( 3 );
5451 aResult[ 0 ] = normal.X();
5452 aResult[ 1 ] = normal.Y();
5453 aResult[ 2 ] = normal.Z();
5456 return aResult._retn();
5459 //================================================================================
5461 * \brief Return an element based on all given nodes.
5463 //================================================================================
5465 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5468 _preMeshInfo->FullLoadFromFile();
5470 CORBA::Long elemID(0);
5471 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5473 vector< const SMDS_MeshNode * > nn( nodes.length() );
5474 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5475 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5478 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5479 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5480 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5481 _impl->NbVolumes( ORDER_QUADRATIC )))
5482 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5484 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5489 //================================================================================
5491 * \brief Return elements including all given nodes.
5493 //================================================================================
5495 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5496 SMESH::ElementType elemType)
5499 _preMeshInfo->FullLoadFromFile();
5501 SMESH::long_array_var result = new SMESH::long_array();
5503 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5505 vector< const SMDS_MeshNode * > nn( nodes.length() );
5506 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5507 nn[i] = mesh->FindNode( nodes[i] );
5509 std::vector<const SMDS_MeshElement *> elems;
5510 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5511 result->length( elems.size() );
5512 for ( size_t i = 0; i < elems.size(); ++i )
5513 result[i] = elems[i]->GetID();
5515 return result._retn();
5518 //=============================================================================
5520 * Return true if given element is polygon
5522 //=============================================================================
5524 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5527 _preMeshInfo->FullLoadFromFile();
5529 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5530 if ( aMeshDS == NULL ) return false;
5531 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5532 if(!elem) return false;
5533 return elem->IsPoly();
5537 //=============================================================================
5539 * Return true if given element is quadratic
5541 //=============================================================================
5543 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5546 _preMeshInfo->FullLoadFromFile();
5548 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5549 if ( aMeshDS == NULL ) return false;
5550 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5551 if(!elem) return false;
5552 return elem->IsQuadratic();
5555 //=============================================================================
5557 * Return diameter of ball discrete element or zero in case of an invalid \a id
5559 //=============================================================================
5561 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5564 _preMeshInfo->FullLoadFromFile();
5566 if ( const SMDS_BallElement* ball =
5567 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5568 return ball->GetDiameter();
5573 //=============================================================================
5575 * Return bary center for given element
5577 //=============================================================================
5579 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5582 _preMeshInfo->FullLoadFromFile();
5584 SMESH::double_array_var aResult = new SMESH::double_array();
5585 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5586 if ( aMeshDS == NULL )
5587 return aResult._retn();
5589 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5591 return aResult._retn();
5593 if(elem->GetType()==SMDSAbs_Volume) {
5594 SMDS_VolumeTool aTool;
5595 if(aTool.Set(elem)) {
5597 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5602 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5604 double x=0., y=0., z=0.;
5605 for(; anIt->more(); ) {
5607 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5621 return aResult._retn();
5624 //================================================================================
5626 * \brief Create a group of elements preventing computation of a sub-shape
5628 //================================================================================
5630 SMESH::ListOfGroups*
5631 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5632 const char* theGroupName )
5634 Unexpect aCatch(SALOME_SalomeException);
5636 if ( !theGroupName || strlen( theGroupName) == 0 )
5637 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5639 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5640 ::SMESH_MeshEditor::ElemFeatures elemType;
5642 // submesh by subshape id
5643 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5644 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5647 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5648 if ( error && error->HasBadElems() )
5650 // sort bad elements by type
5651 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5652 const list<const SMDS_MeshElement*>& badElems =
5653 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5654 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5655 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5656 for ( ; elemIt != elemEnd; ++elemIt )
5658 const SMDS_MeshElement* elem = *elemIt;
5659 if ( !elem ) continue;
5661 if ( elem->GetID() < 1 )
5663 // elem is a temporary element, make a real element
5664 vector< const SMDS_MeshNode* > nodes;
5665 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5666 while ( nIt->more() && elem )
5668 nodes.push_back( nIt->next() );
5669 if ( nodes.back()->GetID() < 1 )
5670 elem = 0; // a temporary element on temporary nodes
5674 ::SMESH_MeshEditor editor( _impl );
5675 elem = editor.AddElement( nodes, elemType.Init( elem ));
5679 elemsByType[ elem->GetType() ].push_back( elem );
5682 // how many groups to create?
5684 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5685 nbTypes += int( !elemsByType[ i ].empty() );
5686 groups->length( nbTypes );
5689 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5691 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5692 if ( elems.empty() ) continue;
5694 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5695 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5697 SMESH::SMESH_Mesh_var mesh = _this();
5698 SALOMEDS::SObject_wrap aSO =
5699 _gen_i->PublishGroup( mesh, groups[ iG ],
5700 GEOM::GEOM_Object::_nil(), theGroupName);
5702 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5703 if ( !grp_i ) continue;
5705 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5706 for ( size_t iE = 0; iE < elems.size(); ++iE )
5707 grpDS->SMDSGroup().Add( elems[ iE ]);
5712 return groups._retn();
5715 //=============================================================================
5717 * Create and publish group servants if any groups were imported or created anyhow
5719 //=============================================================================
5721 void SMESH_Mesh_i::CreateGroupServants()
5723 SMESH::SMESH_Mesh_var aMesh = _this();
5726 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5727 while ( groupIt->more() )
5729 ::SMESH_Group* group = groupIt->next();
5730 int anId = group->GetID();
5732 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5733 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5735 addedIDs.insert( anId );
5737 SMESH_GroupBase_i* aGroupImpl;
5739 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5740 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5742 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5743 shape = groupOnGeom->GetShape();
5746 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5749 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5750 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5751 aGroupImpl->Register();
5753 // register CORBA object for persistence
5754 int nextId = _gen_i->RegisterObject( groupVar );
5755 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5756 else { nextId = 0; } // avoid "unused variable" warning in release mode
5758 // publishing the groups in the study
5759 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5760 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5763 if ( !addedIDs.empty() )
5766 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5767 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5769 set<int>::iterator it = addedIDs.find( i_grp->first );
5770 if ( it != addedIDs.end() )
5772 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5773 addedIDs.erase( it );
5774 if ( addedIDs.empty() )
5781 //=============================================================================
5783 * \brief Return true if all sub-meshes are computed OK - to update an icon
5785 //=============================================================================
5787 bool SMESH_Mesh_i::IsComputedOK()
5789 return _impl->IsComputedOK();
5792 //=============================================================================
5794 * \brief Return groups cantained in _mapGroups by their IDs
5796 //=============================================================================
5798 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5800 int nbGroups = groupIDs.size();
5801 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5802 aList->length( nbGroups );
5804 list<int>::const_iterator ids = groupIDs.begin();
5805 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5807 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5808 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5809 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5811 aList->length( nbGroups );
5812 return aList._retn();
5815 //=============================================================================
5817 * \brief Return information about imported file
5819 //=============================================================================
5821 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5823 SMESH::MedFileInfo_var res( _medFileInfo );
5824 if ( !res.operator->() ) {
5825 res = new SMESH::MedFileInfo;
5827 res->fileSize = res->major = res->minor = res->release = -1;
5832 //=======================================================================
5833 //function : FileInfoToString
5834 //purpose : Persistence of file info
5835 //=======================================================================
5837 std::string SMESH_Mesh_i::FileInfoToString()
5840 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5842 s = SMESH_Comment( _medFileInfo->fileSize )
5843 << " " << _medFileInfo->major
5844 << " " << _medFileInfo->minor
5845 << " " << _medFileInfo->release
5846 << " " << _medFileInfo->fileName;
5851 //=======================================================================
5852 //function : FileInfoFromString
5853 //purpose : Persistence of file info
5854 //=======================================================================
5856 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5858 std::string size, major, minor, release, fileName;
5859 std::istringstream is(info);
5860 is >> size >> major >> minor >> release;
5861 fileName = info.data() + ( size.size() + 1 +
5864 release.size()+ 1 );
5866 _medFileInfo = new SMESH::MedFileInfo();
5867 _medFileInfo->fileName = fileName.c_str();
5868 _medFileInfo->fileSize = atoi( size.c_str() );
5869 _medFileInfo->major = atoi( major.c_str() );
5870 _medFileInfo->minor = atoi( minor.c_str() );
5871 _medFileInfo->release = atoi( release.c_str() );
5874 //=============================================================================
5876 * \brief Pass names of mesh groups from study to mesh DS
5878 //=============================================================================
5880 void SMESH_Mesh_i::checkGroupNames()
5882 int nbGrp = NbGroups();
5886 SMESH::ListOfGroups* grpList = 0;
5887 // avoid dump of "GetGroups"
5889 // store python dump into a local variable inside local scope
5890 SMESH::TPythonDump pDump; // do not delete this line of code
5891 grpList = GetGroups();
5894 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5895 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5898 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5899 if ( aGrpSO->_is_nil() )
5901 // correct name of the mesh group if necessary
5902 const char* guiName = aGrpSO->GetName();
5903 if ( strcmp(guiName, aGrp->GetName()) )
5904 aGrp->SetName( guiName );
5908 //=============================================================================
5910 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
5912 //=============================================================================
5913 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5915 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5919 //=============================================================================
5921 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
5923 //=============================================================================
5925 char* SMESH_Mesh_i::GetParameters()
5927 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5930 //=============================================================================
5932 * \brief Return list of notebook variables used for last Mesh operation
5934 //=============================================================================
5935 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5937 SMESH::string_array_var aResult = new SMESH::string_array();
5938 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5940 CORBA::String_var aParameters = GetParameters();
5941 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5942 if ( aSections->length() > 0 ) {
5943 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5944 aResult->length( aVars.length() );
5945 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5946 aResult[i] = CORBA::string_dup( aVars[i] );
5949 return aResult._retn();
5952 //================================================================================
5954 * \brief Return types of elements it contains
5956 //================================================================================
5958 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5961 return _preMeshInfo->GetTypes();
5963 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5967 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5968 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5969 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5970 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5971 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5972 if (_impl->NbNodes() &&
5973 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5974 types->length( nbTypes );
5976 return types._retn();
5979 //================================================================================
5981 * \brief Return self
5983 //================================================================================
5985 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5987 return SMESH::SMESH_Mesh::_duplicate( _this() );
5990 //================================================================================
5992 * \brief Return false if GetMeshInfo() return incorrect information that may
5993 * happen if mesh data is not yet fully loaded from the file of study.
5997 //================================================================================
5999 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6001 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6004 //=============================================================================
6006 * \brief Return number of mesh elements per each \a EntityType
6008 //=============================================================================
6010 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6013 return _preMeshInfo->GetMeshInfo();
6015 SMESH::long_array_var aRes = new SMESH::long_array();
6016 aRes->length(SMESH::Entity_Last);
6017 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6019 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6021 return aRes._retn();
6022 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6023 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6024 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6025 return aRes._retn();
6028 //=============================================================================
6030 * \brief Return number of mesh elements per each \a ElementType
6032 //=============================================================================
6034 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6036 SMESH::long_array_var aRes = new SMESH::long_array();
6037 aRes->length(SMESH::NB_ELEMENT_TYPES);
6038 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6041 const SMDS_MeshInfo* meshInfo = 0;
6043 meshInfo = _preMeshInfo;
6044 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6045 meshInfo = & meshDS->GetMeshInfo();
6048 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6049 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6051 return aRes._retn();
6054 //=============================================================================
6056 * Collect statistic of mesh elements given by iterator
6058 //=============================================================================
6060 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6061 SMESH::long_array& theInfo)
6063 if (!theItr) return;
6064 while (theItr->more())
6065 theInfo[ theItr->next()->GetEntityType() ]++;
6067 //=============================================================================
6069 * Return mesh unstructed grid information.
6071 //=============================================================================
6073 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6075 SALOMEDS::TMPFile_var SeqFile;
6076 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6077 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6079 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6080 aWriter->WriteToOutputStringOn();
6081 aWriter->SetInputData(aGrid);
6082 aWriter->SetFileTypeToBinary();
6084 char* str = aWriter->GetOutputString();
6085 int size = aWriter->GetOutputStringLength();
6087 //Allocate octet buffer of required size
6088 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6089 //Copy ostrstream content to the octet buffer
6090 memcpy(OctetBuf, str, size);
6091 //Create and return TMPFile
6092 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6096 return SeqFile._retn();
6099 //=============================================================================
6100 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6101 * SMESH::ElementType type) */
6103 using namespace SMESH::Controls;
6104 //-----------------------------------------------------------------------------
6105 struct PredicateIterator : public SMDS_ElemIterator
6107 SMDS_ElemIteratorPtr _elemIter;
6108 PredicatePtr _predicate;
6109 const SMDS_MeshElement* _elem;
6110 SMDSAbs_ElementType _type;
6112 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6113 PredicatePtr predicate,
6114 SMDSAbs_ElementType type):
6115 _elemIter(iterator), _predicate(predicate), _type(type)
6123 virtual const SMDS_MeshElement* next()
6125 const SMDS_MeshElement* res = _elem;
6127 while ( _elemIter->more() && !_elem )
6129 if ((_elem = _elemIter->next()) &&
6130 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6131 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6138 //-----------------------------------------------------------------------------
6139 struct IDSourceIterator : public SMDS_ElemIterator
6141 const CORBA::Long* _idPtr;
6142 const CORBA::Long* _idEndPtr;
6143 SMESH::long_array_var _idArray;
6144 const SMDS_Mesh* _mesh;
6145 const SMDSAbs_ElementType _type;
6146 const SMDS_MeshElement* _elem;
6148 IDSourceIterator( const SMDS_Mesh* mesh,
6149 const CORBA::Long* ids,
6151 SMDSAbs_ElementType type):
6152 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6154 if ( _idPtr && nbIds && _mesh )
6157 IDSourceIterator( const SMDS_Mesh* mesh,
6158 SMESH::long_array* idArray,
6159 SMDSAbs_ElementType type):
6160 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6162 if ( idArray && _mesh )
6164 _idPtr = &_idArray[0];
6165 _idEndPtr = _idPtr + _idArray->length();
6173 virtual const SMDS_MeshElement* next()
6175 const SMDS_MeshElement* res = _elem;
6177 while ( _idPtr < _idEndPtr && !_elem )
6179 if ( _type == SMDSAbs_Node )
6181 _elem = _mesh->FindNode( *_idPtr++ );
6183 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6184 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6192 //-----------------------------------------------------------------------------
6194 struct NodeOfElemIterator : public SMDS_ElemIterator
6196 TColStd_MapOfInteger _checkedNodeIDs;
6197 SMDS_ElemIteratorPtr _elemIter;
6198 SMDS_ElemIteratorPtr _nodeIter;
6199 const SMDS_MeshElement* _node;
6201 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6203 if ( _elemIter && _elemIter->more() )
6205 _nodeIter = _elemIter->next()->nodesIterator();
6213 virtual const SMDS_MeshElement* next()
6215 const SMDS_MeshElement* res = _node;
6217 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6219 if ( _nodeIter->more() )
6221 _node = _nodeIter->next();
6222 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6227 _nodeIter = _elemIter->next()->nodesIterator();
6235 //=============================================================================
6237 * Return iterator on elements of given type in given object
6239 //=============================================================================
6241 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6242 SMESH::ElementType theType)
6244 SMDS_ElemIteratorPtr elemIt;
6245 bool typeOK = ( theType == SMESH::ALL );
6246 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6248 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6249 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6250 if ( !mesh_i ) return elemIt;
6251 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6253 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6255 elemIt = meshDS->elementsIterator( elemType );
6258 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6260 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6263 elemIt = sm->GetElements();
6264 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6266 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6267 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6271 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6273 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6274 if ( groupDS && ( elemType == groupDS->GetType() ||
6275 elemType == SMDSAbs_Node ||
6276 elemType == SMDSAbs_All ))
6278 elemIt = groupDS->GetElements();
6279 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6282 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6284 if ( filter_i->GetElementType() == theType ||
6285 filter_i->GetElementType() == SMESH::ALL ||
6286 elemType == SMDSAbs_Node ||
6287 elemType == SMDSAbs_All)
6289 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6290 if ( pred_i && pred_i->GetPredicate() )
6292 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6293 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6294 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6295 elemIt = SMDS_ElemIteratorPtr
6296 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6297 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6303 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6304 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6305 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6307 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6308 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6311 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6312 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6316 SMESH::long_array_var ids = theObject->GetIDs();
6317 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6319 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6322 if ( elemIt && elemIt->more() && !typeOK )
6324 if ( elemType == SMDSAbs_Node )
6326 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6330 elemIt = SMDS_ElemIteratorPtr();
6336 //=============================================================================
6337 namespace // Finding concurrent hypotheses
6338 //=============================================================================
6342 * \brief mapping of mesh dimension into shape type
6344 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6346 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6348 case 0: aType = TopAbs_VERTEX; break;
6349 case 1: aType = TopAbs_EDGE; break;
6350 case 2: aType = TopAbs_FACE; break;
6352 default:aType = TopAbs_SOLID; break;
6357 //-----------------------------------------------------------------------------
6359 * \brief Internal structure used to find concurrent submeshes
6361 * It represents a pair < submesh, concurrent dimension >, where
6362 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6363 * with another submesh. In other words, it is dimension of a hypothesis assigned
6370 int _dim; //!< a dimension the algo can build (concurrent dimension)
6371 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6372 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6373 const SMESH_subMesh* _subMesh;
6374 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6376 //-----------------------------------------------------------------------------
6377 // Return the algorithm
6378 const SMESH_Algo* GetAlgo() const
6379 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6381 //-----------------------------------------------------------------------------
6383 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6385 const TopoDS_Shape& theShape)
6387 _subMesh = theSubMesh;
6388 SetShape( theDim, theShape );
6391 //-----------------------------------------------------------------------------
6393 void SetShape(const int theDim,
6394 const TopoDS_Shape& theShape)
6397 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6398 if (_dim >= _ownDim)
6399 _shapeMap.Add( theShape );
6401 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6402 for( ; anExp.More(); anExp.Next() )
6403 _shapeMap.Add( anExp.Current() );
6407 //-----------------------------------------------------------------------------
6408 //! Check sharing of sub-shapes
6409 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6410 const TopTools_MapOfShape& theToFind,
6411 const TopAbs_ShapeEnum theType)
6413 bool isShared = false;
6414 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6415 for (; !isShared && anItr.More(); anItr.Next() )
6417 const TopoDS_Shape aSubSh = anItr.Key();
6418 // check for case when concurrent dimensions are same
6419 isShared = theToFind.Contains( aSubSh );
6420 // check for sub-shape with concurrent dimension
6421 TopExp_Explorer anExp( aSubSh, theType );
6422 for ( ; !isShared && anExp.More(); anExp.Next() )
6423 isShared = theToFind.Contains( anExp.Current() );
6428 //-----------------------------------------------------------------------------
6429 //! check algorithms
6430 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6431 const SMESHDS_Hypothesis* theA2)
6433 if ( !theA1 || !theA2 ||
6434 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6435 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6436 return false; // one of the hypothesis is not algorithm
6437 // check algorithm names (should be equal)
6438 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6442 //-----------------------------------------------------------------------------
6443 //! Check if sub-shape hypotheses are concurrent
6444 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6446 if ( _subMesh == theOther->_subMesh )
6447 return false; // same sub-shape - should not be
6449 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6450 // any of the two submeshes is not on COMPOUND shape )
6451 // -> no concurrency
6452 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6453 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6454 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6455 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6456 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6459 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6460 if ( !checkSubShape )
6463 // check algorithms to be same
6464 const SMESH_Algo* a1 = this->GetAlgo();
6465 const SMESH_Algo* a2 = theOther->GetAlgo();
6466 bool isSame = checkAlgo( a1, a2 );
6470 // commented off for IPAL54678
6471 // if ( !a1 || !a2 )
6472 // return false; // pb?
6473 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6476 // check hypothesises for concurrence (skip first as algorithm)
6478 // pointers should be same, because it is referened from mesh hypothesis partition
6479 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6480 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6481 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6482 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6484 // the submeshes are concurrent if their algorithms has different parameters
6485 return nbSame != theOther->_hypotheses.size() - 1;
6488 // Return true if algorithm of this SMESH_DimHyp is used if no
6489 // sub-mesh order is imposed by the user
6490 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6492 // NeedDiscreteBoundary() algo has a higher priority
6493 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6494 theOther->GetAlgo()->NeedDiscreteBoundary() )
6495 return !this->GetAlgo()->NeedDiscreteBoundary();
6497 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6500 }; // end of SMESH_DimHyp
6501 //-----------------------------------------------------------------------------
6503 typedef list<const SMESH_DimHyp*> TDimHypList;
6505 //-----------------------------------------------------------------------------
6507 void addDimHypInstance(const int theDim,
6508 const TopoDS_Shape& theShape,
6509 const SMESH_Algo* theAlgo,
6510 const SMESH_subMesh* theSubMesh,
6511 const list <const SMESHDS_Hypothesis*>& theHypList,
6512 TDimHypList* theDimHypListArr )
6514 if ( !theAlgo->NeedDiscreteBoundary() &&
6515 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6517 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6518 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6520 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6521 dimHyp->_hypotheses.push_front(theAlgo);
6522 listOfdimHyp.push_back( dimHyp );
6525 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6526 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6527 theHypList.begin(), theHypList.end() );
6530 //-----------------------------------------------------------------------------
6531 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6532 TDimHypList& theListOfConcurr)
6534 if ( theListOfConcurr.empty() )
6536 theListOfConcurr.push_back( theDimHyp );
6540 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6541 while ( hypIt != theListOfConcurr.end() &&
6542 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6544 theListOfConcurr.insert( hypIt, theDimHyp );
6548 //-----------------------------------------------------------------------------
6549 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6550 const TDimHypList& theListOfDimHyp,
6551 TDimHypList& theListOfConcurrHyp,
6552 set<int>& theSetOfConcurrId )
6554 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6555 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6557 const SMESH_DimHyp* curDimHyp = *rIt;
6558 if ( curDimHyp == theDimHyp )
6559 break; // meet own dimHyp pointer in same dimension
6561 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6562 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6564 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6569 //-----------------------------------------------------------------------------
6570 void unionLists(TListOfInt& theListOfId,
6571 TListOfListOfInt& theListOfListOfId,
6574 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6575 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6578 continue; //skip already treated lists
6579 // check if other list has any same submesh object
6580 TListOfInt& otherListOfId = *it;
6581 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6582 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6585 // union two lists (from source into target)
6586 TListOfInt::iterator it2 = otherListOfId.begin();
6587 for ( ; it2 != otherListOfId.end(); it2++ ) {
6588 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6589 theListOfId.push_back(*it2);
6591 // clear source list
6592 otherListOfId.clear();
6595 //-----------------------------------------------------------------------------
6597 //! free memory allocated for dimension-hypothesis objects
6598 void removeDimHyps( TDimHypList* theArrOfList )
6600 for (int i = 0; i < 4; i++ ) {
6601 TDimHypList& listOfdimHyp = theArrOfList[i];
6602 TDimHypList::const_iterator it = listOfdimHyp.begin();
6603 for ( ; it != listOfdimHyp.end(); it++ )
6608 //-----------------------------------------------------------------------------
6610 * \brief find common submeshes with given submesh
6611 * \param theSubMeshList list of already collected submesh to check
6612 * \param theSubMesh given submesh to intersect with other
6613 * \param theCommonSubMeshes collected common submeshes
6615 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6616 const SMESH_subMesh* theSubMesh,
6617 set<const SMESH_subMesh*>& theCommon )
6621 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6622 for ( ; it != theSubMeshList.end(); it++ )
6623 theSubMesh->FindIntersection( *it, theCommon );
6624 theSubMeshList.push_back( theSubMesh );
6625 //theCommon.insert( theSubMesh );
6628 //-----------------------------------------------------------------------------
6629 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6631 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6632 for ( ; listsIt != smLists.end(); ++listsIt )
6634 const TListOfInt& smIDs = *listsIt;
6635 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6643 //=============================================================================
6645 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6647 //=============================================================================
6649 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6651 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6652 if ( isSubMeshInList( submeshID, anOrder ))
6655 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6656 return isSubMeshInList( submeshID, allConurrent );
6659 //=============================================================================
6661 * \brief Return sub-mesh objects list in meshing order
6663 //=============================================================================
6665 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6667 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6669 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6671 return aResult._retn();
6673 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6674 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6675 anOrder.splice( anOrder.end(), allConurrent );
6678 TListOfListOfInt::iterator listIt = anOrder.begin();
6679 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6680 unionLists( *listIt, anOrder, listIndx + 1 );
6682 // convert submesh ids into interface instances
6683 // and dump command into python
6684 convertMeshOrder( anOrder, aResult, false );
6686 return aResult._retn();
6689 //=============================================================================
6691 * \brief Finds concurrent sub-meshes
6693 //=============================================================================
6695 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6697 TListOfListOfInt anOrder;
6698 ::SMESH_Mesh& mesh = GetImpl();
6700 // collect submeshes and detect concurrent algorithms and hypothesises
6701 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6703 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6704 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6706 ::SMESH_subMesh* sm = (*i_sm).second;
6708 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6710 // list of assigned hypothesises
6711 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6712 // Find out dimensions where the submesh can be concurrent.
6713 // We define the dimensions by algo of each of hypotheses in hypList
6714 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6715 for( ; hypIt != hypList.end(); hypIt++ )
6717 SMESH_Algo* anAlgo = 0;
6718 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6719 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6720 // hyp it-self is algo
6721 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6723 // try to find algorithm with help of sub-shapes
6724 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6725 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6726 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6729 continue; // no algorithm assigned to a current submesh
6731 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6732 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6733 // and !anAlgo->NeedLowerHyps( dim ))
6735 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6736 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6737 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6739 } // end iterations on submesh
6741 // iterate on created dimension-hypotheses and check for concurrents
6742 for ( int i = 0; i < 4; i++ )
6744 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6745 // check for concurrents in own and other dimensions (step-by-step)
6746 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6747 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6749 const SMESH_DimHyp* dimHyp = *dhIt;
6750 TDimHypList listOfConcurr;
6751 set<int> setOfConcurrIds;
6752 // looking for concurrents and collect into own list
6753 for ( int j = i; j < 4; j++ )
6754 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6755 // check if any concurrents found
6756 if ( listOfConcurr.size() > 0 )
6758 // add own submesh to list of concurrent
6759 addInOrderOfPriority( dimHyp, listOfConcurr );
6760 list<int> listOfConcurrIds;
6761 TDimHypList::iterator hypIt = listOfConcurr.begin();
6762 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6763 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6764 anOrder.push_back( listOfConcurrIds );
6769 removeDimHyps(dimHypListArr);
6771 // now, minimize the number of concurrent groups
6772 // Here we assume that lists of submeshes can have same submesh
6773 // in case of multi-dimension algorithms, as result
6774 // list with common submesh has to be united into one list
6776 TListOfListOfInt::iterator listIt = anOrder.begin();
6777 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6778 unionLists( *listIt, anOrder, listIndx + 1 );
6783 //=============================================================================
6785 * \brief Set submesh object order
6786 * \param theSubMeshArray submesh array order
6788 //=============================================================================
6790 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6793 _preMeshInfo->ForgetOrLoad();
6796 ::SMESH_Mesh& mesh = GetImpl();
6798 TPythonDump aPythonDump; // prevent dump of called methods
6799 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6801 TListOfListOfInt subMeshOrder;
6802 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6804 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6805 TListOfInt subMeshIds;
6807 aPythonDump << ", ";
6808 aPythonDump << "[ ";
6809 // Collect subMeshes which should be clear
6810 // do it list-by-list, because modification of submesh order
6811 // take effect between concurrent submeshes only
6812 set<const SMESH_subMesh*> subMeshToClear;
6813 list<const SMESH_subMesh*> subMeshList;
6814 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6816 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6818 aPythonDump << ", ";
6819 aPythonDump << subMesh;
6820 subMeshIds.push_back( subMesh->GetId() );
6821 // detect common parts of submeshes
6822 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6823 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6825 aPythonDump << " ]";
6826 subMeshOrder.push_back( subMeshIds );
6828 // clear collected sub-meshes
6829 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6830 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6831 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6833 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6834 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6835 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6838 aPythonDump << " ])";
6840 mesh.SetMeshOrder( subMeshOrder );
6843 SMESH::SMESH_Mesh_var me = _this();
6844 _gen_i->UpdateIcons( me );
6849 //=============================================================================
6851 * \brief Convert submesh ids into submesh interfaces
6853 //=============================================================================
6855 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6856 SMESH::submesh_array_array& theResOrder,
6857 const bool theIsDump)
6859 int nbSet = theIdsOrder.size();
6860 TPythonDump aPythonDump; // prevent dump of called methods
6862 aPythonDump << "[ ";
6863 theResOrder.length(nbSet);
6864 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6866 for( ; it != theIdsOrder.end(); it++ )
6868 // translate submesh identificators into submesh objects
6869 // takeing into account real number of concurrent lists
6870 const TListOfInt& aSubOrder = (*it);
6871 if (!aSubOrder.size())
6874 aPythonDump << "[ ";
6875 // convert shape indices into interfaces
6876 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6877 aResSubSet->length(aSubOrder.size());
6878 TListOfInt::const_iterator subIt = aSubOrder.begin();
6880 for( j = 0; subIt != aSubOrder.end(); subIt++ )
6882 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6884 SMESH::SMESH_subMesh_var subMesh =
6885 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6888 aPythonDump << ", ";
6889 aPythonDump << subMesh;
6891 aResSubSet[ j++ ] = subMesh;
6894 aPythonDump << " ]";
6896 theResOrder[ listIndx++ ] = aResSubSet;
6898 // correct number of lists
6899 theResOrder.length( listIndx );
6902 // finilise python dump
6903 aPythonDump << " ]";
6904 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6908 namespace // utils used by SMESH_MeshPartDS
6911 * \brief Class used to access to protected data of SMDS_MeshInfo
6913 struct TMeshInfo : public SMDS_MeshInfo
6915 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6918 * \brief Element holing its ID only
6920 struct TElemID : public SMDS_LinearEdge
6922 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6926 //================================================================================
6928 // Implementation of SMESH_MeshPartDS
6930 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6931 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6933 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6934 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6937 _meshDS = mesh_i->GetImpl().GetMeshDS();
6939 SetPersistentId( _meshDS->GetPersistentId() );
6941 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6943 // <meshPart> is the whole mesh
6944 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6946 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6947 myGroupSet = _meshDS->GetGroups();
6952 SMESH::long_array_var anIDs = meshPart->GetIDs();
6953 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6954 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6956 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6957 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6958 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6963 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6964 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6965 if ( _elements[ e->GetType() ].insert( e ).second )
6968 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6969 while ( nIt->more() )
6971 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6972 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6979 ShapeToMesh( _meshDS->ShapeToMesh() );
6981 _meshDS = 0; // to enforce iteration on _elements and _nodes
6984 // -------------------------------------------------------------------------------------
6985 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6986 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6989 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6990 for ( ; partIt != meshPart.end(); ++partIt )
6991 if ( const SMDS_MeshElement * e = *partIt )
6992 if ( _elements[ e->GetType() ].insert( e ).second )
6995 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6996 while ( nIt->more() )
6998 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6999 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7005 // -------------------------------------------------------------------------------------
7006 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7008 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7010 TElemID elem( IDelem );
7011 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7012 if ( !_elements[ iType ].empty() )
7014 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7015 if ( it != _elements[ iType ].end() )
7020 // -------------------------------------------------------------------------------------
7021 bool SMESH_MeshPartDS::HasNumerationHoles()
7023 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7025 return ( MinNodeID() != 1 ||
7026 MaxNodeID() != NbNodes() ||
7027 MinElementID() != 1 ||
7028 MaxElementID() != NbElements() );
7030 // -------------------------------------------------------------------------------------
7031 int SMESH_MeshPartDS::MaxNodeID() const
7033 if ( _meshDS ) return _meshDS->MaxNodeID();
7034 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7036 // -------------------------------------------------------------------------------------
7037 int SMESH_MeshPartDS::MinNodeID() const
7039 if ( _meshDS ) return _meshDS->MinNodeID();
7040 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7042 // -------------------------------------------------------------------------------------
7043 int SMESH_MeshPartDS::MaxElementID() const
7045 if ( _meshDS ) return _meshDS->MaxElementID();
7047 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7048 if ( !_elements[ iType ].empty() )
7049 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7052 // -------------------------------------------------------------------------------------
7053 int SMESH_MeshPartDS::MinElementID() const
7055 if ( _meshDS ) return _meshDS->MinElementID();
7057 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7058 if ( !_elements[ iType ].empty() )
7059 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7062 // -------------------------------------------------------------------------------------
7063 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7065 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7067 typedef SMDS_SetIterator
7068 <const SMDS_MeshElement*,
7069 TIDSortedElemSet::const_iterator,
7070 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7071 SMDS_MeshElement::GeomFilter
7074 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7076 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7077 _elements[type].end(),
7078 SMDS_MeshElement::GeomFilter( geomType )));
7080 // -------------------------------------------------------------------------------------
7081 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7083 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7085 typedef SMDS_SetIterator
7086 <const SMDS_MeshElement*,
7087 TIDSortedElemSet::const_iterator,
7088 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7089 SMDS_MeshElement::EntityFilter
7092 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7094 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7095 _elements[type].end(),
7096 SMDS_MeshElement::EntityFilter( entity )));
7098 // -------------------------------------------------------------------------------------
7099 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7101 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7102 if ( type == SMDSAbs_All && !_meshDS )
7104 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7106 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7107 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7109 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7111 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7112 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7114 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7115 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7117 // -------------------------------------------------------------------------------------
7118 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7119 iterType SMESH_MeshPartDS::methName() const \
7121 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7122 return _meshDS ? _meshDS->methName() : iterType \
7123 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7125 // -------------------------------------------------------------------------------------
7126 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7127 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7128 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7129 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7130 #undef _GET_ITER_DEFINE
7132 // END Implementation of SMESH_MeshPartDS
7134 //================================================================================