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 )
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief Return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //================================================================================
224 * \brief Return the shape to mesh
226 //================================================================================
228 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
231 Unexpect aCatch(SALOME_SalomeException);
232 GEOM::GEOM_Object_var aShapeObj;
234 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
237 aShapeObj = _gen_i->ShapeToGeomObject( S );
238 if ( aShapeObj->_is_nil() )
240 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
241 // find GEOM_Object by entry (IPAL52735)
242 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
243 for ( ; data != _geomGroupData.end(); ++data )
244 if ( data->_smeshObject->_is_equivalent( _this() ))
246 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
247 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
248 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
254 catch(SALOME_Exception & S_ex) {
255 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
257 return aShapeObj._retn();
260 //================================================================================
262 * \brief Return false if the mesh is not yet fully loaded from the study file
264 //================================================================================
266 CORBA::Boolean SMESH_Mesh_i::IsLoaded()
268 Unexpect aCatch(SALOME_SalomeException);
269 return !_preMeshInfo;
272 //================================================================================
274 * \brief Load full mesh data from the study file
276 //================================================================================
278 void SMESH_Mesh_i::Load()
280 Unexpect aCatch(SALOME_SalomeException);
282 _preMeshInfo->FullLoadFromFile();
285 //================================================================================
287 * \brief Remove all nodes and elements
289 //================================================================================
291 void SMESH_Mesh_i::Clear()
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
299 //CheckGeomGroupModif(); // issue 20145
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
307 SMESH::SMESH_Mesh_var mesh = _this();
308 _gen_i->UpdateIcons( mesh );
311 //================================================================================
313 * \brief Remove all nodes and elements for indicated shape
315 //================================================================================
317 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
320 Unexpect aCatch(SALOME_SalomeException);
322 _preMeshInfo->FullLoadFromFile();
325 _impl->ClearSubMesh( ShapeID );
327 catch(SALOME_Exception & S_ex) {
328 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
330 _impl->GetMeshDS()->Modified();
332 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
335 //=============================================================================
337 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
339 //=============================================================================
341 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
343 SMESH::DriverMED_ReadStatus res;
346 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
347 res = SMESH::DRS_OK; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
349 res = SMESH::DRS_EMPTY; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
351 res = SMESH::DRS_WARN_RENUMBER; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
353 res = SMESH::DRS_WARN_SKIP_ELEM; break;
354 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
355 res = SMESH::DRS_WARN_DESCENDING; break;
356 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
358 res = SMESH::DRS_FAIL; break;
363 //=============================================================================
365 * Convert ::SMESH_ComputeError to SMESH::ComputeError
367 //=============================================================================
369 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
371 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
372 errVar->subShapeID = -1;
373 errVar->hasBadMesh = false;
375 if ( !errorPtr || errorPtr->IsOK() )
377 errVar->code = SMESH::COMPERR_OK;
381 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
382 errVar->comment = errorPtr->myComment.c_str();
384 return errVar._retn();
387 //=============================================================================
391 * Import mesh data from MED file
393 //=============================================================================
395 SMESH::DriverMED_ReadStatus
396 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
398 Unexpect aCatch(SALOME_SalomeException);
401 status = _impl->MEDToMesh( theFileName, theMeshName );
403 catch( SALOME_Exception& S_ex ) {
404 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
407 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
410 CreateGroupServants();
412 int major, minor, release;
413 major = minor = release = 0;
414 MED::GetMEDVersion(theFileName, major, minor, release);
415 _medFileInfo = new SMESH::MedFileInfo();
416 _medFileInfo->fileName = theFileName;
417 _medFileInfo->fileSize = 0;
418 _medFileInfo->major = major;
419 _medFileInfo->minor = minor;
420 _medFileInfo->release = release;
421 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
423 return ConvertDriverMEDReadStatus(status);
426 //================================================================================
428 * \brief Import mesh data from the CGNS file
430 //================================================================================
432 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
433 const int theMeshIndex,
434 std::string& theMeshName )
437 Unexpect aCatch(SALOME_SalomeException);
440 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
442 catch( SALOME_Exception& S_ex ) {
443 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
446 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
449 CreateGroupServants();
451 _medFileInfo = new SMESH::MedFileInfo();
452 _medFileInfo->fileName = theFileName;
453 _medFileInfo->major = 0;
454 _medFileInfo->minor = 0;
455 _medFileInfo->release = 0;
456 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
458 return ConvertDriverMEDReadStatus(status);
461 //================================================================================
463 * \brief Return string representation of a MED file version comprising nbDigits
465 //================================================================================
467 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
469 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
471 return CORBA::string_dup( ver.c_str() );
474 //================================================================================
476 * Return the list of med versions compatibles for write/append,
477 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
479 //================================================================================
481 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
483 SMESH::long_array_var aResult = new SMESH::long_array();
484 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
485 long nbver = mvok.size();
486 aResult->length( nbver );
487 for ( int i = 0; i < nbver; i++ )
488 aResult[i] = mvok[i];
489 return aResult._retn();
492 //=============================================================================
496 * Import mesh data from MED file
498 //=============================================================================
500 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
505 // Read mesh with name = <theMeshName> into SMESH_Mesh
506 _impl->UNVToMesh( theFileName );
508 CreateGroupServants();
510 _medFileInfo = new SMESH::MedFileInfo();
511 _medFileInfo->fileName = theFileName;
512 _medFileInfo->major = 0;
513 _medFileInfo->minor = 0;
514 _medFileInfo->release = 0;
515 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
517 SMESH_CATCH( SMESH::throwCorbaException );
522 //=============================================================================
526 * Import mesh data from STL file
528 //=============================================================================
530 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
535 // Read mesh with name = <theMeshName> into SMESH_Mesh
536 std::string name = _impl->STLToMesh( theFileName );
539 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
540 _gen_i->SetName( meshSO, name.c_str() );
542 _medFileInfo = new SMESH::MedFileInfo();
543 _medFileInfo->fileName = theFileName;
544 _medFileInfo->major = 0;
545 _medFileInfo->minor = 0;
546 _medFileInfo->release = 0;
547 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
549 SMESH_CATCH( SMESH::throwCorbaException );
554 //================================================================================
556 * \brief Function used in SMESH_CATCH by ImportGMFFile()
558 //================================================================================
562 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
564 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
568 //================================================================================
570 * \brief Import data from a GMF file and return an error description
572 //================================================================================
574 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
575 bool theMakeRequiredGroups )
578 SMESH_ComputeErrorPtr error;
581 #define SMESH_CAUGHT error =
584 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
586 _medFileInfo = new SMESH::MedFileInfo();
587 _medFileInfo->fileName = theFileName;
588 _medFileInfo->major = 0;
589 _medFileInfo->minor = 0;
590 _medFileInfo->release = 0;
591 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
593 SMESH_CATCH( exceptionToComputeError );
597 CreateGroupServants();
599 return ConvertComputeError( error );
602 //=============================================================================
604 * \brief Convert SMESH_Hypothesis::Hypothesis_Status into SMESH::Hypothesis_Status
606 //=============================================================================
608 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
610 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
611 (SMESH_Hypothesis::Hypothesis_Status theStatus)
614 RETURNCASE( HYP_OK );
615 RETURNCASE( HYP_MISSING );
616 RETURNCASE( HYP_CONCURRENT );
617 RETURNCASE( HYP_BAD_PARAMETER );
618 RETURNCASE( HYP_HIDDEN_ALGO );
619 RETURNCASE( HYP_HIDING_ALGO );
620 RETURNCASE( HYP_UNKNOWN_FATAL );
621 RETURNCASE( HYP_INCOMPATIBLE );
622 RETURNCASE( HYP_NOTCONFORM );
623 RETURNCASE( HYP_ALREADY_EXIST );
624 RETURNCASE( HYP_BAD_DIM );
625 RETURNCASE( HYP_BAD_SUBSHAPE );
626 RETURNCASE( HYP_BAD_GEOMETRY );
627 RETURNCASE( HYP_NEED_SHAPE );
628 RETURNCASE( HYP_INCOMPAT_HYPS );
631 return SMESH::HYP_UNKNOWN_FATAL;
634 //=============================================================================
638 * Call internal addHypothesis() and then add a reference to <anHyp> under
639 * the SObject actually having a reference to <aSubShape>.
640 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
642 //=============================================================================
644 SMESH::Hypothesis_Status
645 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
646 SMESH::SMESH_Hypothesis_ptr anHyp,
647 CORBA::String_out anErrorText)
650 Unexpect aCatch(SALOME_SalomeException);
652 _preMeshInfo->ForgetOrLoad();
654 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
657 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
658 anErrorText = error.c_str();
660 SMESH::SMESH_Mesh_var mesh( _this() );
661 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
663 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
665 //int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
666 if ( prevNbMeshEnt > 0 /*newNbMeshEnt != prevNbMeshEnt*/ )
667 _gen_i->UpdateIcons( mesh );
669 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
671 // Update Python script
672 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
673 << aSubShape << ", " << anHyp << " )";
675 return ConvertHypothesisStatus(status);
678 //================================================================================
680 * \brief Create a sub-mesh and add a hypothesis to it
682 //================================================================================
684 SMESH_Hypothesis::Hypothesis_Status
685 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
686 SMESH::SMESH_Hypothesis_ptr anHyp,
687 std::string* anErrorText)
689 if(MYDEBUG) MESSAGE("addHypothesis");
691 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
692 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
694 if (CORBA::is_nil( anHyp ))
695 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
697 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
700 TopoDS_Shape myLocSubShape;
701 //use PseudoShape in case if mesh has no shape
703 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
705 myLocSubShape = _impl->GetShapeToMesh();
707 const int hypId = anHyp->GetId();
709 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
710 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
712 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
714 // assure there is a corresponding submesh
715 if ( !_impl->IsMainShape( myLocSubShape )) {
716 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
717 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
718 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
721 else if ( anErrorText )
723 *anErrorText = error;
726 catch(SALOME_Exception & S_ex)
728 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
733 //================================================================================
735 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
737 //================================================================================
739 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
740 SMESH::SMESH_Hypothesis_ptr anHyp)
743 Unexpect aCatch(SALOME_SalomeException);
745 _preMeshInfo->ForgetOrLoad();
747 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
748 SMESH::SMESH_Mesh_var mesh = _this();
750 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
752 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
753 _gen_i->UpdateIcons( mesh );
755 // Update Python script
756 if(_impl->HasShapeToMesh())
757 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
758 << aSubShape << ", " << anHyp << " )";
760 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
763 return ConvertHypothesisStatus(status);
766 //=============================================================================
768 * \brief Un-assign a hypothesis from a sub-mesh dedicate to the given sub-shape
770 //=============================================================================
772 SMESH_Hypothesis::Hypothesis_Status
773 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
774 SMESH::SMESH_Hypothesis_ptr anHyp)
776 if(MYDEBUG) MESSAGE("removeHypothesis()");
778 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
779 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
781 if (CORBA::is_nil( anHyp ))
782 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
785 _preMeshInfo->ForgetOrLoad();
787 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
790 TopoDS_Shape myLocSubShape;
791 //use PseudoShape in case if mesh has no shape
792 if( _impl->HasShapeToMesh() )
793 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
795 myLocSubShape = _impl->GetShapeToMesh();
797 const int hypId = anHyp->GetId();
798 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
799 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
801 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
805 catch(SALOME_Exception & S_ex)
807 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
812 //================================================================================
814 * \brief Return hypotheses assigned to a given sub-shape
816 //================================================================================
818 SMESH::ListOfHypothesis *
819 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
822 Unexpect aCatch(SALOME_SalomeException);
823 if (MYDEBUG) MESSAGE("GetHypothesisList");
824 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
825 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
827 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
830 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
831 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
832 myLocSubShape = _impl->GetShapeToMesh();
833 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
834 int i = 0, n = aLocalList.size();
837 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
838 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
839 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
841 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
842 if ( id_hypptr != _mapHypo.end() )
843 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
847 catch(SALOME_Exception & S_ex) {
848 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
851 return aList._retn();
854 //================================================================================
856 * \brief Return sub-meshes
858 //================================================================================
860 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes()
862 Unexpect aCatch(SALOME_SalomeException);
863 if (MYDEBUG) MESSAGE("GetSubMeshes");
865 SMESH::submesh_array_var aList = new SMESH::submesh_array();
868 TPythonDump aPythonDump;
869 if ( !_mapSubMeshIor.empty() )
873 aList->length( _mapSubMeshIor.size() );
875 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
876 for ( ; it != _mapSubMeshIor.end(); it++ ) {
877 if ( CORBA::is_nil( it->second )) continue;
878 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
880 if (i > 1) aPythonDump << ", ";
881 aPythonDump << it->second;
885 catch(SALOME_Exception & S_ex) {
886 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
889 // Update Python script
890 if ( !_mapSubMeshIor.empty() )
891 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
893 return aList._retn();
896 //================================================================================
898 * \brief Create and return a sub-mesh on the given sub-shape
900 //================================================================================
902 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
903 const char* theName )
906 Unexpect aCatch(SALOME_SalomeException);
907 if (CORBA::is_nil(aSubShape))
908 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
910 SMESH::SMESH_subMesh_var subMesh;
911 SMESH::SMESH_Mesh_var aMesh = _this();
913 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
915 //Get or Create the SMESH_subMesh object implementation
917 TopoDS_Iterator it( myLocSubShape );
918 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
919 bool isValidSub = ( subMeshId || _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ));
920 if ( isValidSub && myLocSubShape.ShapeType() == TopAbs_COMPOUND )
921 isValidSub = !it.Value().IsSame( _impl->GetShapeToMesh() );
925 THROW_SALOME_CORBA_EXCEPTION("Not a sub-shape of the main shape", SALOME::BAD_PARAM);
927 subMesh = getSubMesh( subMeshId );
929 // create a new subMesh object servant if there is none for the shape
930 if ( subMesh->_is_nil() )
931 subMesh = createSubMesh( aSubShape );
932 if ( _gen_i->CanPublishInStudy( subMesh ))
934 SALOMEDS::SObject_wrap aSO =
935 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
936 if ( !aSO->_is_nil()) {
937 // Update Python script
938 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
939 << aSubShape << ", '" << theName << "' )";
943 catch(SALOME_Exception & S_ex) {
944 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
946 return subMesh._retn();
949 //================================================================================
951 * \brief Remove a sub-mesh
953 //================================================================================
955 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
960 if ( theSubMesh->_is_nil() )
963 GEOM::GEOM_Object_var aSubShape;
964 // Remove submesh's SObject
965 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
966 if ( !anSO->_is_nil() ) {
967 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
968 SALOMEDS::SObject_wrap anObj, aRef;
969 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
970 anObj->ReferencedObject( aRef.inout() ))
972 CORBA::Object_var obj = aRef->GetObject();
973 aSubShape = GEOM::GEOM_Object::_narrow( obj );
975 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
976 // aSubShape = theSubMesh->GetSubShape();
978 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
979 builder->RemoveObjectWithChildren( anSO );
981 // Update Python script
982 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
985 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
987 _preMeshInfo->ForgetOrLoad();
989 SMESH_CATCH( SMESH::throwCorbaException );
992 //================================================================================
994 * \brief Create a standalone group
996 //================================================================================
998 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
999 const char* theName )
1002 Unexpect aCatch(SALOME_SalomeException);
1004 _preMeshInfo->FullLoadFromFile();
1006 SMESH::SMESH_Group_var aNewGroup =
1007 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1009 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1011 SMESH::SMESH_Mesh_var mesh = _this();
1012 SALOMEDS::SObject_wrap aSO =
1013 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1014 if ( !aSO->_is_nil())
1015 // Update Python script
1016 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1017 << theElemType << ", '" << theName << "' )";
1019 return aNewGroup._retn();
1022 //================================================================================
1024 * \brief Create a group based on the given geometry
1026 //================================================================================
1028 SMESH::SMESH_GroupOnGeom_ptr
1029 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1030 const char* theName,
1031 GEOM::GEOM_Object_ptr theGeomObj)
1034 Unexpect aCatch(SALOME_SalomeException);
1036 _preMeshInfo->FullLoadFromFile();
1038 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1040 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1041 if ( !aShape.IsNull() )
1044 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1046 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1048 SMESH::SMESH_Mesh_var mesh = _this();
1049 SALOMEDS::SObject_wrap aSO =
1050 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1051 if ( !aSO->_is_nil())
1052 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1053 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1057 return aNewGroup._retn();
1060 //================================================================================
1062 * \brief Creates a group whose contents is defined by filter
1063 * \param theElemType - group type
1064 * \param theName - group name
1065 * \param theFilter - the filter
1066 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1068 //================================================================================
1070 SMESH::SMESH_GroupOnFilter_ptr
1071 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1072 const char* theName,
1073 SMESH::Filter_ptr theFilter )
1076 Unexpect aCatch(SALOME_SalomeException);
1078 _preMeshInfo->FullLoadFromFile();
1080 if ( CORBA::is_nil( theFilter ))
1081 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1083 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1085 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1087 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1088 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1091 if ( !aNewGroup->_is_nil() )
1092 aNewGroup->SetFilter( theFilter );
1094 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1096 SMESH::SMESH_Mesh_var mesh = _this();
1097 SALOMEDS::SObject_wrap aSO =
1098 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1100 if ( !aSO->_is_nil())
1101 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1102 << theElemType << ", '" << theName << "', " << theFilter << " )";
1104 return aNewGroup._retn();
1107 //================================================================================
1109 * \brief Remove a group
1111 //================================================================================
1113 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1116 if ( theGroup->_is_nil() )
1121 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1125 if ( aGroup->GetMeshServant() != this )
1126 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1127 SALOME::BAD_PARAM );
1129 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1130 if ( !aGroupSO->_is_nil() )
1132 // Update Python script
1133 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1135 // Remove group's SObject
1136 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1137 builder->RemoveObjectWithChildren( aGroupSO );
1139 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1141 // Remove the group from SMESH data structures
1142 removeGroup( aGroup->GetLocalID() );
1144 SMESH_CATCH( SMESH::throwCorbaException );
1147 //=============================================================================
1149 * Remove group with its contents
1151 //=============================================================================
1153 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1158 _preMeshInfo->FullLoadFromFile();
1160 if ( theGroup->_is_nil() )
1163 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1164 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1165 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1168 vector<int> nodeIds; // to remove nodes becoming free
1169 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1170 if ( !isNodal && !theGroup->IsEmpty() )
1172 CORBA::Long elemID = theGroup->GetID( 1 );
1173 int nbElemNodes = GetElemNbNodes( elemID );
1174 if ( nbElemNodes > 0 )
1175 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1178 // Retrieve contents
1179 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1180 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1181 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1182 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1183 elems.assign( elemBeg, elemEnd );
1185 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1188 RemoveGroup( theGroup );
1191 for ( size_t i = 0; i < elems.size(); ++i )
1193 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1197 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1198 nodeIds.push_back( nIt->next()->GetID() );
1200 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1204 _impl->GetMeshDS()->RemoveElement( elems[i] );
1208 // Remove free nodes
1209 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1210 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1211 if ( n->NbInverseElements() == 0 )
1212 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1214 // Update Python script (theGroup must be alive for this)
1215 pyDump << SMESH::SMESH_Mesh_var(_this())
1216 << ".RemoveGroupWithContents( " << theGroup << " )";
1218 SMESH_CATCH( SMESH::throwCorbaException );
1221 //================================================================================
1223 * \brief Get the list of groups existing in the mesh
1224 * \retval SMESH::ListOfGroups * - list of groups
1226 //================================================================================
1228 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups()
1230 Unexpect aCatch(SALOME_SalomeException);
1231 if (MYDEBUG) MESSAGE("GetGroups");
1233 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1236 TPythonDump aPythonDump;
1237 if ( !_mapGroups.empty() )
1239 aPythonDump << "[ ";
1241 aList->length( _mapGroups.size() );
1243 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1244 for ( ; it != _mapGroups.end(); it++ ) {
1245 if ( CORBA::is_nil( it->second )) continue;
1246 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1248 if (i > 1) aPythonDump << ", ";
1249 aPythonDump << it->second;
1253 catch(SALOME_Exception & S_ex) {
1254 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1256 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1258 return aList._retn();
1261 //=============================================================================
1263 * Get number of groups existing in the mesh
1265 //=============================================================================
1267 CORBA::Long SMESH_Mesh_i::NbGroups()
1269 Unexpect aCatch(SALOME_SalomeException);
1270 return _mapGroups.size();
1273 //=============================================================================
1275 * New group including all mesh elements present in initial groups is created.
1277 //=============================================================================
1279 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1280 SMESH::SMESH_GroupBase_ptr theGroup2,
1281 const char* theName )
1284 SMESH::SMESH_Group_var aResGrp;
1288 _preMeshInfo->FullLoadFromFile();
1290 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1291 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1293 if ( theGroup1->GetType() != theGroup2->GetType() )
1294 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1299 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1300 if ( aResGrp->_is_nil() )
1301 return SMESH::SMESH_Group::_nil();
1303 aResGrp->AddFrom( theGroup1 );
1304 aResGrp->AddFrom( theGroup2 );
1306 // Update Python script
1307 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1308 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1310 SMESH_CATCH( SMESH::throwCorbaException );
1312 return aResGrp._retn();
1315 //=============================================================================
1317 * \brief New group including all mesh elements present in initial groups is created.
1318 * \param theGroups list of groups
1319 * \param theName name of group to be created
1320 * \return pointer to the new group
1322 //=============================================================================
1324 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1325 const char* theName )
1328 SMESH::SMESH_Group_var aResGrp;
1331 _preMeshInfo->FullLoadFromFile();
1334 return SMESH::SMESH_Group::_nil();
1339 SMESH::ElementType aType = SMESH::ALL;
1340 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1342 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1343 if ( CORBA::is_nil( aGrp ) )
1345 if ( aType == SMESH::ALL )
1346 aType = aGrp->GetType();
1347 else if ( aType != aGrp->GetType() )
1348 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1351 if ( aType == SMESH::ALL )
1352 return SMESH::SMESH_Group::_nil();
1357 aResGrp = CreateGroup( aType, theName );
1358 if ( aResGrp->_is_nil() )
1359 return SMESH::SMESH_Group::_nil();
1361 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1362 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1364 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1365 if ( !CORBA::is_nil( aGrp ) )
1367 aResGrp->AddFrom( aGrp );
1368 if ( g > 0 ) pyDump << ", ";
1372 pyDump << " ], '" << theName << "' )";
1374 SMESH_CATCH( SMESH::throwCorbaException );
1376 return aResGrp._retn();
1379 //=============================================================================
1381 * New group is created. All mesh elements that are
1382 * present in both initial groups are added to the new one.
1384 //=============================================================================
1386 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1387 SMESH::SMESH_GroupBase_ptr theGroup2,
1388 const char* theName )
1391 SMESH::SMESH_Group_var aResGrp;
1396 _preMeshInfo->FullLoadFromFile();
1398 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1399 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1401 if ( theGroup1->GetType() != theGroup2->GetType() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1406 // Create Intersection
1407 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1408 if ( aResGrp->_is_nil() )
1409 return aResGrp._retn();
1411 SMESHDS_GroupBase* groupDS1 = 0;
1412 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1413 groupDS1 = grp_i->GetGroupDS();
1415 SMESHDS_GroupBase* groupDS2 = 0;
1416 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1417 groupDS2 = grp_i->GetGroupDS();
1419 SMESHDS_Group* resGroupDS = 0;
1420 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1421 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1423 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1425 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1426 while ( elemIt1->more() )
1428 const SMDS_MeshElement* e = elemIt1->next();
1429 if ( groupDS2->Contains( e ))
1430 resGroupDS->SMDSGroup().Add( e );
1433 // Update Python script
1434 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1435 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1437 SMESH_CATCH( SMESH::throwCorbaException );
1439 return aResGrp._retn();
1442 //=============================================================================
1444 \brief Intersect list of groups. New group is created. All mesh elements that
1445 are present in all initial groups simultaneously are added to the new one.
1446 \param theGroups list of groups
1447 \param theName name of group to be created
1448 \return pointer on the group
1450 //=============================================================================
1452 SMESH::SMESH_Group_ptr
1453 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1454 const char* theName )
1457 SMESH::SMESH_Group_var aResGrp;
1462 _preMeshInfo->FullLoadFromFile();
1465 return SMESH::SMESH_Group::_nil();
1467 // check types and get SMESHDS_GroupBase's
1468 SMESH::ElementType aType = SMESH::ALL;
1469 vector< SMESHDS_GroupBase* > groupVec;
1470 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1472 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1473 if ( CORBA::is_nil( aGrp ) )
1475 if ( aType == SMESH::ALL )
1476 aType = aGrp->GetType();
1477 else if ( aType != aGrp->GetType() )
1478 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1481 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1482 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1484 if ( grpDS->IsEmpty() )
1489 groupVec.push_back( grpDS );
1492 if ( aType == SMESH::ALL ) // all groups are nil
1493 return SMESH::SMESH_Group::_nil();
1498 aResGrp = CreateGroup( aType, theName );
1500 SMESHDS_Group* resGroupDS = 0;
1501 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1502 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1503 if ( !resGroupDS || groupVec.empty() )
1504 return aResGrp._retn();
1507 size_t i, nb = groupVec.size();
1508 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1509 while ( elemIt1->more() )
1511 const SMDS_MeshElement* e = elemIt1->next();
1513 for ( i = 1; ( i < nb && inAll ); ++i )
1514 inAll = groupVec[i]->Contains( e );
1517 resGroupDS->SMDSGroup().Add( e );
1520 // Update Python script
1521 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1522 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1524 SMESH_CATCH( SMESH::throwCorbaException );
1526 return aResGrp._retn();
1529 //=============================================================================
1531 * New group is created. All mesh elements that are present in
1532 * a main group but is not present in a tool group are added to the new one
1534 //=============================================================================
1536 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1537 SMESH::SMESH_GroupBase_ptr theGroup2,
1538 const char* theName )
1541 SMESH::SMESH_Group_var aResGrp;
1546 _preMeshInfo->FullLoadFromFile();
1548 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1549 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1551 if ( theGroup1->GetType() != theGroup2->GetType() )
1552 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1556 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1557 if ( aResGrp->_is_nil() )
1558 return aResGrp._retn();
1560 SMESHDS_GroupBase* groupDS1 = 0;
1561 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1562 groupDS1 = grp_i->GetGroupDS();
1564 SMESHDS_GroupBase* groupDS2 = 0;
1565 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1566 groupDS2 = grp_i->GetGroupDS();
1568 SMESHDS_Group* resGroupDS = 0;
1569 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1570 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1572 if ( groupDS1 && groupDS2 && resGroupDS )
1574 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1575 while ( elemIt1->more() )
1577 const SMDS_MeshElement* e = elemIt1->next();
1578 if ( !groupDS2->Contains( e ))
1579 resGroupDS->SMDSGroup().Add( e );
1582 // Update Python script
1583 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1584 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1586 SMESH_CATCH( SMESH::throwCorbaException );
1588 return aResGrp._retn();
1591 //=============================================================================
1593 \brief Cut lists of groups. New group is created. All mesh elements that are
1594 present in main groups but do not present in tool groups are added to the new one
1595 \param theMainGroups list of main groups
1596 \param theToolGroups list of tool groups
1597 \param theName name of group to be created
1598 \return pointer on the group
1600 //=============================================================================
1602 SMESH::SMESH_Group_ptr
1603 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1604 const SMESH::ListOfGroups& theToolGroups,
1605 const char* theName )
1608 SMESH::SMESH_Group_var aResGrp;
1613 _preMeshInfo->FullLoadFromFile();
1616 return SMESH::SMESH_Group::_nil();
1618 // check types and get SMESHDS_GroupBase's
1619 SMESH::ElementType aType = SMESH::ALL;
1620 vector< SMESHDS_GroupBase* > toolGroupVec;
1621 vector< SMDS_ElemIteratorPtr > mainIterVec;
1623 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1625 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1626 if ( CORBA::is_nil( aGrp ) )
1628 if ( aType == SMESH::ALL )
1629 aType = aGrp->GetType();
1630 else if ( aType != aGrp->GetType() )
1631 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1633 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1634 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1635 if ( !grpDS->IsEmpty() )
1636 mainIterVec.push_back( grpDS->GetElements() );
1638 if ( aType == SMESH::ALL ) // all main groups are nil
1639 return SMESH::SMESH_Group::_nil();
1640 if ( mainIterVec.empty() ) // all main groups are empty
1641 return aResGrp._retn();
1643 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1645 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1646 if ( CORBA::is_nil( aGrp ) )
1648 if ( aType != aGrp->GetType() )
1649 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1651 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1652 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1653 toolGroupVec.push_back( grpDS );
1659 aResGrp = CreateGroup( aType, theName );
1661 SMESHDS_Group* resGroupDS = 0;
1662 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1663 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1665 return aResGrp._retn();
1668 size_t i, nb = toolGroupVec.size();
1669 SMDS_ElemIteratorPtr mainElemIt
1670 ( new SMDS_IteratorOnIterators
1671 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1672 while ( mainElemIt->more() )
1674 const SMDS_MeshElement* e = mainElemIt->next();
1676 for ( i = 0; ( i < nb && !isIn ); ++i )
1677 isIn = toolGroupVec[i]->Contains( e );
1680 resGroupDS->SMDSGroup().Add( e );
1683 // Update Python script
1684 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1685 << ".CutListOfGroups( " << theMainGroups << ", "
1686 << theToolGroups << ", '" << theName << "' )";
1688 SMESH_CATCH( SMESH::throwCorbaException );
1690 return aResGrp._retn();
1693 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1695 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1696 bool & toStopChecking )
1698 toStopChecking = ( nbCommon < nbChecked );
1699 return nbCommon == nbNodes;
1701 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1702 bool & toStopChecking )
1704 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1705 return nbCommon == nbCorners;
1707 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1708 bool & toStopChecking )
1710 return nbCommon > 0;
1712 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1713 bool & toStopChecking )
1715 return nbCommon >= (nbNodes+1) / 2;
1719 //=============================================================================
1721 * Create a group of entities basing on nodes of other groups.
1722 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1723 * \param [in] anElemType - a type of elements to include to the new group.
1724 * \param [in] theName - a name of the new group.
1725 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1726 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1727 * new group provided that it is based on nodes of an element of \a aListOfGroups
1728 * \return SMESH_Group - the created group
1730 // IMP 19939, bug 22010, IMP 22635
1731 //=============================================================================
1733 SMESH::SMESH_Group_ptr
1734 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1735 SMESH::ElementType theElemType,
1736 const char* theName,
1737 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1738 CORBA::Boolean theUnderlyingOnly)
1741 SMESH::SMESH_Group_var aResGrp;
1745 _preMeshInfo->FullLoadFromFile();
1747 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1749 if ( !theName || !aMeshDS )
1750 return SMESH::SMESH_Group::_nil();
1752 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1754 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1755 SMESH_Comment nbCoNoStr( "SMESH.");
1756 switch ( theNbCommonNodes ) {
1757 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1758 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1759 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1760 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1761 default: return aResGrp._retn();
1763 int nbChecked, nbCommon, nbNodes, nbCorners;
1769 aResGrp = CreateGroup( theElemType, theName );
1770 if ( aResGrp->_is_nil() )
1771 return SMESH::SMESH_Group::_nil();
1773 SMESHDS_GroupBase* groupBaseDS =
1774 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1775 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1777 vector<bool> isNodeInGroups;
1779 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1781 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1782 if ( CORBA::is_nil( aGrp ) )
1784 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1785 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1788 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1789 if ( !elIt ) continue;
1791 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1793 while ( elIt->more() ) {
1794 const SMDS_MeshElement* el = elIt->next();
1795 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1796 while ( nIt->more() )
1797 resGroupCore.Add( nIt->next() );
1800 // get elements of theElemType based on nodes of every element of group
1801 else if ( theUnderlyingOnly )
1803 while ( elIt->more() )
1805 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1806 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1807 TIDSortedElemSet checkedElems;
1808 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1809 while ( nIt->more() )
1811 const SMDS_MeshNode* n = nIt->next();
1812 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1813 // check nodes of elements of theElemType around el
1814 while ( elOfTypeIt->more() )
1816 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1817 if ( !checkedElems.insert( elOfType ).second ) continue;
1818 nbNodes = elOfType->NbNodes();
1819 nbCorners = elOfType->NbCornerNodes();
1821 bool toStopChecking = false;
1822 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1823 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1824 if ( elNodes.count( nIt2->next() ) &&
1825 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1827 resGroupCore.Add( elOfType );
1834 // get all nodes of elements of groups
1837 while ( elIt->more() )
1839 const SMDS_MeshElement* el = elIt->next(); // an element of group
1840 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1841 while ( nIt->more() )
1843 const SMDS_MeshNode* n = nIt->next();
1844 if ( n->GetID() >= (int) isNodeInGroups.size() )
1845 isNodeInGroups.resize( n->GetID() + 1, false );
1846 isNodeInGroups[ n->GetID() ] = true;
1852 // Get elements of theElemType based on a certain number of nodes of elements of groups
1853 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1855 const SMDS_MeshNode* n;
1856 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1857 const int isNodeInGroupsSize = isNodeInGroups.size();
1858 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1860 if ( !isNodeInGroups[ iN ] ||
1861 !( n = aMeshDS->FindNode( iN )))
1864 // check nodes of elements of theElemType around n
1865 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1866 while ( elOfTypeIt->more() )
1868 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1869 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1874 nbNodes = elOfType->NbNodes();
1875 nbCorners = elOfType->NbCornerNodes();
1877 bool toStopChecking = false;
1878 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1879 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1881 const int nID = nIt->next()->GetID();
1882 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1883 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1885 resGroupCore.Add( elOfType );
1893 // Update Python script
1894 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1895 << ".CreateDimGroup( "
1896 << theGroups << ", " << theElemType << ", '" << theName << "', "
1897 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1899 SMESH_CATCH( SMESH::throwCorbaException );
1901 return aResGrp._retn();
1904 //================================================================================
1906 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1907 * existing 1D elements as group boundaries.
1908 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1909 * adjacent faces is more than \a sharpAngle in degrees.
1910 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1911 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1912 * \return ListOfGroups - the created groups
1914 //================================================================================
1916 SMESH::ListOfGroups*
1917 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1918 CORBA::Boolean theCreateEdges,
1919 CORBA::Boolean theUseExistingEdges )
1922 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1923 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1926 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1932 _preMeshInfo->FullLoadFromFile();
1934 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1936 std::vector< SMESH_MeshAlgos::Edge > edges =
1937 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1939 if ( theCreateEdges )
1941 std::vector<const SMDS_MeshNode *> nodes(2);
1942 for ( size_t i = 0; i < edges.size(); ++i )
1944 nodes[0] = edges[i]._node1;
1945 nodes[1] = edges[i]._node2;
1946 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1948 if ( edges[i]._medium )
1949 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1951 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1955 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1956 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1958 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1960 resultGroups->length( faceGroups.size() );
1961 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1963 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1964 _editor->GenerateGroupName("Group").c_str());
1965 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1967 SMESHDS_GroupBase* groupBaseDS =
1968 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1969 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1971 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1972 for ( size_t i = 0; i < faces.size(); ++i )
1973 groupCore.Add( faces[i] );
1976 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1977 << ".FaceGroupsSeparatedByEdges( "
1978 << TVar( theSharpAngle ) << ", "
1979 << theCreateEdges << ", "
1980 << theUseExistingEdges << " )";
1982 SMESH_CATCH( SMESH::throwCorbaException );
1983 return resultGroups._retn();
1987 //================================================================================
1989 * \brief Remember GEOM group data
1991 //================================================================================
1993 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1994 CORBA::Object_ptr theSmeshObj)
1996 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1999 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2000 if ( groupSO->_is_nil() )
2003 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2004 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2005 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2008 _geomGroupData.push_back( TGeomGroupData() );
2009 TGeomGroupData & groupData = _geomGroupData.back();
2011 CORBA::String_var entry = groupSO->GetID();
2012 groupData._groupEntry = entry.in();
2014 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2015 groupData._indices.insert( ids[i] );
2017 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2018 // shape index in SMESHDS
2019 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2020 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2023 //================================================================================
2025 * Remove GEOM group data relating to removed smesh object
2027 //================================================================================
2029 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2031 list<TGeomGroupData>::iterator
2032 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2033 for ( ; data != dataEnd; ++data ) {
2034 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2035 _geomGroupData.erase( data );
2041 //================================================================================
2043 * \brief Replace a shape in the mesh upon Break Link
2045 //================================================================================
2047 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
2050 // check if geometry changed
2051 bool geomChanged = true;
2052 GEOM::GEOM_Object_var oldGeom = GetShapeToMesh();
2053 if ( !theNewGeom->_is_nil() && !oldGeom->_is_nil() )
2054 geomChanged = ( //oldGeom->_is_equivalent( theNewGeom ) ||
2055 oldGeom->GetTick() < theNewGeom->GetTick() );
2057 TopoDS_Shape S = _impl->GetShapeToMesh();
2058 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2059 TCollection_AsciiString aIOR;
2060 CORBA::String_var ior;
2061 if ( geomClient->Find( S, aIOR ))
2062 geomClient->RemoveShapeFromBuffer( aIOR );
2064 // clear buffer also for sub-groups
2065 const std::set<SMESHDS_GroupBase*>& groups = _impl->GetMeshDS()->GetGroups();
2066 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2067 for (; g != groups.end(); ++g)
2068 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
2070 const TopoDS_Shape& s = group->GetShape();
2071 if ( geomClient->Find( s, aIOR ))
2072 geomClient->RemoveShapeFromBuffer( aIOR );
2076 int shapeID, fromID, toID; // indices of elements of a sub-mesh
2078 std::vector< TRange > elemRanges, nodeRanges; // elements of sub-meshes
2079 std::vector< SMDS_PositionPtr > positions; // node positions
2080 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2083 // store positions of elements on geometry
2085 if ( meshDS->MaxNodeID() > meshDS->NbNodes() ||
2086 meshDS->MaxElementID() > meshDS->NbElements() )
2089 meshDS->CompactMesh();
2091 positions.resize( meshDS->NbNodes() + 1 );
2092 for ( SMDS_NodeIteratorPtr nodeIt = meshDS->nodesIterator(); nodeIt->more(); )
2094 const SMDS_MeshNode* n = nodeIt->next();
2095 positions[ n->GetID() ] = n->GetPosition();
2098 // remove elements from sub-meshes to avoid their removal at hypotheses addition
2099 for ( int isNode = 0; isNode < 2; ++isNode )
2101 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2102 ranges.reserve( meshDS->MaxShapeIndex() + 10 );
2103 ranges.push_back( TRange{ 0,0,0 });
2104 SMDS_ElemIteratorPtr elemIt = meshDS->elementsIterator( isNode ? SMDSAbs_Node : SMDSAbs_All );
2105 while ( elemIt->more() )
2107 const SMDS_MeshElement* e = elemIt->next();
2108 const int elemID = e->GetID();
2109 const int shapeID = e->GetShapeID();
2110 TRange & lastRange = ranges.back();
2111 if ( lastRange.shapeID != shapeID ||
2112 lastRange.toID != elemID )
2113 ranges.push_back( TRange{ shapeID, elemID, elemID + 1 });
2115 lastRange.toID = elemID + 1;
2117 if ( SMESHDS_SubMesh* sm = meshDS->MeshElements( shapeID ))
2119 if ( isNode ) sm->RemoveNode( static_cast< const SMDS_MeshNode *>( e ));
2120 else sm->RemoveElement( e );
2127 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
2128 SMESH::SMESH_Mesh_var me = _this();
2129 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
2130 CORBA::String_var entry = theNewGeom->GetStudyEntry();
2131 if ( !aSO->_is_nil() )
2133 SALOMEDS::SObject_wrap aShapeRefSO;
2134 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
2136 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
2137 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2138 builder->Addreference( aShapeRefSO, aShapeSO );
2142 // re-assign global hypotheses to the new shape
2143 _mainShapeTick = geomChanged ? -1 : theNewGeom->GetTick();
2144 CheckGeomModif( true );
2148 // restore positions of elements on geometry
2149 for ( int isNode = 0; isNode < 2; ++isNode )
2151 std::vector< TRange > & ranges = isNode ? nodeRanges : elemRanges;
2152 for ( size_t i = 1; i < ranges.size(); ++i )
2154 int elemID = ranges[ i ].fromID;
2155 int toID = ranges[ i ].toID;
2156 SMESHDS_SubMesh * smDS = meshDS->NewSubMesh( ranges[ i ].shapeID );
2158 for ( ; elemID < toID; ++elemID )
2159 smDS->AddNode( meshDS->FindNode( elemID ));
2161 for ( ; elemID < toID; ++elemID )
2162 smDS->AddElement( meshDS->FindElement( elemID ));
2164 if ( SMESH_subMesh* sm = _impl->GetSubMeshContaining( ranges[ i ].shapeID ))
2165 sm->ComputeStateEngine( SMESH_subMesh::CHECK_COMPUTE_STATE );
2168 for ( unsigned int nodeID = 1; nodeID < positions.size(); ++nodeID )
2169 if ( positions[ nodeID ])
2170 if ( SMDS_MeshNode* n = const_cast< SMDS_MeshNode*>( meshDS->FindNode( nodeID )))
2171 n->SetPosition( positions[ nodeID ], n->GetShapeID() );
2174 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2177 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
2178 << me <<".GetMesh()), " << entry.in() << ")";
2180 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
2184 //================================================================================
2186 * \brief Return new group contents if it has been changed and update group data
2188 //================================================================================
2190 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2192 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2194 TopoDS_Shape newShape;
2195 SALOMEDS::SObject_wrap groupSO;
2197 if ( how == IS_BREAK_LINK )
2199 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2200 SALOMEDS::SObject_wrap geomRefSO;
2201 if ( !meshSO->_is_nil() &&
2202 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ))
2204 geomRefSO->ReferencedObject( groupSO.inout() );
2210 groupSO = _gen_i->getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2213 if ( groupSO->_is_nil() )
2216 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2217 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2218 if ( geomGroup->_is_nil() )
2221 // get indices of group items
2222 set<int> curIndices;
2223 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2224 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2225 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2226 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2227 curIndices.insert( ids[i] );
2229 bool sameIndices = ( groupData._indices == curIndices );
2230 if ( how == ONLY_IF_CHANGED && sameIndices )
2231 return newShape; // group not changed
2234 CORBA::String_var entry = geomGroup->GetStudyEntry();
2235 groupData._groupEntry = entry.in();
2236 groupData._indices = curIndices;
2238 newShape = _gen_i->GeomObjectToShape( geomGroup );
2240 // check if newShape is up-to-date
2241 if ( !newShape.IsNull() && ids->length() > 0 )
2243 bool toUpdate = ! _impl->GetMeshDS()->IsGroupOfSubShapes( newShape );
2246 TopExp_Explorer exp( newShape, (TopAbs_ShapeEnum)( groupOp->GetType( geomGroup )));
2247 for ( ; exp.More() && !toUpdate; exp.Next() )
2249 int ind = _impl->GetMeshDS()->ShapeToIndex( exp.Current() );
2250 toUpdate = ( curIndices.erase( ind ) == 0 );
2252 if ( !curIndices.empty() )
2257 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2258 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2259 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2260 newShape = _gen_i->GeomObjectToShape( geomGroup );
2265 // geom group becomes empty - return empty compound
2266 TopoDS_Compound compound;
2267 BRep_Builder().MakeCompound(compound);
2268 newShape = compound;
2276 //-----------------------------------------------------------------------------
2278 * \brief Storage of shape and index used in CheckGeomGroupModif()
2280 struct TIndexedShape
2283 TopoDS_Shape _shape;
2284 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2286 //-----------------------------------------------------------------------------
2288 * \brief Data to re-create a group on geometry
2290 struct TGroupOnGeomData
2293 TopoDS_Shape _shape;
2294 SMDSAbs_ElementType _type;
2296 Quantity_Color _color;
2298 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2300 _oldID = group->GetID();
2301 _type = group->GetType();
2302 _name = group->GetStoreName();
2303 _color = group->GetColor();
2307 //-----------------------------------------------------------------------------
2309 * \brief Check if a filter is still valid after geometry removal
2311 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2313 if ( theFilter->_is_nil() )
2315 SMESH::Filter::Criteria_var criteria;
2316 theFilter->GetCriteria( criteria.out() );
2318 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2320 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2322 switch ( criteria[ iCr ].Type )
2324 case SMESH::FT_BelongToGeom:
2325 case SMESH::FT_BelongToPlane:
2326 case SMESH::FT_BelongToCylinder:
2327 case SMESH::FT_BelongToGenSurface:
2328 case SMESH::FT_LyingOnGeom:
2329 entry = thresholdID;
2331 case SMESH::FT_ConnectedElements:
2334 entry = thresholdID;
2340 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2341 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2342 if ( so->_is_nil() )
2344 CORBA::Object_var obj = so->GetObject();
2345 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2346 if ( gen->GeomObjectToShape( geom ).IsNull() )
2349 } // loop on criteria
2355 //=============================================================================
2357 * \brief Update data if geometry changes
2361 //=============================================================================
2363 void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink )
2365 SMESH::SMESH_Mesh_var me = _this();
2366 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2368 TPythonDump dumpNothing; // prevent any dump
2370 //bool removedFromClient = false;
2372 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2374 //removedFromClient = _impl->HasShapeToMesh();
2376 // try to find geometry by study reference
2377 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2378 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2379 if ( !meshSO->_is_nil() &&
2380 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2381 geomRefSO->ReferencedObject( geomSO.inout() ))
2383 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2384 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2387 if ( mainGO->_is_nil() && // geometry removed ==>
2388 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2390 // convert geom dependent groups into standalone ones
2391 CheckGeomGroupModif();
2393 _impl->ShapeToMesh( TopoDS_Shape() );
2395 // remove sub-meshes
2396 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2397 while ( i_sm != _mapSubMeshIor.end() )
2399 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2401 RemoveSubMesh( sm );
2403 // remove all children except groups in the study
2404 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2405 SALOMEDS::SObject_wrap so;
2406 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2407 if ( meshSO->FindSubObject( tag, so.inout() ))
2408 builder->RemoveObjectWithChildren( so );
2410 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2416 if ( !_impl->HasShapeToMesh() ) return;
2419 // Update after group modification
2421 const bool geomChanged = ( mainGO->GetTick() != _mainShapeTick );
2422 if ( !theIsBreakLink )
2423 if ( mainGO->GetType() == GEOM_GROUP || !geomChanged ) // is group or not modified
2425 int nb = NbNodes() + NbElements();
2426 CheckGeomGroupModif();
2427 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2428 _gen_i->UpdateIcons( me );
2432 // Update after shape modification or breakLink w/o geometry change
2434 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2435 if ( !geomClient ) return;
2436 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2437 if ( geomGen->_is_nil() ) return;
2438 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2439 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2441 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2443 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2444 if ( meshDS->ShapeToIndex( newShape ) == 1 ) // not yet updated
2446 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2447 geomClient->RemoveShapeFromBuffer( ior.in() );
2448 newShape = _gen_i->GeomObjectToShape( mainGO );
2451 // Update data taking into account that if topology doesn't change
2452 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2455 _preMeshInfo->ForgetAllData();
2457 if ( geomChanged || !isShaper )
2459 if ( newShape.IsNull() )
2462 _mainShapeTick = mainGO->GetTick();
2464 // store data of groups on geometry including new TopoDS_Shape's
2465 std::vector< TGroupOnGeomData > groupsData;
2466 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2467 groupsData.reserve( groups.size() );
2468 TopTools_DataMapOfShapeShape old2newShapeMap;
2469 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2470 for ( ; g != groups.end(); ++g )
2472 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2474 groupsData.push_back( TGroupOnGeomData( group ));
2477 SMESH::SMESH_GroupOnGeom_var gog;
2478 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2479 if ( i_grp != _mapGroups.end() )
2480 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2482 GEOM::GEOM_Object_var geom;
2483 if ( !gog->_is_nil() )
2485 if ( !theIsBreakLink )
2486 geom = gog->GetShape();
2488 if ( theIsBreakLink || geom->_is_nil() )
2490 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2491 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2492 if ( !grpSO->_is_nil() &&
2493 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2494 geomRefSO->ReferencedObject( geomSO.inout() ))
2496 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2497 geom = GEOM::GEOM_Object::_narrow( geomObj );
2501 if ( old2newShapeMap.IsBound( group->GetShape() ))
2503 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2505 else if ( !geom->_is_nil() )
2507 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2508 if ( meshDS->IsGroupOfSubShapes( groupsData.back()._shape ))
2510 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2511 geomClient->RemoveShapeFromBuffer( ior.in() );
2512 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2514 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2519 // store assigned hypotheses
2520 std::vector< pair< int, THypList > > ids2Hyps;
2521 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2522 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2524 const TopoDS_Shape& s = s2hyps.Key();
2525 const THypList& hyps = s2hyps.ChangeValue();
2526 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2529 std::multimap< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2531 // count shapes excluding compounds corresponding to geom groups
2532 int oldNbSubShapes = meshDS->MaxShapeIndex();
2533 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2535 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2536 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2539 std::set<int> subIds;
2540 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2541 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2542 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2545 // check if shape topology changes - save shape type per shape ID
2546 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2547 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2548 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2550 // change shape to mesh
2551 _impl->ShapeToMesh( TopoDS_Shape() );
2552 _impl->ShapeToMesh( newShape );
2554 // check if shape topology changes - check new shape types
2555 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2556 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2558 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2559 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2562 // re-add shapes (compounds) of geom groups
2563 typedef std::map< std::vector< int >, TGeomGroupData* > TIndices2GroupData;
2564 TIndices2GroupData ii2grData;
2565 std::vector< int > ii;
2566 std::map< int, int > old2newIDs; // group IDs
2567 std::list<TGeomGroupData>::iterator dataIt = _geomGroupData.begin();
2568 for ( ; dataIt != _geomGroupData.end(); ++dataIt )
2570 TGeomGroupData* data = &(*dataIt);
2571 ii.reserve( data->_indices.size() );
2572 ii.assign( data->_indices.begin(), data->_indices.end() );
2573 TIndices2GroupData::iterator ii2gd = ii2grData.insert( std::make_pair( ii, data )).first;
2574 if ( ii2gd->second != data )
2576 data->_groupEntry = ii2gd->second->_groupEntry;
2577 data->_indices = ii2gd->second->_indices;
2580 const int oldNbSub = data->_indices.size();
2581 const int soleOldID = oldNbSub == 1 ? *data->_indices.begin() : 0;
2583 std::multimap< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2584 if ( ii2i != ii2iMap.end() )
2586 oldID = ii2i->second;
2587 ii2iMap.erase( ii2i );
2589 if ( !oldID && oldNbSub == 1 )
2591 if ( old2newIDs.count( oldID ))
2594 int how = ( theIsBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2595 newShape = newGroupShape( *data, how );
2597 if ( !newShape.IsNull() )
2599 if ( oldNbSub > 1 && meshDS->ShapeToIndex( newShape ) > 0 ) // group reduced to one sub-shape
2601 TopoDS_Compound compound;
2602 BRep_Builder().MakeCompound( compound );
2603 BRep_Builder().Add( compound, newShape );
2604 newShape = compound;
2606 int newID = _impl->GetSubMesh( newShape )->GetId();
2607 if ( oldID /*&& oldID != newID*/ )
2608 old2newIDs.insert( std::make_pair( oldID, newID ));
2609 if ( oldNbSub == 1 )
2610 old2newIDs.insert( std::make_pair( soleOldID, newID ));
2614 // re-assign hypotheses
2615 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2617 int sID = ids2Hyps[i].first;
2620 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2621 if ( o2n != old2newIDs.end() )
2623 else if ( !sameTopology )
2626 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2629 const THypList& hyps = ids2Hyps[i].second;
2630 THypList::const_iterator h = hyps.begin();
2631 for ( ; h != hyps.end(); ++h )
2632 _impl->AddHypothesis( s, (*h)->GetID() );
2636 // restore groups on geometry
2637 for ( size_t i = 0; i < groupsData.size(); ++i )
2639 const TGroupOnGeomData& data = groupsData[i];
2640 if ( data._shape.IsNull() )
2643 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2644 if ( i2g == _mapGroups.end() ) continue;
2646 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2647 if ( !gr_i ) continue;
2649 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2651 _mapGroups.erase( i2g );
2653 g->GetGroupDS()->SetColor( data._color );
2656 if ( !sameTopology )
2658 std::map< int, int >::iterator o2n = old2newIDs.begin();
2659 for ( ; o2n != old2newIDs.end(); ++o2n )
2661 int newID = o2n->second, oldID = o2n->first;
2662 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2666 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2667 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2668 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2670 _mapSubMesh. erase(oldID);
2671 _mapSubMesh_i. erase(oldID);
2672 _mapSubMeshIor.erase(oldID);
2674 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2678 // update _mapSubMesh
2679 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2680 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2681 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2684 if ( !sameTopology )
2686 // remove invalid study sub-objects
2687 CheckGeomGroupModif();
2690 _gen_i->UpdateIcons( me );
2692 if ( !theIsBreakLink && isShaper )
2694 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2695 if ( !meshSO->_is_nil() )
2696 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2700 //=============================================================================
2702 * \brief Update objects depending on changed geom groups
2704 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2705 * issue 0020210: Update of a smesh group after modification of the associated geom group
2707 //=============================================================================
2709 void SMESH_Mesh_i::CheckGeomGroupModif()
2711 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2712 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2713 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2714 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2715 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2717 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2718 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2719 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2721 int nbValid = 0, nbRemoved = 0;
2722 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2723 for ( ; chItr->More(); chItr->Next() )
2725 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2726 if ( !smSO->_is_nil() &&
2727 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2728 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2730 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2731 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2732 if ( !geom->_non_existent() )
2735 continue; // keep the sub-mesh
2738 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2739 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2740 if ( !sm->_is_nil() && !sm->_non_existent() )
2742 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2743 if ( smGeom->_is_nil() )
2745 RemoveSubMesh( sm );
2752 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2753 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2757 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2758 builder->RemoveObjectWithChildren( rootSO );
2762 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2763 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2764 while ( i_gr != _mapGroups.end())
2766 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2768 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO, geomSO;
2769 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2770 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2771 bool isValidGeom = false;
2772 if ( !onGeom->_is_nil() )
2774 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() ); // check TopoDS
2775 if ( !isValidGeom ) // check reference
2777 isValidGeom = ( ! groupSO->_is_nil() &&
2778 groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ) &&
2779 refSO->ReferencedObject( geomSO.inout() ) &&
2780 ! geomSO->_is_nil() &&
2781 !CORBA::is_nil( CORBA::Object_var( geomSO->GetObject() )));
2784 else if ( !onFilt->_is_nil() )
2786 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2790 isValidGeom = ( !groupSO->_is_nil() &&
2791 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2795 if ( !IsLoaded() || group->IsEmpty() )
2797 RemoveGroup( group );
2799 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2801 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2803 else // is it possible?
2805 builder->RemoveObjectWithChildren( refSO );
2811 if ( !_impl->HasShapeToMesh() ) return;
2813 CORBA::Long nbEntities = NbNodes() + NbElements();
2815 // Check if group contents changed
2817 typedef map< string, TopoDS_Shape > TEntry2Geom;
2818 TEntry2Geom newGroupContents;
2820 list<TGeomGroupData>::iterator
2821 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2822 for ( ; data != dataEnd; ++data )
2824 pair< TEntry2Geom::iterator, bool > it_new =
2825 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2826 bool processedGroup = !it_new.second;
2827 TopoDS_Shape& newShape = it_new.first->second;
2828 if ( !processedGroup )
2829 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2830 if ( newShape.IsNull() )
2831 continue; // no changes
2834 _preMeshInfo->ForgetOrLoad();
2836 if ( processedGroup ) { // update group indices
2837 list<TGeomGroupData>::iterator data2 = data;
2838 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2839 data->_indices = data2->_indices;
2842 // Update SMESH objects according to new GEOM group contents
2844 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2845 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2847 int oldID = submesh->GetId();
2848 if ( !_mapSubMeshIor.count( oldID ))
2850 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2852 // update hypotheses
2853 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2854 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2855 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2857 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2858 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2860 // care of submeshes
2861 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2862 int newID = newSubmesh->GetId();
2863 if ( newID != oldID ) {
2864 _mapSubMesh [ newID ] = newSubmesh;
2865 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2866 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2867 _mapSubMesh. erase(oldID);
2868 _mapSubMesh_i. erase(oldID);
2869 _mapSubMeshIor.erase(oldID);
2870 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2875 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2876 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2877 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2879 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2881 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2882 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2883 ds->SetShape( newShape );
2888 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2889 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2891 // Remove groups and submeshes basing on removed sub-shapes
2893 TopTools_MapOfShape newShapeMap;
2894 TopoDS_Iterator shapeIt( newShape );
2895 for ( ; shapeIt.More(); shapeIt.Next() )
2896 newShapeMap.Add( shapeIt.Value() );
2898 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2899 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2901 if ( newShapeMap.Contains( shapeIt.Value() ))
2903 TopTools_IndexedMapOfShape oldShapeMap;
2904 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2905 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2907 const TopoDS_Shape& oldShape = oldShapeMap(i);
2908 int oldInd = meshDS->ShapeToIndex( oldShape );
2910 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2911 if ( i_smIor != _mapSubMeshIor.end() ) {
2912 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2915 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2916 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2918 // check if a group bases on oldInd shape
2919 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2920 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2921 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2922 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2924 RemoveGroup( i_grp->second ); // several groups can base on same shape
2925 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2930 // Reassign hypotheses and update groups after setting the new shape to mesh
2932 // collect anassigned hypotheses
2933 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2934 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2935 TShapeHypList assignedHyps;
2936 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2938 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2939 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2940 if ( !hyps.empty() ) {
2941 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2942 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2943 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2946 // collect shapes supporting groups
2947 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2948 TShapeTypeList groupData;
2949 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2950 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2951 for ( ; grIt != groups.end(); ++grIt )
2953 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2955 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2957 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2959 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2960 _impl->ShapeToMesh( newShape );
2962 // reassign hypotheses
2963 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2964 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2966 TIndexedShape& geom = indS_hyps->first;
2967 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2968 int oldID = geom._index;
2969 int newID = meshDS->ShapeToIndex( geom._shape );
2970 if ( oldID == 1 ) { // main shape
2972 geom._shape = newShape;
2976 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2977 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2978 // care of sub-meshes
2979 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2980 if ( newID != oldID ) {
2981 _mapSubMesh [ newID ] = newSubmesh;
2982 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2983 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2984 _mapSubMesh. erase(oldID);
2985 _mapSubMesh_i. erase(oldID);
2986 _mapSubMeshIor.erase(oldID);
2987 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2991 TShapeTypeList::iterator geomType = groupData.begin();
2992 for ( ; geomType != groupData.end(); ++geomType )
2994 const TIndexedShape& geom = geomType->first;
2995 int oldID = geom._index;
2996 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2999 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
3000 CORBA::String_var name = groupSO->GetName();
3002 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
3003 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
3004 /*id=*/-1, geom._shape ))
3005 group_i->changeLocalId( group->GetID() );
3008 break; // everything has been updated
3011 } // loop on group data
3015 CORBA::Long newNbEntities = NbNodes() + NbElements();
3016 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
3017 if ( newNbEntities != nbEntities )
3019 // Add all SObjects with icons to soToUpdateIcons
3020 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
3022 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
3023 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
3024 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
3026 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
3027 i_gr != _mapGroups.end(); ++i_gr ) // groups
3028 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
3031 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
3032 for ( ; so != soToUpdateIcons.end(); ++so )
3033 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
3036 //=============================================================================
3038 * \brief Create standalone group from a group on geometry or filter
3040 //=============================================================================
3042 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
3045 SMESH::SMESH_Group_var aGroup;
3050 _preMeshInfo->FullLoadFromFile();
3052 if ( theGroup->_is_nil() )
3053 return aGroup._retn();
3055 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
3057 return aGroup._retn();
3059 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
3061 const int anId = aGroupToRem->GetLocalID();
3062 if ( !_impl->ConvertToStandalone( anId ) )
3063 return aGroup._retn();
3064 removeGeomGroupData( theGroup );
3066 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3068 // remove old instance of group from own map
3069 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
3070 _mapGroups.erase( anId );
3072 SALOMEDS::StudyBuilder_var builder;
3073 SALOMEDS::SObject_wrap aGroupSO;
3074 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3075 if ( !aStudy->_is_nil() ) {
3076 builder = aStudy->NewBuilder();
3077 aGroupSO = _gen_i->ObjectToSObject( theGroup );
3078 if ( !aGroupSO->_is_nil() )
3080 // remove reference to geometry
3081 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
3082 for ( ; chItr->More(); chItr->Next() )
3084 // Remove group's child SObject
3085 SALOMEDS::SObject_wrap so = chItr->Value();
3086 builder->RemoveObject( so );
3088 // Update Python script
3089 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
3090 << ".ConvertToStandalone( " << aGroupSO << " )";
3092 // change icon of Group on Filter
3095 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
3096 // const int isEmpty = ( elemTypes->length() == 0 );
3099 SALOMEDS::GenericAttribute_wrap anAttr =
3100 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
3101 SALOMEDS::AttributePixMap_wrap pm = anAttr;
3102 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
3108 // remember new group in own map
3109 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
3110 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3112 // register CORBA object for persistence
3113 _gen_i->RegisterObject( aGroup );
3115 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
3116 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
3117 //aGroup->Register();
3118 aGroupToRem->UnRegister();
3120 SMESH_CATCH( SMESH::throwCorbaException );
3122 return aGroup._retn();
3125 //================================================================================
3127 * \brief Create a sub-mesh on a given sub-shape
3129 //================================================================================
3131 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
3133 if(MYDEBUG) MESSAGE( "createSubMesh" );
3134 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
3135 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
3138 SMESH_subMesh_i * subMeshServant;
3141 subMeshId = mySubMesh->GetId();
3142 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
3144 else // "invalid sub-mesh"
3146 // The invalid sub-mesh is created for the case where a valid sub-shape not found
3147 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
3148 if ( _mapSubMesh.empty() )
3151 subMeshId = _mapSubMesh.begin()->first - 1;
3152 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
3155 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
3157 _mapSubMesh [subMeshId] = mySubMesh;
3158 _mapSubMesh_i [subMeshId] = subMeshServant;
3159 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
3161 subMeshServant->Register();
3163 // register CORBA object for persistence
3164 int nextId = _gen_i->RegisterObject( subMesh );
3165 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3166 else { nextId = 0; } // avoid "unused variable" warning
3168 // to track changes of GEOM groups
3169 if ( subMeshId > 0 )
3170 addGeomGroupData( theSubShapeObject, subMesh );
3172 return subMesh._retn();
3175 //================================================================================
3177 * \brief Return an existing sub-mesh based on a sub-shape with the given ID
3179 //================================================================================
3181 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3183 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3184 if ( it == _mapSubMeshIor.end() )
3185 return SMESH::SMESH_subMesh::_nil();
3187 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3190 //================================================================================
3192 * \brief Remove a sub-mesh based on the given sub-shape
3194 //================================================================================
3196 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3197 GEOM::GEOM_Object_ptr theSubShapeObject )
3199 bool isHypChanged = false;
3200 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3201 return isHypChanged;
3203 const int subMeshId = theSubMesh->GetId();
3205 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3208 if (( _mapSubMesh.count( subMeshId )) &&
3209 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3211 TopoDS_Shape S = sm->GetSubShape();
3214 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3215 isHypChanged = !hyps.empty();
3216 if ( isHypChanged && _preMeshInfo )
3217 _preMeshInfo->ForgetOrLoad();
3218 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3219 for ( ; hyp != hyps.end(); ++hyp )
3220 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3227 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3228 isHypChanged = ( aHypList->length() > 0 );
3229 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3230 removeHypothesis( theSubShapeObject, aHypList[i] );
3233 catch( const SALOME::SALOME_Exception& ) {
3234 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3236 removeGeomGroupData( theSubShapeObject );
3240 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3241 if ( id_smi != _mapSubMesh_i.end() )
3242 id_smi->second->UnRegister();
3244 // remove a CORBA object
3245 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3246 if ( id_smptr != _mapSubMeshIor.end() )
3247 SMESH::SMESH_subMesh_var( id_smptr->second );
3249 _mapSubMesh.erase(subMeshId);
3250 _mapSubMesh_i.erase(subMeshId);
3251 _mapSubMeshIor.erase(subMeshId);
3253 return isHypChanged;
3256 //================================================================================
3258 * \brief Create a group. Group type depends on given arguments
3260 //================================================================================
3262 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3263 const char* theName,
3265 const TopoDS_Shape& theShape,
3266 const SMESH_PredicatePtr& thePredicate )
3268 std::string newName;
3269 if ( !theName || !theName[0] )
3271 std::set< std::string > presentNames;
3272 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3273 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3275 CORBA::String_var name = i_gr->second->GetName();
3276 presentNames.insert( name.in() );
3279 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3280 } while ( !presentNames.insert( newName ).second );
3281 theName = newName.c_str();
3283 SMESH::SMESH_GroupBase_var aGroup;
3284 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3285 theID, theShape, thePredicate ))
3287 int anId = g->GetID();
3288 SMESH_GroupBase_i* aGroupImpl;
3289 if ( !theShape.IsNull() )
3290 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3291 else if ( thePredicate )
3292 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3294 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3296 aGroup = aGroupImpl->_this();
3297 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3298 aGroupImpl->Register();
3300 // register CORBA object for persistence
3301 int nextId = _gen_i->RegisterObject( aGroup );
3302 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3303 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3305 // to track changes of GEOM groups
3306 if ( !theShape.IsNull() ) {
3307 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3308 addGeomGroupData( geom, aGroup );
3311 return aGroup._retn();
3314 //=============================================================================
3316 * SMESH_Mesh_i::removeGroup
3318 * Should be called by ~SMESH_Group_i()
3320 //=============================================================================
3322 void SMESH_Mesh_i::removeGroup( const int theId )
3324 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3325 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3326 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3327 _mapGroups.erase( theId );
3328 removeGeomGroupData( group );
3329 if ( !_impl->RemoveGroup( theId ))
3331 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3332 RemoveGroup( group );
3334 group->UnRegister();
3338 //================================================================================
3340 * \brief Return a log that can be used to move another mesh to the same state as this one
3342 //================================================================================
3344 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3347 SMESH::log_array_var aLog;
3351 _preMeshInfo->FullLoadFromFile();
3353 list < SMESHDS_Command * >logDS = _impl->GetLog();
3354 aLog = new SMESH::log_array;
3356 int lg = logDS.size();
3358 list < SMESHDS_Command * >::iterator its = logDS.begin();
3359 while(its != logDS.end()){
3360 SMESHDS_Command *com = *its;
3361 int comType = com->GetType();
3362 int lgcom = com->GetNumber();
3363 const list < int >&intList = com->GetIndexes();
3364 int inum = intList.size();
3365 list < int >::const_iterator ii = intList.begin();
3366 const list < double >&coordList = com->GetCoords();
3367 int rnum = coordList.size();
3368 list < double >::const_iterator ir = coordList.begin();
3369 aLog[indexLog].commandType = comType;
3370 aLog[indexLog].number = lgcom;
3371 aLog[indexLog].coords.length(rnum);
3372 aLog[indexLog].indexes.length(inum);
3373 for(int i = 0; i < rnum; i++){
3374 aLog[indexLog].coords[i] = *ir;
3377 for(int i = 0; i < inum; i++){
3378 aLog[indexLog].indexes[i] = *ii;
3387 SMESH_CATCH( SMESH::throwCorbaException );
3389 return aLog._retn();
3392 //================================================================================
3394 * \brief Remove the log of commands
3396 //================================================================================
3398 void SMESH_Mesh_i::ClearLog()
3402 SMESH_CATCH( SMESH::throwCorbaException );
3405 //================================================================================
3407 * \brief Return a mesh ID
3409 //================================================================================
3411 CORBA::Long SMESH_Mesh_i::GetId()
3416 //=============================================================================
3419 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3420 // issue 0020918: groups removal is caused by hyp modification
3421 // issue 0021208: to forget not loaded mesh data at hyp modification
3422 struct TCallUp_i : public SMESH_Mesh::TCallUp
3424 SMESH_Mesh_i* _mesh;
3425 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3426 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3427 virtual void HypothesisModified( int hypID,
3428 bool updIcons) { _mesh->onHypothesisModified( hypID,
3430 virtual void Load () { _mesh->Load(); }
3431 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3435 //================================================================================
3437 * \brief callback from _impl to
3438 * 1) forget not loaded mesh data (issue 0021208)
3439 * 2) mark hypothesis as valid
3441 //================================================================================
3443 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3446 _preMeshInfo->ForgetOrLoad();
3448 if ( theUpdateIcons )
3450 SMESH::SMESH_Mesh_var mesh = _this();
3451 _gen_i->UpdateIcons( mesh );
3454 if ( _nbInvalidHypos != 0 )
3456 // mark a hypothesis as valid after edition
3458 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3459 SALOMEDS::SObject_wrap hypRoot;
3460 if ( !smeshComp->_is_nil() &&
3461 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3463 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3464 for ( ; anIter->More(); anIter->Next() )
3466 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3467 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3468 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3469 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3470 _gen_i->HighLightInvalid( hyp, false );
3472 nbInvalid += _gen_i->IsInvalid( hypSO );
3475 _nbInvalidHypos = nbInvalid;
3479 //================================================================================
3481 * \brief Set mesh implementation
3483 //================================================================================
3485 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3487 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3490 _impl->SetCallUp( new TCallUp_i(this));
3493 //=============================================================================
3495 * Return a mesh implementation
3497 //=============================================================================
3499 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3501 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3505 //=============================================================================
3507 * Return mesh editor
3509 //=============================================================================
3511 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3514 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3518 _preMeshInfo->FullLoadFromFile();
3520 // Create MeshEditor
3522 _editor = new SMESH_MeshEditor_i( this, false );
3523 aMeshEdVar = _editor->_this();
3525 // Update Python script
3526 TPythonDump() << _editor << " = "
3527 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3529 SMESH_CATCH( SMESH::throwCorbaException );
3531 return aMeshEdVar._retn();
3534 //=============================================================================
3536 * Return mesh edition previewer
3538 //=============================================================================
3540 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3543 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3547 _preMeshInfo->FullLoadFromFile();
3549 if ( !_previewEditor )
3550 _previewEditor = new SMESH_MeshEditor_i( this, true );
3551 aMeshEdVar = _previewEditor->_this();
3553 SMESH_CATCH( SMESH::throwCorbaException );
3555 return aMeshEdVar._retn();
3558 //================================================================================
3560 * \brief Return true if the mesh has been edited since a last total re-compute
3561 * and those modifications may prevent successful partial re-compute
3563 //================================================================================
3565 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard()
3567 Unexpect aCatch(SALOME_SalomeException);
3568 return _impl->HasModificationsToDiscard();
3571 //================================================================================
3573 * \brief Return a random unique color
3575 //================================================================================
3577 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3579 const int MAX_ATTEMPTS = 100;
3581 double tolerance = 0.5;
3582 SALOMEDS::Color col;
3586 // generate random color
3587 double red = (double)rand() / RAND_MAX;
3588 double green = (double)rand() / RAND_MAX;
3589 double blue = (double)rand() / RAND_MAX;
3590 // check existence in the list of the existing colors
3591 bool matched = false;
3592 std::list<SALOMEDS::Color>::const_iterator it;
3593 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3594 SALOMEDS::Color color = *it;
3595 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3596 matched = tol < tolerance;
3598 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3599 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3607 //=============================================================================
3609 * Set auto-color mode. If it is on, groups get unique random colors
3611 //=============================================================================
3613 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor)
3615 Unexpect aCatch(SALOME_SalomeException);
3616 _impl->SetAutoColor(theAutoColor);
3618 TPythonDump pyDump; // not to dump group->SetColor() from below code
3619 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3621 std::list<SALOMEDS::Color> aReservedColors;
3622 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3623 for ( ; it != _mapGroups.end(); it++ ) {
3624 if ( CORBA::is_nil( it->second )) continue;
3625 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3626 it->second->SetColor( aColor );
3627 aReservedColors.push_back( aColor );
3631 //=============================================================================
3633 * Return true if auto-color mode is on
3635 //=============================================================================
3637 CORBA::Boolean SMESH_Mesh_i::GetAutoColor()
3639 Unexpect aCatch(SALOME_SalomeException);
3640 return _impl->GetAutoColor();
3643 //=============================================================================
3645 * Check if there are groups with equal names
3647 //=============================================================================
3649 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3651 return _impl->HasDuplicatedGroupNamesMED();
3654 //================================================================================
3656 * \brief Care of a file before exporting mesh into it
3658 //================================================================================
3660 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3662 SMESH_File aFile( file, false );
3664 if ( aFile.exists() ) {
3665 // existing filesystem node
3666 if ( !aFile.isDirectory() ) {
3667 if ( aFile.openForWriting() ) {
3668 if ( overwrite && ! aFile.remove()) {
3669 msg << "Can't replace " << aFile.getName();
3672 msg << "Can't write into " << aFile.getName();
3675 msg << "Location " << aFile.getName() << " is not a file";
3679 // nonexisting file; check if it can be created
3680 if ( !aFile.openForWriting() ) {
3681 msg << "You cannot create the file "
3683 << ". Check the directory existence and access rights";
3691 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3695 //================================================================================
3697 * \brief Prepare a file for export and pass names of mesh groups from study to mesh DS
3698 * \param file - file name
3699 * \param overwrite - to erase the file or not
3700 * \retval string - mesh name
3702 //================================================================================
3704 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3705 CORBA::Boolean overwrite)
3708 PrepareForWriting(file, overwrite);
3709 string aMeshName = "Mesh";
3710 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3711 if ( !aStudy->_is_nil() ) {
3712 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3713 if ( !aMeshSO->_is_nil() ) {
3714 CORBA::String_var name = aMeshSO->GetName();
3716 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3717 if ( !aStudy->GetProperties()->IsLocked() )
3719 SALOMEDS::GenericAttribute_wrap anAttr;
3720 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3721 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3722 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3723 ASSERT(!aFileName->_is_nil());
3724 aFileName->SetValue(file);
3725 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3726 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3727 ASSERT(!aFileType->_is_nil());
3728 aFileType->SetValue("FICHIERMED");
3732 // Update Python script
3733 // set name of mesh before export
3734 TPythonDump() << _gen_i << ".SetName("
3735 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3737 // check names of groups
3743 //================================================================================
3745 * \brief Export to MED file
3747 //================================================================================
3749 void SMESH_Mesh_i::ExportMED(const char* file,
3750 CORBA::Boolean auto_groups,
3751 CORBA::Long version,
3752 CORBA::Boolean overwrite,
3753 CORBA::Boolean autoDimension)
3756 //MESSAGE("MED minor version: "<< minor);
3759 _preMeshInfo->FullLoadFromFile();
3761 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3762 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3764 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3766 << "auto_groups=" <<auto_groups << ", "
3767 << "minor=" << version << ", "
3768 << "overwrite=" << overwrite << ", "
3769 << "meshPart=None, "
3770 << "autoDimension=" << autoDimension << " )";
3772 SMESH_CATCH( SMESH::throwCorbaException );
3775 //================================================================================
3777 * \brief Export a mesh to a SAUV file
3779 //================================================================================
3781 void SMESH_Mesh_i::ExportSAUV (const char* file,
3782 CORBA::Boolean auto_groups)
3785 Unexpect aCatch(SALOME_SalomeException);
3787 _preMeshInfo->FullLoadFromFile();
3789 string aMeshName = prepareMeshNameAndGroups(file, true);
3790 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3791 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3792 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3796 //================================================================================
3798 * \brief Export a mesh to a DAT file
3800 //================================================================================
3802 void SMESH_Mesh_i::ExportDAT (const char *file)
3805 Unexpect aCatch(SALOME_SalomeException);
3807 _preMeshInfo->FullLoadFromFile();
3809 // Update Python script
3810 // check names of groups
3812 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3815 PrepareForWriting(file);
3816 _impl->ExportDAT(file);
3819 //================================================================================
3821 * \brief Export a mesh to an UNV file
3823 //================================================================================
3825 void SMESH_Mesh_i::ExportUNV (const char *file)
3828 Unexpect aCatch(SALOME_SalomeException);
3830 _preMeshInfo->FullLoadFromFile();
3832 // Update Python script
3833 // check names of groups
3835 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3838 PrepareForWriting(file);
3839 _impl->ExportUNV(file);
3842 //================================================================================
3844 * \brief Export a mesh to an STL file
3846 //================================================================================
3848 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3851 Unexpect aCatch(SALOME_SalomeException);
3853 _preMeshInfo->FullLoadFromFile();
3855 // Update Python script
3856 // check names of groups
3858 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3859 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3861 CORBA::String_var name;
3862 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3863 if ( !so->_is_nil() )
3864 name = so->GetName();
3867 PrepareForWriting( file );
3868 _impl->ExportSTL( file, isascii, name.in() );
3871 //================================================================================
3873 * \brief Export a part of mesh to a med file
3875 //================================================================================
3877 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3879 CORBA::Boolean auto_groups,
3880 CORBA::Long version,
3881 CORBA::Boolean overwrite,
3882 CORBA::Boolean autoDimension,
3883 const GEOM::ListOfFields& fields,
3884 const char* geomAssocFields,
3885 CORBA::Double ZTolerance)
3888 MESSAGE("MED version: "<< version);
3891 _preMeshInfo->FullLoadFromFile();
3894 bool have0dField = false;
3895 if ( fields.length() > 0 )
3897 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3898 if ( shapeToMesh->_is_nil() )
3899 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3901 for ( size_t i = 0; i < fields.length(); ++i )
3903 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3904 THROW_SALOME_CORBA_EXCEPTION
3905 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3906 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3907 if ( fieldShape->_is_nil() )
3908 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3909 if ( !fieldShape->IsSame( shapeToMesh ) )
3910 THROW_SALOME_CORBA_EXCEPTION
3911 ( "Field defined not on shape", SALOME::BAD_PARAM);
3912 if ( fields[i]->GetDimension() == 0 )
3915 if ( geomAssocFields )
3916 for ( int i = 0; geomAssocFields[i]; ++i )
3917 switch ( geomAssocFields[i] ) {
3918 case 'v':case 'e':case 'f':case 's': break;
3919 case 'V':case 'E':case 'F':case 'S': break;
3920 default: THROW_SALOME_CORBA_EXCEPTION
3921 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3925 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3929 string aMeshName = "Mesh";
3930 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3931 if ( CORBA::is_nil( meshPart ) ||
3932 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3934 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3935 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3936 0, autoDimension, /*addODOnVertices=*/have0dField,
3938 meshDS = _impl->GetMeshDS();
3943 _preMeshInfo->FullLoadFromFile();
3945 PrepareForWriting(file, overwrite);
3947 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3948 if ( !SO->_is_nil() ) {
3949 CORBA::String_var name = SO->GetName();
3953 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3954 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3955 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3956 meshDS = tmpDSDeleter._obj = partDS;
3961 if ( _impl->HasShapeToMesh() )
3963 DriverMED_W_Field fieldWriter;
3964 fieldWriter.SetFile( file );
3965 fieldWriter.SetMeshName( aMeshName );
3966 fieldWriter.AddODOnVertices( have0dField );
3968 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3972 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3973 goList->length( fields.length() );
3974 for ( size_t i = 0; i < fields.length(); ++i )
3976 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3979 TPythonDump() << _this() << ".ExportPartToMED( "
3980 << meshPart << ", r'"
3982 << auto_groups << ", "
3984 << overwrite << ", "
3985 << autoDimension << ", "
3987 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3988 << TVar( ZTolerance )
3991 SMESH_CATCH( SMESH::throwCorbaException );
3994 //================================================================================
3996 * Write GEOM fields to MED file
3998 //================================================================================
4000 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
4001 SMESHDS_Mesh* meshDS,
4002 const GEOM::ListOfFields& fields,
4003 const char* geomAssocFields)
4005 #define METH "SMESH_Mesh_i::exportMEDFields() "
4007 if (( fields.length() < 1 ) &&
4008 ( !geomAssocFields || !geomAssocFields[0] ))
4011 std::vector< std::vector< double > > dblVals;
4012 std::vector< std::vector< int > > intVals;
4013 std::vector< int > subIdsByDim[ 4 ];
4014 const double noneDblValue = 0.;
4015 const double noneIntValue = 0;
4017 for ( size_t iF = 0; iF < fields.length(); ++iF )
4021 int dim = fields[ iF ]->GetDimension();
4022 SMDSAbs_ElementType elemType;
4023 TopAbs_ShapeEnum shapeType;
4025 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
4026 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
4027 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
4028 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
4030 continue; // skip fields on whole shape
4032 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
4033 if ( dataType == GEOM::FDT_String )
4035 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
4036 if ( stepIDs->length() < 1 )
4038 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
4039 if ( comps->length() < 1 )
4041 CORBA::String_var name = fields[ iF ]->GetName();
4043 if ( !fieldWriter.Set( meshDS,
4047 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
4050 for ( size_t iC = 0; iC < comps->length(); ++iC )
4051 fieldWriter.SetCompName( iC, comps[ iC ].in() );
4053 dblVals.resize( comps->length() );
4054 intVals.resize( comps->length() );
4056 // find sub-shape IDs
4058 std::vector< int >& subIds = subIdsByDim[ dim ];
4059 if ( subIds.empty() )
4060 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
4061 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
4062 subIds.push_back( id );
4066 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4070 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
4072 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
4073 if ( step->_is_nil() )
4076 CORBA::Long stamp = step->GetStamp();
4077 CORBA::Long id = step->GetID();
4078 fieldWriter.SetDtIt( int( stamp ), int( id ));
4080 // fill dblVals or intVals
4081 for ( size_t iC = 0; iC < comps->length(); ++iC )
4082 if ( dataType == GEOM::FDT_Double )
4084 dblVals[ iC ].clear();
4085 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4089 intVals[ iC ].clear();
4090 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
4094 case GEOM::FDT_Double:
4096 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
4097 if ( dblStep->_is_nil() ) continue;
4098 GEOM::ListOfDouble_var vv = dblStep->GetValues();
4099 if ( vv->length() != subIds.size() * comps->length() )
4100 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4101 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4102 for ( size_t iC = 0; iC < comps->length(); ++iC )
4103 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
4108 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
4109 if ( intStep->_is_nil() ) continue;
4110 GEOM::ListOfLong_var vv = intStep->GetValues();
4111 if ( vv->length() != subIds.size() * comps->length() )
4112 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4113 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4114 for ( size_t iC = 0; iC < comps->length(); ++iC )
4115 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4118 case GEOM::FDT_Bool:
4120 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
4121 if ( boolStep->_is_nil() ) continue;
4122 GEOM::short_array_var vv = boolStep->GetValues();
4123 if ( vv->length() != subIds.size() * comps->length() )
4124 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
4125 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
4126 for ( size_t iC = 0; iC < comps->length(); ++iC )
4127 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
4133 // pass values to fieldWriter
4134 elemIt = fieldWriter.GetOrderedElems();
4135 if ( dataType == GEOM::FDT_Double )
4136 while ( elemIt->more() )
4138 const SMDS_MeshElement* e = elemIt->next();
4139 const int shapeID = e->getshapeId();
4140 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
4141 for ( size_t iC = 0; iC < comps->length(); ++iC )
4142 fieldWriter.AddValue( noneDblValue );
4144 for ( size_t iC = 0; iC < comps->length(); ++iC )
4145 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
4148 while ( elemIt->more() )
4150 const SMDS_MeshElement* e = elemIt->next();
4151 const int shapeID = e->getshapeId();
4152 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
4153 for ( size_t iC = 0; iC < comps->length(); ++iC )
4154 fieldWriter.AddValue( (double) noneIntValue );
4156 for ( size_t iC = 0; iC < comps->length(); ++iC )
4157 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4161 fieldWriter.Perform();
4162 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4163 if ( res && res->IsKO() )
4165 if ( res->myComment.empty() )
4166 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4168 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4174 if ( !geomAssocFields || !geomAssocFields[0] )
4177 // write geomAssocFields
4179 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4180 shapeDim[ TopAbs_COMPOUND ] = 3;
4181 shapeDim[ TopAbs_COMPSOLID ] = 3;
4182 shapeDim[ TopAbs_SOLID ] = 3;
4183 shapeDim[ TopAbs_SHELL ] = 2;
4184 shapeDim[ TopAbs_FACE ] = 2;
4185 shapeDim[ TopAbs_WIRE ] = 1;
4186 shapeDim[ TopAbs_EDGE ] = 1;
4187 shapeDim[ TopAbs_VERTEX ] = 0;
4188 shapeDim[ TopAbs_SHAPE ] = 3;
4190 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4192 std::vector< std::string > compNames;
4193 switch ( geomAssocFields[ iF ]) {
4195 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4196 compNames.push_back( "dim" );
4199 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4202 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4205 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4209 compNames.push_back( "id" );
4210 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4211 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4213 fieldWriter.SetDtIt( -1, -1 );
4215 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4219 if ( compNames.size() == 2 ) // _vertices_
4220 while ( elemIt->more() )
4222 const SMDS_MeshElement* e = elemIt->next();
4223 const int shapeID = e->getshapeId();
4226 fieldWriter.AddValue( (double) -1 );
4227 fieldWriter.AddValue( (double) -1 );
4231 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4232 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4233 fieldWriter.AddValue( (double) shapeID );
4237 while ( elemIt->more() )
4239 const SMDS_MeshElement* e = elemIt->next();
4240 const int shapeID = e->getshapeId();
4242 fieldWriter.AddValue( (double) -1 );
4244 fieldWriter.AddValue( (double) shapeID );
4248 fieldWriter.Perform();
4249 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4250 if ( res && res->IsKO() )
4252 if ( res->myComment.empty() )
4253 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4255 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4258 } // loop on geomAssocFields
4263 //================================================================================
4265 * \brief Export a part of mesh to a DAT file
4267 //================================================================================
4269 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4273 Unexpect aCatch(SALOME_SalomeException);
4275 _preMeshInfo->FullLoadFromFile();
4277 PrepareForWriting(file);
4279 SMESH_MeshPartDS partDS( meshPart );
4280 _impl->ExportDAT(file,&partDS);
4282 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4283 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4285 //================================================================================
4287 * \brief Export a part of mesh to an UNV file
4289 //================================================================================
4291 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4295 Unexpect aCatch(SALOME_SalomeException);
4297 _preMeshInfo->FullLoadFromFile();
4299 PrepareForWriting(file);
4301 SMESH_MeshPartDS partDS( meshPart );
4302 _impl->ExportUNV(file, &partDS);
4304 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4305 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4307 //================================================================================
4309 * \brief Export a part of mesh to an STL file
4311 //================================================================================
4313 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4315 ::CORBA::Boolean isascii)
4318 Unexpect aCatch(SALOME_SalomeException);
4320 _preMeshInfo->FullLoadFromFile();
4322 PrepareForWriting(file);
4324 CORBA::String_var name;
4325 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4326 if ( !so->_is_nil() )
4327 name = so->GetName();
4329 SMESH_MeshPartDS partDS( meshPart );
4330 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4332 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4333 << meshPart<< ", r'" << file << "', " << isascii << ")";
4336 //================================================================================
4338 * \brief Export a part of mesh to an STL file
4340 //================================================================================
4342 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4344 CORBA::Boolean overwrite,
4345 CORBA::Boolean groupElemsByType)
4349 Unexpect aCatch(SALOME_SalomeException);
4351 _preMeshInfo->FullLoadFromFile();
4353 PrepareForWriting(file,overwrite);
4355 std::string meshName("");
4356 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4357 if ( !so->_is_nil() )
4359 CORBA::String_var name = so->GetName();
4360 meshName = name.in();
4364 SMESH_MeshPartDS partDS( meshPart );
4365 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4367 SMESH_CATCH( SMESH::throwCorbaException );
4369 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4370 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4372 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4376 //================================================================================
4378 * \brief Export a part of mesh to a GMF file
4380 //================================================================================
4382 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4384 bool withRequiredGroups)
4387 Unexpect aCatch(SALOME_SalomeException);
4389 _preMeshInfo->FullLoadFromFile();
4391 PrepareForWriting(file,/*overwrite=*/true);
4393 SMESH_MeshPartDS partDS( meshPart );
4394 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4396 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4397 << meshPart<< ", r'"
4399 << withRequiredGroups << ")";
4402 //=============================================================================
4404 * Return computation progress [0.,1]
4406 //=============================================================================
4408 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4412 return _impl->GetComputeProgress();
4414 SMESH_CATCH( SMESH::doNothing );
4418 //================================================================================
4420 * \brief Return nb of nodes
4422 //================================================================================
4424 CORBA::Long SMESH_Mesh_i::NbNodes()
4426 Unexpect aCatch(SALOME_SalomeException);
4428 return _preMeshInfo->NbNodes();
4430 return _impl->NbNodes();
4433 //================================================================================
4435 * \brief Return nb of elements
4437 //================================================================================
4439 CORBA::Long SMESH_Mesh_i::NbElements()
4441 Unexpect aCatch(SALOME_SalomeException);
4443 return _preMeshInfo->NbElements();
4445 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4448 //================================================================================
4450 * \brief Return nb of 0D elements
4452 //================================================================================
4454 CORBA::Long SMESH_Mesh_i::Nb0DElements()
4456 Unexpect aCatch(SALOME_SalomeException);
4458 return _preMeshInfo->Nb0DElements();
4460 return _impl->Nb0DElements();
4463 //================================================================================
4465 * \brief Return nb of BALL elements
4467 //================================================================================
4469 CORBA::Long SMESH_Mesh_i::NbBalls()
4471 Unexpect aCatch(SALOME_SalomeException);
4473 return _preMeshInfo->NbBalls();
4475 return _impl->NbBalls();
4478 //================================================================================
4480 * \brief Return nb of 1D elements
4482 //================================================================================
4484 CORBA::Long SMESH_Mesh_i::NbEdges()
4486 Unexpect aCatch(SALOME_SalomeException);
4488 return _preMeshInfo->NbEdges();
4490 return _impl->NbEdges();
4493 //================================================================================
4495 * \brief Return nb of edges
4497 //================================================================================
4499 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4502 Unexpect aCatch(SALOME_SalomeException);
4504 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4506 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4509 //================================================================================
4511 * \brief Return nb of faces
4513 //================================================================================
4515 CORBA::Long SMESH_Mesh_i::NbFaces()
4517 Unexpect aCatch(SALOME_SalomeException);
4519 return _preMeshInfo->NbFaces();
4521 return _impl->NbFaces();
4524 //================================================================================
4526 * \brief Return nb of tringles
4528 //================================================================================
4530 CORBA::Long SMESH_Mesh_i::NbTriangles()
4532 Unexpect aCatch(SALOME_SalomeException);
4534 return _preMeshInfo->NbTriangles();
4536 return _impl->NbTriangles();
4539 //================================================================================
4541 * \brief Return nb of bi-quadratic triangles
4543 //================================================================================
4545 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()
4547 Unexpect aCatch(SALOME_SalomeException);
4549 return _preMeshInfo->NbBiQuadTriangles();
4551 return _impl->NbBiQuadTriangles();
4554 CORBA::Long SMESH_Mesh_i::NbQuadrangles()
4556 Unexpect aCatch(SALOME_SalomeException);
4558 return _preMeshInfo->NbQuadrangles();
4560 return _impl->NbQuadrangles();
4563 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()
4565 Unexpect aCatch(SALOME_SalomeException);
4567 return _preMeshInfo->NbBiQuadQuadrangles();
4569 return _impl->NbBiQuadQuadrangles();
4572 CORBA::Long SMESH_Mesh_i::NbPolygons()
4574 Unexpect aCatch(SALOME_SalomeException);
4576 return _preMeshInfo->NbPolygons();
4578 return _impl->NbPolygons();
4581 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order)
4583 Unexpect aCatch(SALOME_SalomeException);
4585 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4587 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4590 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4593 Unexpect aCatch(SALOME_SalomeException);
4595 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4597 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4600 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4603 Unexpect aCatch(SALOME_SalomeException);
4605 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4607 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4610 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4613 Unexpect aCatch(SALOME_SalomeException);
4615 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4617 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4620 //=============================================================================
4622 CORBA::Long SMESH_Mesh_i::NbVolumes()
4624 Unexpect aCatch(SALOME_SalomeException);
4626 return _preMeshInfo->NbVolumes();
4628 return _impl->NbVolumes();
4631 CORBA::Long SMESH_Mesh_i::NbTetras()
4633 Unexpect aCatch(SALOME_SalomeException);
4635 return _preMeshInfo->NbTetras();
4637 return _impl->NbTetras();
4640 CORBA::Long SMESH_Mesh_i::NbHexas()
4642 Unexpect aCatch(SALOME_SalomeException);
4644 return _preMeshInfo->NbHexas();
4646 return _impl->NbHexas();
4649 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()
4651 Unexpect aCatch(SALOME_SalomeException);
4653 return _preMeshInfo->NbTriQuadHexas();
4655 return _impl->NbTriQuadraticHexas();
4658 CORBA::Long SMESH_Mesh_i::NbPyramids()
4660 Unexpect aCatch(SALOME_SalomeException);
4662 return _preMeshInfo->NbPyramids();
4664 return _impl->NbPyramids();
4667 CORBA::Long SMESH_Mesh_i::NbPrisms()
4669 Unexpect aCatch(SALOME_SalomeException);
4671 return _preMeshInfo->NbPrisms();
4673 return _impl->NbPrisms();
4676 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()
4678 Unexpect aCatch(SALOME_SalomeException);
4680 return _preMeshInfo->NbHexPrisms();
4682 return _impl->NbHexagonalPrisms();
4685 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()
4687 Unexpect aCatch(SALOME_SalomeException);
4689 return _preMeshInfo->NbPolyhedrons();
4691 return _impl->NbPolyhedrons();
4694 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4697 Unexpect aCatch(SALOME_SalomeException);
4699 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4701 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4704 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4707 Unexpect aCatch(SALOME_SalomeException);
4709 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4711 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4714 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4717 Unexpect aCatch(SALOME_SalomeException);
4719 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4721 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4724 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4727 Unexpect aCatch(SALOME_SalomeException);
4729 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4731 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4734 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4737 Unexpect aCatch(SALOME_SalomeException);
4739 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4741 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4744 //=============================================================================
4746 * Return nb of published sub-meshes
4748 //=============================================================================
4750 CORBA::Long SMESH_Mesh_i::NbSubMesh()
4752 Unexpect aCatch(SALOME_SalomeException);
4753 return _mapSubMesh_i.size();
4756 //=============================================================================
4758 * Dumps mesh into a string
4760 //=============================================================================
4762 char* SMESH_Mesh_i::Dump()
4766 return CORBA::string_dup( os.str().c_str() );
4769 //=============================================================================
4771 * Method of SMESH_IDSource interface
4773 //=============================================================================
4775 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4777 return GetElementsId();
4780 //=============================================================================
4782 * Return ids of all elements
4784 //=============================================================================
4786 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4789 Unexpect aCatch(SALOME_SalomeException);
4791 _preMeshInfo->FullLoadFromFile();
4793 SMESH::long_array_var aResult = new SMESH::long_array();
4794 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4796 if ( aSMESHDS_Mesh == NULL )
4797 return aResult._retn();
4799 long nbElements = NbElements();
4800 aResult->length( nbElements );
4801 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4802 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4803 aResult[i] = anIt->next()->GetID();
4805 return aResult._retn();
4809 //=============================================================================
4811 * Return ids of all elements of given type
4813 //=============================================================================
4815 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4818 Unexpect aCatch(SALOME_SalomeException);
4820 _preMeshInfo->FullLoadFromFile();
4822 SMESH::long_array_var aResult = new SMESH::long_array();
4823 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4825 if ( aSMESHDS_Mesh == NULL )
4826 return aResult._retn();
4828 long nbElements = NbElements();
4830 // No sense in returning ids of elements along with ids of nodes:
4831 // when theElemType == SMESH::ALL, return node ids only if
4832 // there are no elements
4833 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4834 return GetNodesId();
4836 aResult->length( nbElements );
4840 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4841 while ( i < nbElements && anIt->more() )
4842 aResult[i++] = anIt->next()->GetID();
4844 aResult->length( i );
4846 return aResult._retn();
4849 //=============================================================================
4851 * Return ids of all nodes
4853 //=============================================================================
4855 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4858 Unexpect aCatch(SALOME_SalomeException);
4860 _preMeshInfo->FullLoadFromFile();
4862 SMESH::long_array_var aResult = new SMESH::long_array();
4863 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4865 if ( aMeshDS == NULL )
4866 return aResult._retn();
4868 long nbNodes = NbNodes();
4869 aResult->length( nbNodes );
4870 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4871 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4872 aResult[i] = anIt->next()->GetID();
4874 return aResult._retn();
4877 //=============================================================================
4879 * Return type of the given element
4881 //=============================================================================
4883 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4886 SMESH::ElementType type = SMESH::ALL;
4890 _preMeshInfo->FullLoadFromFile();
4892 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4894 SMESH_CATCH( SMESH::throwCorbaException );
4899 //=============================================================================
4901 * Return geometric type of the given element
4903 //=============================================================================
4905 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4909 _preMeshInfo->FullLoadFromFile();
4911 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4913 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4915 return ( SMESH::EntityType ) e->GetEntityType();
4918 //=============================================================================
4920 * Return type of the given element
4922 //=============================================================================
4924 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4928 _preMeshInfo->FullLoadFromFile();
4930 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4932 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4934 return ( SMESH::GeometryType ) e->GetGeomType();
4937 //=============================================================================
4939 * Return ID of elements for given submesh
4941 //=============================================================================
4943 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4946 SMESH::long_array_var aResult = new SMESH::long_array();
4950 _preMeshInfo->FullLoadFromFile();
4952 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4953 if(!SM) return aResult._retn();
4955 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4956 if(!SDSM) return aResult._retn();
4958 aResult->length(SDSM->NbElements());
4960 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4962 while ( eIt->more() ) {
4963 aResult[i++] = eIt->next()->GetID();
4966 SMESH_CATCH( SMESH::throwCorbaException );
4968 return aResult._retn();
4971 //=============================================================================
4973 * Return ID of nodes for given sub-mesh
4974 * If param all==true - return all nodes, else -
4975 * Return only nodes on shapes.
4977 //=============================================================================
4979 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4983 SMESH::long_array_var aResult = new SMESH::long_array();
4987 _preMeshInfo->FullLoadFromFile();
4989 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4990 if(!SM) return aResult._retn();
4992 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4993 if(!SDSM) return aResult._retn();
4996 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4997 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4998 while ( nIt->more() ) {
4999 const SMDS_MeshNode* elem = nIt->next();
5000 theElems.insert( elem->GetID() );
5003 else { // all nodes of submesh elements
5004 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5005 while ( eIt->more() ) {
5006 const SMDS_MeshElement* anElem = eIt->next();
5007 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
5008 while ( nIt->more() ) {
5009 const SMDS_MeshElement* elem = nIt->next();
5010 theElems.insert( elem->GetID() );
5015 aResult->length(theElems.size());
5016 set<int>::iterator itElem;
5018 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
5019 aResult[i++] = *itElem;
5021 SMESH_CATCH( SMESH::throwCorbaException );
5023 return aResult._retn();
5026 //=============================================================================
5028 * Return type of elements for given sub-mesh
5030 //=============================================================================
5032 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
5035 SMESH::ElementType type = SMESH::ALL;
5039 _preMeshInfo->FullLoadFromFile();
5041 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
5042 if(!SM) return SMESH::ALL;
5044 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
5045 if(!SDSM) return SMESH::ALL;
5047 if(SDSM->NbElements()==0)
5048 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
5050 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
5051 const SMDS_MeshElement* anElem = eIt->next();
5053 type = ( SMESH::ElementType ) anElem->GetType();
5055 SMESH_CATCH( SMESH::throwCorbaException );
5061 //=============================================================================
5063 * Return pointer to _impl as an integer value. Is called from constructor of SMESH_Client
5065 //=============================================================================
5067 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
5070 _preMeshInfo->FullLoadFromFile();
5072 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
5073 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
5078 //=============================================================================
5080 * Get XYZ coordinates of node as list of double
5081 * If there is not node for given ID - return empty list
5083 //=============================================================================
5085 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
5088 _preMeshInfo->FullLoadFromFile();
5090 SMESH::double_array_var aResult = new SMESH::double_array();
5091 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5092 if ( aMeshDS == NULL )
5093 return aResult._retn();
5096 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5098 return aResult._retn();
5102 aResult[0] = aNode->X();
5103 aResult[1] = aNode->Y();
5104 aResult[2] = aNode->Z();
5105 return aResult._retn();
5109 //=============================================================================
5111 * For given node return list of IDs of inverse elements
5112 * If there is not node for given ID - return empty list
5114 //=============================================================================
5116 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
5117 SMESH::ElementType elemType)
5120 _preMeshInfo->FullLoadFromFile();
5122 SMESH::long_array_var aResult = new SMESH::long_array();
5123 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5124 if ( aMeshDS == NULL )
5125 return aResult._retn();
5128 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
5130 return aResult._retn();
5132 // find inverse elements
5133 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
5134 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
5135 aResult->length( aNode->NbInverseElements( type ));
5136 for( int i = 0; eIt->more(); ++i )
5138 const SMDS_MeshElement* elem = eIt->next();
5139 aResult[ i ] = elem->GetID();
5141 return aResult._retn();
5144 //=============================================================================
5146 * \brief Return position of a node on shape
5148 //=============================================================================
5150 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
5153 _preMeshInfo->FullLoadFromFile();
5155 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
5156 aNodePosition->shapeID = 0;
5157 aNodePosition->shapeType = GEOM::SHAPE;
5159 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5160 if ( !mesh ) return aNodePosition;
5162 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
5164 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
5166 aNodePosition->shapeID = aNode->getshapeId();
5167 switch ( pos->GetTypeOfPosition() ) {
5169 aNodePosition->shapeType = GEOM::EDGE;
5170 aNodePosition->params.length(1);
5171 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
5173 case SMDS_TOP_FACE: {
5174 SMDS_FacePositionPtr fPos = pos;
5175 aNodePosition->shapeType = GEOM::FACE;
5176 aNodePosition->params.length(2);
5177 aNodePosition->params[0] = fPos->GetUParameter();
5178 aNodePosition->params[1] = fPos->GetVParameter();
5181 case SMDS_TOP_VERTEX:
5182 aNodePosition->shapeType = GEOM::VERTEX;
5184 case SMDS_TOP_3DSPACE:
5185 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
5186 aNodePosition->shapeType = GEOM::SOLID;
5187 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
5188 aNodePosition->shapeType = GEOM::SHELL;
5194 return aNodePosition;
5197 //=============================================================================
5199 * \brief Return position of an element on shape
5201 //=============================================================================
5203 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
5206 _preMeshInfo->FullLoadFromFile();
5208 SMESH::ElementPosition anElementPosition;
5209 anElementPosition.shapeID = 0;
5210 anElementPosition.shapeType = GEOM::SHAPE;
5212 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5213 if ( !mesh ) return anElementPosition;
5215 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5217 anElementPosition.shapeID = anElem->getshapeId();
5218 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5219 if ( !aSp.IsNull() ) {
5220 switch ( aSp.ShapeType() ) {
5222 anElementPosition.shapeType = GEOM::EDGE;
5225 anElementPosition.shapeType = GEOM::FACE;
5228 anElementPosition.shapeType = GEOM::VERTEX;
5231 anElementPosition.shapeType = GEOM::SOLID;
5234 anElementPosition.shapeType = GEOM::SHELL;
5240 return anElementPosition;
5243 //=============================================================================
5245 * If given element is node return IDs of shape from position
5246 * If there is not node for given ID - return -1
5248 //=============================================================================
5250 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5253 _preMeshInfo->FullLoadFromFile();
5255 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5256 if ( aMeshDS == NULL )
5260 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5262 return aNode->getshapeId();
5269 //=============================================================================
5271 * For given element return ID of result shape after
5272 * ::FindShape() from SMESH_MeshEditor
5273 * If there is not element for given ID - return -1
5275 //=============================================================================
5277 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5280 _preMeshInfo->FullLoadFromFile();
5282 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5283 if ( aMeshDS == NULL )
5286 // try to find element
5287 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5291 ::SMESH_MeshEditor aMeshEditor(_impl);
5292 int index = aMeshEditor.FindShape( elem );
5300 //=============================================================================
5302 * Return number of nodes for given element
5303 * If there is not element for given ID - return -1
5305 //=============================================================================
5307 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5310 _preMeshInfo->FullLoadFromFile();
5312 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5313 if ( aMeshDS == NULL ) return -1;
5314 // try to find element
5315 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5316 if(!elem) return -1;
5317 return elem->NbNodes();
5321 //=============================================================================
5323 * Return ID of node by given index for given element
5324 * If there is not element for given ID - return -1
5325 * If there is not node for given index - return -2
5327 //=============================================================================
5329 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5332 _preMeshInfo->FullLoadFromFile();
5334 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5335 if ( aMeshDS == NULL ) return -1;
5336 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5337 if(!elem) return -1;
5338 if( index>=elem->NbNodes() || index<0 ) return -1;
5339 return elem->GetNode(index)->GetID();
5342 //=============================================================================
5344 * Return IDs of nodes of given element
5346 //=============================================================================
5348 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5351 _preMeshInfo->FullLoadFromFile();
5353 SMESH::long_array_var aResult = new SMESH::long_array();
5354 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5356 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5358 aResult->length( elem->NbNodes() );
5359 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5360 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5361 aResult[ i ] = n->GetID();
5364 return aResult._retn();
5367 //=============================================================================
5369 * Return true if given node is medium node
5370 * in given quadratic element
5372 //=============================================================================
5374 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5377 _preMeshInfo->FullLoadFromFile();
5379 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5380 if ( aMeshDS == NULL ) return false;
5382 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5383 if(!aNode) return false;
5384 // try to find element
5385 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5386 if(!elem) return false;
5388 return elem->IsMediumNode(aNode);
5392 //=============================================================================
5394 * Return true if given node is medium node
5395 * in one of quadratic elements
5397 //=============================================================================
5399 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5400 SMESH::ElementType theElemType)
5403 _preMeshInfo->FullLoadFromFile();
5405 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5406 if ( aMeshDS == NULL ) return false;
5409 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5410 if(!aNode) return false;
5412 SMESH_MesherHelper aHelper( *(_impl) );
5414 SMDSAbs_ElementType aType;
5415 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5416 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5417 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5418 else aType = SMDSAbs_All;
5420 return aHelper.IsMedium(aNode,aType);
5424 //=============================================================================
5426 * Return number of edges for given element
5428 //=============================================================================
5430 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5433 _preMeshInfo->FullLoadFromFile();
5435 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5436 if ( aMeshDS == NULL ) return -1;
5437 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5438 if(!elem) return -1;
5439 return elem->NbEdges();
5443 //=============================================================================
5445 * Return number of faces for given element
5447 //=============================================================================
5449 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5452 _preMeshInfo->FullLoadFromFile();
5454 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5455 if ( aMeshDS == NULL ) return -1;
5456 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5457 if(!elem) return -1;
5458 return elem->NbFaces();
5461 //================================================================================
5463 * \brief Return nodes of given face (counted from zero) for given element.
5465 //================================================================================
5467 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5468 CORBA::Short faceIndex)
5471 _preMeshInfo->FullLoadFromFile();
5473 SMESH::long_array_var aResult = new SMESH::long_array();
5474 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5476 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5478 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5479 if ( faceIndex < vtool.NbFaces() )
5481 aResult->length( vtool.NbFaceNodes( faceIndex ));
5482 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5483 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5484 aResult[ i ] = nn[ i ]->GetID();
5488 return aResult._retn();
5491 //================================================================================
5493 * \brief Return three components of normal of given mesh face.
5495 //================================================================================
5497 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5498 CORBA::Boolean normalized)
5501 _preMeshInfo->FullLoadFromFile();
5503 SMESH::double_array_var aResult = new SMESH::double_array();
5505 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5508 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5510 aResult->length( 3 );
5511 aResult[ 0 ] = normal.X();
5512 aResult[ 1 ] = normal.Y();
5513 aResult[ 2 ] = normal.Z();
5516 return aResult._retn();
5519 //================================================================================
5521 * \brief Return an element based on all given nodes.
5523 //================================================================================
5525 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5528 _preMeshInfo->FullLoadFromFile();
5530 CORBA::Long elemID(0);
5531 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5533 vector< const SMDS_MeshNode * > nn( nodes.length() );
5534 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5535 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5538 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5539 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5540 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5541 _impl->NbVolumes( ORDER_QUADRATIC )))
5542 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5544 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5549 //================================================================================
5551 * \brief Return elements including all given nodes.
5553 //================================================================================
5555 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5556 SMESH::ElementType elemType)
5559 _preMeshInfo->FullLoadFromFile();
5561 SMESH::long_array_var result = new SMESH::long_array();
5563 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5565 vector< const SMDS_MeshNode * > nn( nodes.length() );
5566 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5567 nn[i] = mesh->FindNode( nodes[i] );
5569 std::vector<const SMDS_MeshElement *> elems;
5570 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5571 result->length( elems.size() );
5572 for ( size_t i = 0; i < elems.size(); ++i )
5573 result[i] = elems[i]->GetID();
5575 return result._retn();
5578 //=============================================================================
5580 * Return true if given element is polygon
5582 //=============================================================================
5584 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5587 _preMeshInfo->FullLoadFromFile();
5589 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5590 if ( aMeshDS == NULL ) return false;
5591 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5592 if(!elem) return false;
5593 return elem->IsPoly();
5597 //=============================================================================
5599 * Return true if given element is quadratic
5601 //=============================================================================
5603 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5606 _preMeshInfo->FullLoadFromFile();
5608 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5609 if ( aMeshDS == NULL ) return false;
5610 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5611 if(!elem) return false;
5612 return elem->IsQuadratic();
5615 //=============================================================================
5617 * Return diameter of ball discrete element or zero in case of an invalid \a id
5619 //=============================================================================
5621 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5624 _preMeshInfo->FullLoadFromFile();
5626 if ( const SMDS_BallElement* ball =
5627 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5628 return ball->GetDiameter();
5633 //=============================================================================
5635 * Return bary center for given element
5637 //=============================================================================
5639 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5642 _preMeshInfo->FullLoadFromFile();
5644 SMESH::double_array_var aResult = new SMESH::double_array();
5645 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5646 if ( aMeshDS == NULL )
5647 return aResult._retn();
5649 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5651 return aResult._retn();
5653 if(elem->GetType()==SMDSAbs_Volume) {
5654 SMDS_VolumeTool aTool;
5655 if(aTool.Set(elem)) {
5657 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5662 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5664 double x=0., y=0., z=0.;
5665 for(; anIt->more(); ) {
5667 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5681 return aResult._retn();
5684 //================================================================================
5686 * \brief Create a group of elements preventing computation of a sub-shape
5688 //================================================================================
5690 SMESH::ListOfGroups*
5691 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5692 const char* theGroupName )
5695 Unexpect aCatch(SALOME_SalomeException);
5697 if ( !theGroupName || strlen( theGroupName) == 0 )
5698 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5700 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5701 ::SMESH_MeshEditor::ElemFeatures elemType;
5703 // submesh by subshape id
5704 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5705 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5708 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5709 if ( error && error->HasBadElems() )
5711 // sort bad elements by type
5712 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5713 const list<const SMDS_MeshElement*>& badElems =
5714 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5715 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5716 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5717 for ( ; elemIt != elemEnd; ++elemIt )
5719 const SMDS_MeshElement* elem = *elemIt;
5720 if ( !elem ) continue;
5722 if ( elem->GetID() < 1 )
5724 // elem is a temporary element, make a real element
5725 vector< const SMDS_MeshNode* > nodes;
5726 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5727 while ( nIt->more() && elem )
5729 nodes.push_back( nIt->next() );
5730 if ( nodes.back()->GetID() < 1 )
5731 elem = 0; // a temporary element on temporary nodes
5735 ::SMESH_MeshEditor editor( _impl );
5736 elem = editor.AddElement( nodes, elemType.Init( elem ));
5740 elemsByType[ elem->GetType() ].push_back( elem );
5743 // how many groups to create?
5745 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5746 nbTypes += int( !elemsByType[ i ].empty() );
5747 groups->length( nbTypes );
5750 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5752 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5753 if ( elems.empty() ) continue;
5755 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5756 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5758 SMESH::SMESH_Mesh_var mesh = _this();
5759 SALOMEDS::SObject_wrap aSO =
5760 _gen_i->PublishGroup( mesh, groups[ iG ],
5761 GEOM::GEOM_Object::_nil(), theGroupName);
5763 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5764 if ( !grp_i ) continue;
5766 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5767 for ( size_t iE = 0; iE < elems.size(); ++iE )
5768 grpDS->SMDSGroup().Add( elems[ iE ]);
5773 return groups._retn();
5776 //=============================================================================
5778 * Create and publish group servants if any groups were imported or created anyhow
5780 //=============================================================================
5782 void SMESH_Mesh_i::CreateGroupServants()
5784 SMESH::SMESH_Mesh_var aMesh = _this();
5787 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5788 while ( groupIt->more() )
5790 ::SMESH_Group* group = groupIt->next();
5791 int anId = group->GetID();
5793 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5794 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5796 addedIDs.insert( anId );
5798 SMESH_GroupBase_i* aGroupImpl;
5800 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5801 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5803 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5804 shape = groupOnGeom->GetShape();
5807 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5810 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5811 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5812 aGroupImpl->Register();
5814 // register CORBA object for persistence
5815 int nextId = _gen_i->RegisterObject( groupVar );
5816 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5817 else { nextId = 0; } // avoid "unused variable" warning in release mode
5819 // publishing the groups in the study
5820 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5821 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5824 if ( !addedIDs.empty() )
5827 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
5828 for ( int index = 0; i_grp != _mapGroups.end(); ++index, ++i_grp )
5830 set<int>::iterator it = addedIDs.find( i_grp->first );
5831 if ( it != addedIDs.end() )
5833 TPythonDump() << i_grp->second << " = " << aMesh << ".GetGroups()[ "<< index << " ]";
5834 addedIDs.erase( it );
5835 if ( addedIDs.empty() )
5842 //=============================================================================
5844 * \brief Return true if all sub-meshes are computed OK - to update an icon
5846 //=============================================================================
5848 bool SMESH_Mesh_i::IsComputedOK()
5850 return _impl->IsComputedOK();
5853 //=============================================================================
5855 * \brief Return groups cantained in _mapGroups by their IDs
5857 //=============================================================================
5859 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5861 int nbGroups = groupIDs.size();
5862 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5863 aList->length( nbGroups );
5865 list<int>::const_iterator ids = groupIDs.begin();
5866 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5868 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5869 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5870 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5872 aList->length( nbGroups );
5873 return aList._retn();
5876 //=============================================================================
5878 * \brief Return information about imported file
5880 //=============================================================================
5882 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5884 SMESH::MedFileInfo_var res( _medFileInfo );
5885 if ( !res.operator->() ) {
5886 res = new SMESH::MedFileInfo;
5888 res->fileSize = res->major = res->minor = res->release = -1;
5893 //=======================================================================
5894 //function : FileInfoToString
5895 //purpose : Persistence of file info
5896 //=======================================================================
5898 std::string SMESH_Mesh_i::FileInfoToString()
5901 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5903 s = SMESH_Comment( _medFileInfo->fileSize )
5904 << " " << _medFileInfo->major
5905 << " " << _medFileInfo->minor
5906 << " " << _medFileInfo->release
5907 << " " << _medFileInfo->fileName;
5912 //=======================================================================
5913 //function : FileInfoFromString
5914 //purpose : Persistence of file info
5915 //=======================================================================
5917 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5919 std::string size, major, minor, release, fileName;
5920 std::istringstream is(info);
5921 is >> size >> major >> minor >> release;
5922 fileName = info.data() + ( size.size() + 1 +
5925 release.size()+ 1 );
5927 _medFileInfo = new SMESH::MedFileInfo();
5928 _medFileInfo->fileName = fileName.c_str();
5929 _medFileInfo->fileSize = atoi( size.c_str() );
5930 _medFileInfo->major = atoi( major.c_str() );
5931 _medFileInfo->minor = atoi( minor.c_str() );
5932 _medFileInfo->release = atoi( release.c_str() );
5935 //=============================================================================
5937 * \brief Pass names of mesh groups from study to mesh DS
5939 //=============================================================================
5941 void SMESH_Mesh_i::checkGroupNames()
5943 int nbGrp = NbGroups();
5947 SMESH::ListOfGroups* grpList = 0;
5948 // avoid dump of "GetGroups"
5950 // store python dump into a local variable inside local scope
5951 SMESH::TPythonDump pDump; // do not delete this line of code
5952 grpList = GetGroups();
5955 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5956 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5959 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5960 if ( aGrpSO->_is_nil() )
5962 // correct name of the mesh group if necessary
5963 const char* guiName = aGrpSO->GetName();
5964 if ( strcmp(guiName, aGrp->GetName()) )
5965 aGrp->SetName( guiName );
5969 //=============================================================================
5971 * \brief Set list of notebook variables used for Mesh operations separated by ":" symbol
5973 //=============================================================================
5974 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5976 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5980 //=============================================================================
5982 * \brief Return list of notebook variables used for Mesh operations separated by ":" symbol
5984 //=============================================================================
5986 char* SMESH_Mesh_i::GetParameters()
5988 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5991 //=============================================================================
5993 * \brief Return list of notebook variables used for last Mesh operation
5995 //=============================================================================
5996 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5998 SMESH::string_array_var aResult = new SMESH::string_array();
5999 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
6001 CORBA::String_var aParameters = GetParameters();
6002 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
6003 if ( aSections->length() > 0 ) {
6004 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
6005 aResult->length( aVars.length() );
6006 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
6007 aResult[i] = CORBA::string_dup( aVars[i] );
6010 return aResult._retn();
6013 //================================================================================
6015 * \brief Return types of elements it contains
6017 //================================================================================
6019 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
6022 return _preMeshInfo->GetTypes();
6024 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
6028 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
6029 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
6030 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
6031 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
6032 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
6033 if (_impl->NbNodes() &&
6034 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
6035 types->length( nbTypes );
6037 return types._retn();
6040 //================================================================================
6042 * \brief Return self
6044 //================================================================================
6046 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
6048 return SMESH::SMESH_Mesh::_duplicate( _this() );
6051 //================================================================================
6053 * \brief Return false if GetMeshInfo() return incorrect information that may
6054 * happen if mesh data is not yet fully loaded from the file of study.
6058 //================================================================================
6060 bool SMESH_Mesh_i::IsMeshInfoCorrect()
6062 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
6065 //=============================================================================
6067 * \brief Return number of mesh elements per each \a EntityType
6069 //=============================================================================
6071 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
6074 return _preMeshInfo->GetMeshInfo();
6076 SMESH::long_array_var aRes = new SMESH::long_array();
6077 aRes->length(SMESH::Entity_Last);
6078 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6080 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6082 return aRes._retn();
6083 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
6084 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
6085 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
6086 return aRes._retn();
6089 //=============================================================================
6091 * \brief Return number of mesh elements per each \a ElementType
6093 //=============================================================================
6095 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
6097 SMESH::long_array_var aRes = new SMESH::long_array();
6098 aRes->length(SMESH::NB_ELEMENT_TYPES);
6099 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6102 const SMDS_MeshInfo* meshInfo = 0;
6104 meshInfo = _preMeshInfo;
6105 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
6106 meshInfo = & meshDS->GetMeshInfo();
6109 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
6110 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
6112 return aRes._retn();
6115 //=============================================================================
6117 * Collect statistic of mesh elements given by iterator
6119 //=============================================================================
6121 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
6122 SMESH::long_array& theInfo)
6124 if (!theItr) return;
6125 while (theItr->more())
6126 theInfo[ theItr->next()->GetEntityType() ]++;
6128 //=============================================================================
6130 * Return mesh unstructed grid information.
6132 //=============================================================================
6134 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
6136 SALOMEDS::TMPFile_var SeqFile;
6137 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
6138 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
6140 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
6141 aWriter->WriteToOutputStringOn();
6142 aWriter->SetInputData(aGrid);
6143 aWriter->SetFileTypeToBinary();
6145 char* str = aWriter->GetOutputString();
6146 int size = aWriter->GetOutputStringLength();
6148 //Allocate octet buffer of required size
6149 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
6150 //Copy ostrstream content to the octet buffer
6151 memcpy(OctetBuf, str, size);
6152 //Create and return TMPFile
6153 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
6157 return SeqFile._retn();
6160 //=============================================================================
6161 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
6162 * SMESH::ElementType type) */
6164 using namespace SMESH::Controls;
6165 //-----------------------------------------------------------------------------
6166 struct PredicateIterator : public SMDS_ElemIterator
6168 SMDS_ElemIteratorPtr _elemIter;
6169 PredicatePtr _predicate;
6170 const SMDS_MeshElement* _elem;
6171 SMDSAbs_ElementType _type;
6173 PredicateIterator( SMDS_ElemIteratorPtr iterator,
6174 PredicatePtr predicate,
6175 SMDSAbs_ElementType type):
6176 _elemIter(iterator), _predicate(predicate), _type(type)
6184 virtual const SMDS_MeshElement* next()
6186 const SMDS_MeshElement* res = _elem;
6188 while ( _elemIter->more() && !_elem )
6190 if ((_elem = _elemIter->next()) &&
6191 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
6192 ( !_predicate->IsSatisfy( _elem->GetID() ))))
6199 //-----------------------------------------------------------------------------
6200 struct IDSourceIterator : public SMDS_ElemIterator
6202 const CORBA::Long* _idPtr;
6203 const CORBA::Long* _idEndPtr;
6204 SMESH::long_array_var _idArray;
6205 const SMDS_Mesh* _mesh;
6206 const SMDSAbs_ElementType _type;
6207 const SMDS_MeshElement* _elem;
6209 IDSourceIterator( const SMDS_Mesh* mesh,
6210 const CORBA::Long* ids,
6212 SMDSAbs_ElementType type):
6213 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
6215 if ( _idPtr && nbIds && _mesh )
6218 IDSourceIterator( const SMDS_Mesh* mesh,
6219 SMESH::long_array* idArray,
6220 SMDSAbs_ElementType type):
6221 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
6223 if ( idArray && _mesh )
6225 _idPtr = &_idArray[0];
6226 _idEndPtr = _idPtr + _idArray->length();
6234 virtual const SMDS_MeshElement* next()
6236 const SMDS_MeshElement* res = _elem;
6238 while ( _idPtr < _idEndPtr && !_elem )
6240 if ( _type == SMDSAbs_Node )
6242 _elem = _mesh->FindNode( *_idPtr++ );
6244 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6245 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6253 //-----------------------------------------------------------------------------
6255 struct NodeOfElemIterator : public SMDS_ElemIterator
6257 TColStd_MapOfInteger _checkedNodeIDs;
6258 SMDS_ElemIteratorPtr _elemIter;
6259 SMDS_ElemIteratorPtr _nodeIter;
6260 const SMDS_MeshElement* _node;
6262 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6264 if ( _elemIter && _elemIter->more() )
6266 _nodeIter = _elemIter->next()->nodesIterator();
6274 virtual const SMDS_MeshElement* next()
6276 const SMDS_MeshElement* res = _node;
6278 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6280 if ( _nodeIter->more() )
6282 _node = _nodeIter->next();
6283 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6288 _nodeIter = _elemIter->next()->nodesIterator();
6296 //=============================================================================
6298 * Return iterator on elements of given type in given object
6300 //=============================================================================
6302 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6303 SMESH::ElementType theType)
6305 SMDS_ElemIteratorPtr elemIt;
6306 bool typeOK = ( theType == SMESH::ALL );
6307 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6309 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6310 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6311 if ( !mesh_i ) return elemIt;
6312 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6314 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6316 elemIt = meshDS->elementsIterator( elemType );
6319 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6321 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6324 elemIt = sm->GetElements();
6325 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6327 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6328 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6332 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6334 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6335 if ( groupDS && ( elemType == groupDS->GetType() ||
6336 elemType == SMDSAbs_Node ||
6337 elemType == SMDSAbs_All ))
6339 elemIt = groupDS->GetElements();
6340 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6343 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6345 if ( filter_i->GetElementType() == theType ||
6346 filter_i->GetElementType() == SMESH::ALL ||
6347 elemType == SMDSAbs_Node ||
6348 elemType == SMDSAbs_All)
6350 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6351 if ( pred_i && pred_i->GetPredicate() )
6353 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6354 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6355 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6356 elemIt = SMDS_ElemIteratorPtr
6357 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6358 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6364 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6365 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6366 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6368 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6369 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6372 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6373 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6377 SMESH::long_array_var ids = theObject->GetIDs();
6378 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6380 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6383 if ( elemIt && elemIt->more() && !typeOK )
6385 if ( elemType == SMDSAbs_Node )
6387 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6391 elemIt = SMDS_ElemIteratorPtr();
6397 //=============================================================================
6398 namespace // Finding concurrent hypotheses
6399 //=============================================================================
6403 * \brief mapping of mesh dimension into shape type
6405 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6407 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6409 case 0: aType = TopAbs_VERTEX; break;
6410 case 1: aType = TopAbs_EDGE; break;
6411 case 2: aType = TopAbs_FACE; break;
6413 default:aType = TopAbs_SOLID; break;
6418 //-----------------------------------------------------------------------------
6420 * \brief Internal structure used to find concurrent submeshes
6422 * It represents a pair < submesh, concurrent dimension >, where
6423 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6424 * with another submesh. In other words, it is dimension of a hypothesis assigned
6431 int _dim; //!< a dimension the algo can build (concurrent dimension)
6432 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6433 TopTools_MapOfShape _shapeMap; //!< [sub-]shapes of dimension == _dim
6434 const SMESH_subMesh* _subMesh;
6435 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6437 //-----------------------------------------------------------------------------
6438 // Return the algorithm
6439 const SMESH_Algo* GetAlgo() const
6440 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6442 //-----------------------------------------------------------------------------
6444 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6446 const TopoDS_Shape& theShape)
6448 _subMesh = theSubMesh;
6449 SetShape( theDim, theShape );
6452 //-----------------------------------------------------------------------------
6454 void SetShape(const int theDim,
6455 const TopoDS_Shape& theShape)
6458 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6459 if (_dim >= _ownDim)
6460 _shapeMap.Add( theShape );
6462 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6463 for( ; anExp.More(); anExp.Next() )
6464 _shapeMap.Add( anExp.Current() );
6468 //-----------------------------------------------------------------------------
6469 //! Check sharing of sub-shapes
6470 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6471 const TopTools_MapOfShape& theToFind,
6472 const TopAbs_ShapeEnum theType)
6474 bool isShared = false;
6475 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6476 for (; !isShared && anItr.More(); anItr.Next() )
6478 const TopoDS_Shape aSubSh = anItr.Key();
6479 // check for case when concurrent dimensions are same
6480 isShared = theToFind.Contains( aSubSh );
6481 // check for sub-shape with concurrent dimension
6482 TopExp_Explorer anExp( aSubSh, theType );
6483 for ( ; !isShared && anExp.More(); anExp.Next() )
6484 isShared = theToFind.Contains( anExp.Current() );
6489 //-----------------------------------------------------------------------------
6490 //! check algorithms
6491 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6492 const SMESHDS_Hypothesis* theA2)
6494 if ( !theA1 || !theA2 ||
6495 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6496 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6497 return false; // one of the hypothesis is not algorithm
6498 // check algorithm names (should be equal)
6499 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6503 //-----------------------------------------------------------------------------
6504 //! Check if sub-shape hypotheses are concurrent
6505 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6507 if ( _subMesh == theOther->_subMesh )
6508 return false; // same sub-shape - should not be
6510 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6511 // any of the two submeshes is not on COMPOUND shape )
6512 // -> no concurrency
6513 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6514 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6515 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6516 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6517 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6520 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6521 if ( !checkSubShape )
6524 // check algorithms to be same
6525 const SMESH_Algo* a1 = this->GetAlgo();
6526 const SMESH_Algo* a2 = theOther->GetAlgo();
6527 bool isSame = checkAlgo( a1, a2 );
6531 // commented off for IPAL54678
6532 // if ( !a1 || !a2 )
6533 // return false; // pb?
6534 // return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6537 // check hypothesises for concurrence (skip first as algorithm)
6539 // pointers should be same, because it is referened from mesh hypothesis partition
6540 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6541 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6542 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6543 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6545 // the submeshes are concurrent if their algorithms has different parameters
6546 return nbSame != theOther->_hypotheses.size() - 1;
6549 // Return true if algorithm of this SMESH_DimHyp is used if no
6550 // sub-mesh order is imposed by the user
6551 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6553 // NeedDiscreteBoundary() algo has a higher priority
6554 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6555 theOther->GetAlgo()->NeedDiscreteBoundary() )
6556 return !this->GetAlgo()->NeedDiscreteBoundary();
6558 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6561 }; // end of SMESH_DimHyp
6562 //-----------------------------------------------------------------------------
6564 typedef list<const SMESH_DimHyp*> TDimHypList;
6566 //-----------------------------------------------------------------------------
6568 void addDimHypInstance(const int theDim,
6569 const TopoDS_Shape& theShape,
6570 const SMESH_Algo* theAlgo,
6571 const SMESH_subMesh* theSubMesh,
6572 const list <const SMESHDS_Hypothesis*>& theHypList,
6573 TDimHypList* theDimHypListArr )
6575 if ( !theAlgo->NeedDiscreteBoundary() &&
6576 theAlgo->NeedLowerHyps( theDim )) // IPAL54678
6578 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6579 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh )
6581 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6582 dimHyp->_hypotheses.push_front(theAlgo);
6583 listOfdimHyp.push_back( dimHyp );
6586 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6587 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6588 theHypList.begin(), theHypList.end() );
6591 //-----------------------------------------------------------------------------
6592 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6593 TDimHypList& theListOfConcurr)
6595 if ( theListOfConcurr.empty() )
6597 theListOfConcurr.push_back( theDimHyp );
6601 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6602 while ( hypIt != theListOfConcurr.end() &&
6603 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6605 theListOfConcurr.insert( hypIt, theDimHyp );
6609 //-----------------------------------------------------------------------------
6610 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6611 const TDimHypList& theListOfDimHyp,
6612 TDimHypList& theListOfConcurrHyp,
6613 set<int>& theSetOfConcurrId )
6615 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6616 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6618 const SMESH_DimHyp* curDimHyp = *rIt;
6619 if ( curDimHyp == theDimHyp )
6620 break; // meet own dimHyp pointer in same dimension
6622 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6623 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6625 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6630 //-----------------------------------------------------------------------------
6631 void unionLists(TListOfInt& theListOfId,
6632 TListOfListOfInt& theListOfListOfId,
6635 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6636 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ )
6639 continue; //skip already treated lists
6640 // check if other list has any same submesh object
6641 TListOfInt& otherListOfId = *it;
6642 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6643 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6646 // union two lists (from source into target)
6647 TListOfInt::iterator it2 = otherListOfId.begin();
6648 for ( ; it2 != otherListOfId.end(); it2++ ) {
6649 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6650 theListOfId.push_back(*it2);
6652 // clear source list
6653 otherListOfId.clear();
6656 //-----------------------------------------------------------------------------
6658 //! free memory allocated for dimension-hypothesis objects
6659 void removeDimHyps( TDimHypList* theArrOfList )
6661 for (int i = 0; i < 4; i++ ) {
6662 TDimHypList& listOfdimHyp = theArrOfList[i];
6663 TDimHypList::const_iterator it = listOfdimHyp.begin();
6664 for ( ; it != listOfdimHyp.end(); it++ )
6669 //-----------------------------------------------------------------------------
6671 * \brief find common submeshes with given submesh
6672 * \param theSubMeshList list of already collected submesh to check
6673 * \param theSubMesh given submesh to intersect with other
6674 * \param theCommonSubMeshes collected common submeshes
6676 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6677 const SMESH_subMesh* theSubMesh,
6678 set<const SMESH_subMesh*>& theCommon )
6682 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6683 for ( ; it != theSubMeshList.end(); it++ )
6684 theSubMesh->FindIntersection( *it, theCommon );
6685 theSubMeshList.push_back( theSubMesh );
6686 //theCommon.insert( theSubMesh );
6689 //-----------------------------------------------------------------------------
6690 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6692 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6693 for ( ; listsIt != smLists.end(); ++listsIt )
6695 const TListOfInt& smIDs = *listsIt;
6696 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6704 //=============================================================================
6706 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6708 //=============================================================================
6710 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6712 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6713 if ( isSubMeshInList( submeshID, anOrder ))
6716 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6717 return isSubMeshInList( submeshID, allConurrent );
6720 //=============================================================================
6722 * \brief Return sub-mesh objects list in meshing order
6724 //=============================================================================
6726 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6728 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6730 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6732 return aResult._retn();
6734 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6735 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6736 anOrder.splice( anOrder.end(), allConurrent );
6739 TListOfListOfInt::iterator listIt = anOrder.begin();
6740 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6741 unionLists( *listIt, anOrder, listIndx + 1 );
6743 // convert submesh ids into interface instances
6744 // and dump command into python
6745 convertMeshOrder( anOrder, aResult, false );
6747 return aResult._retn();
6750 //=============================================================================
6752 * \brief Finds concurrent sub-meshes
6754 //=============================================================================
6756 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6758 TListOfListOfInt anOrder;
6759 ::SMESH_Mesh& mesh = GetImpl();
6761 // collect submeshes and detect concurrent algorithms and hypothesises
6762 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6764 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6765 for ( ; i_sm != _mapSubMesh.end(); i_sm++ )
6767 ::SMESH_subMesh* sm = (*i_sm).second;
6769 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6771 // list of assigned hypothesises
6772 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6773 // Find out dimensions where the submesh can be concurrent.
6774 // We define the dimensions by algo of each of hypotheses in hypList
6775 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6776 for( ; hypIt != hypList.end(); hypIt++ )
6778 SMESH_Algo* anAlgo = 0;
6779 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6780 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6781 // hyp it-self is algo
6782 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6784 // try to find algorithm with help of sub-shapes
6785 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6786 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6787 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6790 continue; // no algorithm assigned to a current submesh
6792 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6793 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary()
6794 // and !anAlgo->NeedLowerHyps( dim ))
6796 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6797 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6798 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6800 } // end iterations on submesh
6802 // iterate on created dimension-hypotheses and check for concurrents
6803 for ( int i = 0; i < 4; i++ )
6805 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6806 // check for concurrents in own and other dimensions (step-by-step)
6807 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6808 for ( ; dhIt != listOfDimHyp.end(); dhIt++ )
6810 const SMESH_DimHyp* dimHyp = *dhIt;
6811 TDimHypList listOfConcurr;
6812 set<int> setOfConcurrIds;
6813 // looking for concurrents and collect into own list
6814 for ( int j = i; j < 4; j++ )
6815 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6816 // check if any concurrents found
6817 if ( listOfConcurr.size() > 0 )
6819 // add own submesh to list of concurrent
6820 addInOrderOfPriority( dimHyp, listOfConcurr );
6821 list<int> listOfConcurrIds;
6822 TDimHypList::iterator hypIt = listOfConcurr.begin();
6823 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6824 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6825 anOrder.push_back( listOfConcurrIds );
6830 removeDimHyps(dimHypListArr);
6832 // now, minimize the number of concurrent groups
6833 // Here we assume that lists of submeshes can have same submesh
6834 // in case of multi-dimension algorithms, as result
6835 // list with common submesh has to be united into one list
6837 TListOfListOfInt::iterator listIt = anOrder.begin();
6838 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6839 unionLists( *listIt, anOrder, listIndx + 1 );
6844 //=============================================================================
6846 * \brief Set submesh object order
6847 * \param theSubMeshArray submesh array order
6849 //=============================================================================
6851 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6854 _preMeshInfo->ForgetOrLoad();
6857 ::SMESH_Mesh& mesh = GetImpl();
6859 TPythonDump aPythonDump; // prevent dump of called methods
6860 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6862 TListOfListOfInt subMeshOrder;
6863 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6865 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6866 TListOfInt subMeshIds;
6868 aPythonDump << ", ";
6869 aPythonDump << "[ ";
6870 // Collect subMeshes which should be clear
6871 // do it list-by-list, because modification of submesh order
6872 // take effect between concurrent submeshes only
6873 set<const SMESH_subMesh*> subMeshToClear;
6874 list<const SMESH_subMesh*> subMeshList;
6875 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6877 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6879 aPythonDump << ", ";
6880 aPythonDump << subMesh;
6881 subMeshIds.push_back( subMesh->GetId() );
6882 // detect common parts of submeshes
6883 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6884 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6886 aPythonDump << " ]";
6887 subMeshOrder.push_back( subMeshIds );
6889 // clear collected sub-meshes
6890 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6891 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6892 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6894 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6895 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6896 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6899 aPythonDump << " ])";
6901 mesh.SetMeshOrder( subMeshOrder );
6904 SMESH::SMESH_Mesh_var me = _this();
6905 _gen_i->UpdateIcons( me );
6910 //=============================================================================
6912 * \brief Convert submesh ids into submesh interfaces
6914 //=============================================================================
6916 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6917 SMESH::submesh_array_array& theResOrder,
6918 const bool theIsDump)
6920 int nbSet = theIdsOrder.size();
6921 TPythonDump aPythonDump; // prevent dump of called methods
6923 aPythonDump << "[ ";
6924 theResOrder.length(nbSet);
6925 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6927 for( ; it != theIdsOrder.end(); it++ )
6929 // translate submesh identificators into submesh objects
6930 // takeing into account real number of concurrent lists
6931 const TListOfInt& aSubOrder = (*it);
6932 if (!aSubOrder.size())
6935 aPythonDump << "[ ";
6936 // convert shape indices into interfaces
6937 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6938 aResSubSet->length(aSubOrder.size());
6939 TListOfInt::const_iterator subIt = aSubOrder.begin();
6941 for( j = 0; subIt != aSubOrder.end(); subIt++ )
6943 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6945 SMESH::SMESH_subMesh_var subMesh =
6946 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6949 aPythonDump << ", ";
6950 aPythonDump << subMesh;
6952 aResSubSet[ j++ ] = subMesh;
6955 aPythonDump << " ]";
6957 theResOrder[ listIndx++ ] = aResSubSet;
6959 // correct number of lists
6960 theResOrder.length( listIndx );
6963 // finilise python dump
6964 aPythonDump << " ]";
6965 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6969 namespace // utils used by SMESH_MeshPartDS
6972 * \brief Class used to access to protected data of SMDS_MeshInfo
6974 struct TMeshInfo : public SMDS_MeshInfo
6976 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6979 * \brief Element holing its ID only
6981 struct TElemID : public SMDS_LinearEdge
6983 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6987 //================================================================================
6989 // Implementation of SMESH_MeshPartDS
6991 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6992 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6994 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6995 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6998 _meshDS = mesh_i->GetImpl().GetMeshDS();
7000 SetPersistentId( _meshDS->GetPersistentId() );
7002 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
7004 // <meshPart> is the whole mesh
7005 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
7007 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
7008 myGroupSet = _meshDS->GetGroups();
7013 SMESH::long_array_var anIDs = meshPart->GetIDs();
7014 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
7015 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
7017 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7018 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
7019 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7024 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
7025 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
7026 if ( _elements[ e->GetType() ].insert( e ).second )
7029 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7030 while ( nIt->more() )
7032 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7033 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7040 ShapeToMesh( _meshDS->ShapeToMesh() );
7042 _meshDS = 0; // to enforce iteration on _elements and _nodes
7045 // -------------------------------------------------------------------------------------
7046 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
7047 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
7050 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
7051 for ( ; partIt != meshPart.end(); ++partIt )
7052 if ( const SMDS_MeshElement * e = *partIt )
7053 if ( _elements[ e->GetType() ].insert( e ).second )
7056 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
7057 while ( nIt->more() )
7059 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
7060 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
7066 // -------------------------------------------------------------------------------------
7067 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
7069 if ( _meshDS ) return _meshDS->FindElement( IDelem );
7071 TElemID elem( IDelem );
7072 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7073 if ( !_elements[ iType ].empty() )
7075 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
7076 if ( it != _elements[ iType ].end() )
7081 // -------------------------------------------------------------------------------------
7082 bool SMESH_MeshPartDS::HasNumerationHoles()
7084 if ( _meshDS ) return _meshDS->HasNumerationHoles();
7086 return ( MinNodeID() != 1 ||
7087 MaxNodeID() != NbNodes() ||
7088 MinElementID() != 1 ||
7089 MaxElementID() != NbElements() );
7091 // -------------------------------------------------------------------------------------
7092 int SMESH_MeshPartDS::MaxNodeID() const
7094 if ( _meshDS ) return _meshDS->MaxNodeID();
7095 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
7097 // -------------------------------------------------------------------------------------
7098 int SMESH_MeshPartDS::MinNodeID() const
7100 if ( _meshDS ) return _meshDS->MinNodeID();
7101 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
7103 // -------------------------------------------------------------------------------------
7104 int SMESH_MeshPartDS::MaxElementID() const
7106 if ( _meshDS ) return _meshDS->MaxElementID();
7108 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7109 if ( !_elements[ iType ].empty() )
7110 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
7113 // -------------------------------------------------------------------------------------
7114 int SMESH_MeshPartDS::MinElementID() const
7116 if ( _meshDS ) return _meshDS->MinElementID();
7118 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
7119 if ( !_elements[ iType ].empty() )
7120 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
7123 // -------------------------------------------------------------------------------------
7124 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
7126 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
7128 typedef SMDS_SetIterator
7129 <const SMDS_MeshElement*,
7130 TIDSortedElemSet::const_iterator,
7131 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7132 SMDS_MeshElement::GeomFilter
7135 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
7137 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7138 _elements[type].end(),
7139 SMDS_MeshElement::GeomFilter( geomType )));
7141 // -------------------------------------------------------------------------------------
7142 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
7144 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
7146 typedef SMDS_SetIterator
7147 <const SMDS_MeshElement*,
7148 TIDSortedElemSet::const_iterator,
7149 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
7150 SMDS_MeshElement::EntityFilter
7153 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
7155 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
7156 _elements[type].end(),
7157 SMDS_MeshElement::EntityFilter( entity )));
7159 // -------------------------------------------------------------------------------------
7160 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
7162 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
7163 if ( type == SMDSAbs_All && !_meshDS )
7165 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
7167 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
7168 if ( !_elements[i].empty() && i != SMDSAbs_Node )
7170 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
7172 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
7173 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
7175 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
7176 ( new TIter( _elements[type].begin(), _elements[type].end() ));
7178 // -------------------------------------------------------------------------------------
7179 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
7180 iterType SMESH_MeshPartDS::methName() const \
7182 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
7183 return _meshDS ? _meshDS->methName() : iterType \
7184 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
7186 // -------------------------------------------------------------------------------------
7187 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
7188 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
7189 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
7190 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
7191 #undef _GET_ITER_DEFINE
7193 // END Implementation of SMESH_MeshPartDS
7195 //================================================================================