1 // Copyright (C) 2007-2016 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_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 CORBA::Long studyId )
111 : SALOME::GenericObj_i( thePOA )
115 _id = _idGenerator++;
118 _previewEditor = NULL;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 aGroup->UnRegister();
137 SMESH::SMESH_GroupBase_var( itGr->second );
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
147 SMESH::SMESH_subMesh_var( itSM->second );
149 _mapSubMeshIor.clear();
151 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
155 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
156 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
159 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
163 // clear cached shapes if no more meshes remain; (the cache is blame,
164 // together with publishing, of spent time increasing in issue 22874)
165 if ( _impl->NbMeshes() == 1 )
166 _gen_i->GetShapeReader()->ClearClientBuffer();
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
208 throw (SALOME::SALOME_Exception)
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //=======================================================================
222 //function : GetShapeToMesh
224 //=======================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
245 if ( study->_is_nil() ) break;
246 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
247 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
248 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
254 catch(SALOME_Exception & S_ex) {
255 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
257 return aShapeObj._retn();
260 //================================================================================
262 * \brief Return false if the mesh is not yet fully loaded from the study file
264 //================================================================================
266 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
268 Unexpect aCatch(SALOME_SalomeException);
269 return !_preMeshInfo;
272 //================================================================================
274 * \brief Load full mesh data from the study file
276 //================================================================================
278 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
280 Unexpect aCatch(SALOME_SalomeException);
282 _preMeshInfo->FullLoadFromFile();
285 //================================================================================
287 * \brief Remove all nodes and elements
289 //================================================================================
291 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
293 Unexpect aCatch(SALOME_SalomeException);
295 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
299 //CheckGeomGroupModif(); // issue 20145
301 catch(SALOME_Exception & S_ex) {
302 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
308 //================================================================================
310 * \brief Remove all nodes and elements for indicated shape
312 //================================================================================
314 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
315 throw (SALOME::SALOME_Exception)
317 Unexpect aCatch(SALOME_SalomeException);
319 _preMeshInfo->FullLoadFromFile();
322 _impl->ClearSubMesh( ShapeID );
324 catch(SALOME_Exception & S_ex) {
325 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
327 _impl->GetMeshDS()->Modified();
329 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
332 //=============================================================================
334 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
336 //=============================================================================
338 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
340 SMESH::DriverMED_ReadStatus res;
343 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
344 res = SMESH::DRS_OK; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
346 res = SMESH::DRS_EMPTY; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
348 res = SMESH::DRS_WARN_RENUMBER; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
350 res = SMESH::DRS_WARN_SKIP_ELEM; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
352 res = SMESH::DRS_WARN_DESCENDING; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
355 res = SMESH::DRS_FAIL; break;
360 //=============================================================================
362 * Convert ::SMESH_ComputeError to SMESH::ComputeError
364 //=============================================================================
366 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
368 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
369 errVar->subShapeID = -1;
370 errVar->hasBadMesh = false;
372 if ( !errorPtr || errorPtr->IsOK() )
374 errVar->code = SMESH::COMPERR_OK;
378 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
379 errVar->comment = errorPtr->myComment.c_str();
381 return errVar._retn();
384 //=============================================================================
388 * Imports mesh data from MED file
390 //=============================================================================
392 SMESH::DriverMED_ReadStatus
393 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
394 throw ( SALOME::SALOME_Exception )
396 Unexpect aCatch(SALOME_SalomeException);
399 status = _impl->MEDToMesh( theFileName, theMeshName );
401 catch( SALOME_Exception& S_ex ) {
402 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
405 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
408 CreateGroupServants();
410 int major, minor, release;
411 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
412 major = minor = release = -1;
413 _medFileInfo = new SMESH::MedFileInfo();
414 _medFileInfo->fileName = theFileName;
415 _medFileInfo->fileSize = 0;
416 _medFileInfo->major = major;
417 _medFileInfo->minor = minor;
418 _medFileInfo->release = release;
419 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
421 return ConvertDriverMEDReadStatus(status);
424 //================================================================================
426 * \brief Imports mesh data from the CGNS file
428 //================================================================================
430 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
431 const int theMeshIndex,
432 std::string& theMeshName )
433 throw ( SALOME::SALOME_Exception )
435 Unexpect aCatch(SALOME_SalomeException);
438 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
440 catch( SALOME_Exception& S_ex ) {
441 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
444 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
447 CreateGroupServants();
449 return ConvertDriverMEDReadStatus(status);
452 //================================================================================
454 * \brief Return string representation of a MED file version comprising nbDigits
456 //================================================================================
458 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
460 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
462 return CORBA::string_dup( ver.c_str() );
465 //=============================================================================
469 * Imports mesh data from MED file
471 //=============================================================================
473 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
474 throw ( SALOME::SALOME_Exception )
478 // Read mesh with name = <theMeshName> into SMESH_Mesh
479 _impl->UNVToMesh( theFileName );
481 CreateGroupServants();
483 SMESH_CATCH( SMESH::throwCorbaException );
488 //=============================================================================
492 * Imports mesh data from STL file
494 //=============================================================================
495 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
496 throw ( SALOME::SALOME_Exception )
500 // Read mesh with name = <theMeshName> into SMESH_Mesh
501 std::string name = _impl->STLToMesh( theFileName );
504 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
505 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( study, _this() );
506 _gen_i->SetName( meshSO, name.c_str() );
509 SMESH_CATCH( SMESH::throwCorbaException );
514 //================================================================================
516 * \brief Function used in SMESH_CATCH by ImportGMFFile()
518 //================================================================================
522 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
524 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
528 //================================================================================
530 * \brief Imports data from a GMF file and returns an error description
532 //================================================================================
534 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
535 bool theMakeRequiredGroups )
536 throw (SALOME::SALOME_Exception)
538 SMESH_ComputeErrorPtr error;
541 #define SMESH_CAUGHT error =
544 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
546 SMESH_CATCH( exceptionToComputeError );
550 CreateGroupServants();
552 return ConvertComputeError( error );
555 //=============================================================================
559 //=============================================================================
561 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
563 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
564 (SMESH_Hypothesis::Hypothesis_Status theStatus)
567 RETURNCASE( HYP_OK );
568 RETURNCASE( HYP_MISSING );
569 RETURNCASE( HYP_CONCURRENT );
570 RETURNCASE( HYP_BAD_PARAMETER );
571 RETURNCASE( HYP_HIDDEN_ALGO );
572 RETURNCASE( HYP_HIDING_ALGO );
573 RETURNCASE( HYP_UNKNOWN_FATAL );
574 RETURNCASE( HYP_INCOMPATIBLE );
575 RETURNCASE( HYP_NOTCONFORM );
576 RETURNCASE( HYP_ALREADY_EXIST );
577 RETURNCASE( HYP_BAD_DIM );
578 RETURNCASE( HYP_BAD_SUBSHAPE );
579 RETURNCASE( HYP_BAD_GEOMETRY );
580 RETURNCASE( HYP_NEED_SHAPE );
581 RETURNCASE( HYP_INCOMPAT_HYPS );
584 return SMESH::HYP_UNKNOWN_FATAL;
587 //=============================================================================
591 * calls internal addHypothesis() and then adds a reference to <anHyp> under
592 * the SObject actually having a reference to <aSubShape>.
593 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
595 //=============================================================================
597 SMESH::Hypothesis_Status
598 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
599 SMESH::SMESH_Hypothesis_ptr anHyp,
600 CORBA::String_out anErrorText)
601 throw(SALOME::SALOME_Exception)
603 Unexpect aCatch(SALOME_SalomeException);
605 _preMeshInfo->ForgetOrLoad();
608 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
609 anErrorText = error.c_str();
611 SMESH::SMESH_Mesh_var mesh( _this() );
612 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
614 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
615 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
617 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
619 // Update Python script
620 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
621 << aSubShape << ", " << anHyp << " )";
623 return ConvertHypothesisStatus(status);
626 //=============================================================================
630 //=============================================================================
632 SMESH_Hypothesis::Hypothesis_Status
633 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
634 SMESH::SMESH_Hypothesis_ptr anHyp,
635 std::string* anErrorText)
637 if(MYDEBUG) MESSAGE("addHypothesis");
639 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
640 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
642 if (CORBA::is_nil( anHyp ))
643 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
645 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
648 TopoDS_Shape myLocSubShape;
649 //use PseudoShape in case if mesh has no shape
651 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
653 myLocSubShape = _impl->GetShapeToMesh();
655 const int hypId = anHyp->GetId();
657 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
658 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
660 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
662 // assure there is a corresponding submesh
663 if ( !_impl->IsMainShape( myLocSubShape )) {
664 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
665 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
666 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
669 else if ( anErrorText )
671 *anErrorText = error;
674 catch(SALOME_Exception & S_ex)
676 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
681 //=============================================================================
685 //=============================================================================
687 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
688 SMESH::SMESH_Hypothesis_ptr anHyp)
689 throw(SALOME::SALOME_Exception)
691 Unexpect aCatch(SALOME_SalomeException);
693 _preMeshInfo->ForgetOrLoad();
695 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
696 SMESH::SMESH_Mesh_var mesh = _this();
698 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
700 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
701 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
703 // Update Python script
704 if(_impl->HasShapeToMesh())
705 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
706 << aSubShape << ", " << anHyp << " )";
708 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
711 return ConvertHypothesisStatus(status);
714 //=============================================================================
718 //=============================================================================
720 SMESH_Hypothesis::Hypothesis_Status
721 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
722 SMESH::SMESH_Hypothesis_ptr anHyp)
724 if(MYDEBUG) MESSAGE("removeHypothesis()");
726 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
727 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
729 if (CORBA::is_nil( anHyp ))
730 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
732 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
735 TopoDS_Shape myLocSubShape;
736 //use PseudoShape in case if mesh has no shape
737 if( _impl->HasShapeToMesh() )
738 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
740 myLocSubShape = _impl->GetShapeToMesh();
742 const int hypId = anHyp->GetId();
743 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
744 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
746 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
750 catch(SALOME_Exception & S_ex)
752 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
757 //=============================================================================
761 //=============================================================================
763 SMESH::ListOfHypothesis *
764 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
765 throw(SALOME::SALOME_Exception)
767 Unexpect aCatch(SALOME_SalomeException);
768 if (MYDEBUG) MESSAGE("GetHypothesisList");
769 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
770 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
772 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
775 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
776 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
777 myLocSubShape = _impl->GetShapeToMesh();
778 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
779 int i = 0, n = aLocalList.size();
782 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
783 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
784 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
786 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
787 if ( id_hypptr != _mapHypo.end() )
788 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
792 catch(SALOME_Exception & S_ex) {
793 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
796 return aList._retn();
799 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
801 Unexpect aCatch(SALOME_SalomeException);
802 if (MYDEBUG) MESSAGE("GetSubMeshes");
804 SMESH::submesh_array_var aList = new SMESH::submesh_array();
807 TPythonDump aPythonDump;
808 if ( !_mapSubMeshIor.empty() )
812 aList->length( _mapSubMeshIor.size() );
814 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
815 for ( ; it != _mapSubMeshIor.end(); it++ ) {
816 if ( CORBA::is_nil( it->second )) continue;
817 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
819 if (i > 1) aPythonDump << ", ";
820 aPythonDump << it->second;
824 catch(SALOME_Exception & S_ex) {
825 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
828 // Update Python script
829 if ( !_mapSubMeshIor.empty() )
830 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
832 return aList._retn();
835 //=============================================================================
839 //=============================================================================
841 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
842 const char* theName )
843 throw(SALOME::SALOME_Exception)
845 Unexpect aCatch(SALOME_SalomeException);
846 if (CORBA::is_nil(aSubShape))
847 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
849 SMESH::SMESH_subMesh_var subMesh;
850 SMESH::SMESH_Mesh_var aMesh = _this();
852 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
854 //Get or Create the SMESH_subMesh object implementation
856 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
858 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
860 TopoDS_Iterator it( myLocSubShape );
862 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
864 subMesh = getSubMesh( subMeshId );
866 // create a new subMesh object servant if there is none for the shape
867 if ( subMesh->_is_nil() )
868 subMesh = createSubMesh( aSubShape );
869 if ( _gen_i->CanPublishInStudy( subMesh ))
871 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
872 SALOMEDS::SObject_wrap aSO =
873 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
874 if ( !aSO->_is_nil()) {
875 // Update Python script
876 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
877 << aSubShape << ", '" << theName << "' )";
881 catch(SALOME_Exception & S_ex) {
882 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
884 return subMesh._retn();
887 //=============================================================================
891 //=============================================================================
893 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
894 throw (SALOME::SALOME_Exception)
898 if ( theSubMesh->_is_nil() )
901 GEOM::GEOM_Object_var aSubShape;
902 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
903 if ( !aStudy->_is_nil() ) {
904 // Remove submesh's SObject
905 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
906 if ( !anSO->_is_nil() ) {
907 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
908 SALOMEDS::SObject_wrap anObj, aRef;
909 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
910 anObj->ReferencedObject( aRef.inout() ))
912 CORBA::Object_var obj = aRef->GetObject();
913 aSubShape = GEOM::GEOM_Object::_narrow( obj );
915 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
916 // aSubShape = theSubMesh->GetSubShape();
918 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
919 builder->RemoveObjectWithChildren( anSO );
921 // Update Python script
922 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
926 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
928 _preMeshInfo->ForgetOrLoad();
930 SMESH_CATCH( SMESH::throwCorbaException );
933 //=============================================================================
937 //=============================================================================
939 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
940 const char* theName )
941 throw(SALOME::SALOME_Exception)
943 Unexpect aCatch(SALOME_SalomeException);
945 _preMeshInfo->FullLoadFromFile();
947 SMESH::SMESH_Group_var aNewGroup =
948 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
950 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
952 SMESH::SMESH_Mesh_var mesh = _this();
953 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
954 SALOMEDS::SObject_wrap aSO =
955 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
956 if ( !aSO->_is_nil())
957 // Update Python script
958 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
959 << theElemType << ", '" << theName << "' )";
961 return aNewGroup._retn();
964 //=============================================================================
968 //=============================================================================
969 SMESH::SMESH_GroupOnGeom_ptr
970 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
972 GEOM::GEOM_Object_ptr theGeomObj)
973 throw(SALOME::SALOME_Exception)
975 Unexpect aCatch(SALOME_SalomeException);
977 _preMeshInfo->FullLoadFromFile();
979 SMESH::SMESH_GroupOnGeom_var aNewGroup;
981 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
982 if ( !aShape.IsNull() )
985 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
987 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
989 SMESH::SMESH_Mesh_var mesh = _this();
990 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
991 SALOMEDS::SObject_wrap aSO =
992 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
993 if ( !aSO->_is_nil())
994 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
995 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
999 return aNewGroup._retn();
1002 //================================================================================
1004 * \brief Creates a group whose contents is defined by filter
1005 * \param theElemType - group type
1006 * \param theName - group name
1007 * \param theFilter - the filter
1008 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1010 //================================================================================
1012 SMESH::SMESH_GroupOnFilter_ptr
1013 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1014 const char* theName,
1015 SMESH::Filter_ptr theFilter )
1016 throw (SALOME::SALOME_Exception)
1018 Unexpect aCatch(SALOME_SalomeException);
1020 _preMeshInfo->FullLoadFromFile();
1022 if ( CORBA::is_nil( theFilter ))
1023 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1025 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1027 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1029 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1030 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1033 if ( !aNewGroup->_is_nil() )
1034 aNewGroup->SetFilter( theFilter );
1036 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1038 SMESH::SMESH_Mesh_var mesh = _this();
1039 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1040 SALOMEDS::SObject_wrap aSO =
1041 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1043 if ( !aSO->_is_nil())
1044 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1045 << theElemType << ", '" << theName << "', " << theFilter << " )";
1047 return aNewGroup._retn();
1050 //=============================================================================
1054 //=============================================================================
1056 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1057 throw (SALOME::SALOME_Exception)
1059 if ( theGroup->_is_nil() )
1064 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1068 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1069 if ( !aStudy->_is_nil() )
1071 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1072 if ( !aGroupSO->_is_nil() )
1074 // Update Python script
1075 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1077 // Remove group's SObject
1078 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1079 builder->RemoveObjectWithChildren( aGroupSO );
1082 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1084 // Remove the group from SMESH data structures
1085 removeGroup( aGroup->GetLocalID() );
1087 SMESH_CATCH( SMESH::throwCorbaException );
1090 //=============================================================================
1092 * Remove group with its contents
1094 //=============================================================================
1096 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1097 throw (SALOME::SALOME_Exception)
1101 _preMeshInfo->FullLoadFromFile();
1103 if ( theGroup->_is_nil() )
1106 vector<int> nodeIds; // to remove nodes becoming free
1107 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1108 if ( !isNodal && !theGroup->IsEmpty() )
1110 CORBA::Long elemID = theGroup->GetID( 1 );
1111 int nbElemNodes = GetElemNbNodes( elemID );
1112 if ( nbElemNodes > 0 )
1113 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1116 // Retrieve contents
1117 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1118 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1119 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1120 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1121 elems.assign( elemBeg, elemEnd );
1123 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1126 RemoveGroup( theGroup );
1129 for ( size_t i = 0; i < elems.size(); ++i )
1131 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1135 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1136 nodeIds.push_back( nIt->next()->GetID() );
1138 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1142 _impl->GetMeshDS()->RemoveElement( elems[i] );
1146 // Remove free nodes
1147 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1148 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1149 if ( n->NbInverseElements() == 0 )
1150 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1152 // Update Python script (theGroup must be alive for this)
1153 pyDump << SMESH::SMESH_Mesh_var(_this())
1154 << ".RemoveGroupWithContents( " << theGroup << " )";
1156 SMESH_CATCH( SMESH::throwCorbaException );
1159 //================================================================================
1161 * \brief Get the list of groups existing in the mesh
1162 * \retval SMESH::ListOfGroups * - list of groups
1164 //================================================================================
1166 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1168 Unexpect aCatch(SALOME_SalomeException);
1169 if (MYDEBUG) MESSAGE("GetGroups");
1171 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1174 TPythonDump aPythonDump;
1175 if ( !_mapGroups.empty() )
1177 aPythonDump << "[ ";
1179 aList->length( _mapGroups.size() );
1181 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1182 for ( ; it != _mapGroups.end(); it++ ) {
1183 if ( CORBA::is_nil( it->second )) continue;
1184 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1186 if (i > 1) aPythonDump << ", ";
1187 aPythonDump << it->second;
1191 catch(SALOME_Exception & S_ex) {
1192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1194 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1196 return aList._retn();
1199 //=============================================================================
1201 * Get number of groups existing in the mesh
1203 //=============================================================================
1205 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1207 Unexpect aCatch(SALOME_SalomeException);
1208 return _mapGroups.size();
1211 //=============================================================================
1213 * New group including all mesh elements present in initial groups is created.
1215 //=============================================================================
1217 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1218 SMESH::SMESH_GroupBase_ptr theGroup2,
1219 const char* theName )
1220 throw (SALOME::SALOME_Exception)
1222 SMESH::SMESH_Group_var aResGrp;
1226 _preMeshInfo->FullLoadFromFile();
1228 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1229 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1231 if ( theGroup1->GetType() != theGroup2->GetType() )
1232 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1237 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1238 if ( aResGrp->_is_nil() )
1239 return SMESH::SMESH_Group::_nil();
1241 aResGrp->AddFrom( theGroup1 );
1242 aResGrp->AddFrom( theGroup2 );
1244 // Update Python script
1245 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1246 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1248 SMESH_CATCH( SMESH::throwCorbaException );
1250 return aResGrp._retn();
1253 //=============================================================================
1255 * \brief New group including all mesh elements present in initial groups is created.
1256 * \param theGroups list of groups
1257 * \param theName name of group to be created
1258 * \return pointer to the new group
1260 //=============================================================================
1262 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1263 const char* theName )
1264 throw (SALOME::SALOME_Exception)
1266 SMESH::SMESH_Group_var aResGrp;
1269 _preMeshInfo->FullLoadFromFile();
1272 return SMESH::SMESH_Group::_nil();
1277 SMESH::ElementType aType = SMESH::ALL;
1278 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1280 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1281 if ( CORBA::is_nil( aGrp ) )
1283 if ( aType == SMESH::ALL )
1284 aType = aGrp->GetType();
1285 else if ( aType != aGrp->GetType() )
1286 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1289 if ( aType == SMESH::ALL )
1290 return SMESH::SMESH_Group::_nil();
1295 aResGrp = CreateGroup( aType, theName );
1296 if ( aResGrp->_is_nil() )
1297 return SMESH::SMESH_Group::_nil();
1299 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1300 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1302 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1303 if ( !CORBA::is_nil( aGrp ) )
1305 aResGrp->AddFrom( aGrp );
1306 if ( g > 0 ) pyDump << ", ";
1310 pyDump << " ], '" << theName << "' )";
1312 SMESH_CATCH( SMESH::throwCorbaException );
1314 return aResGrp._retn();
1317 //=============================================================================
1319 * New group is created. All mesh elements that are
1320 * present in both initial groups are added to the new one.
1322 //=============================================================================
1324 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1325 SMESH::SMESH_GroupBase_ptr theGroup2,
1326 const char* theName )
1327 throw (SALOME::SALOME_Exception)
1329 SMESH::SMESH_Group_var aResGrp;
1334 _preMeshInfo->FullLoadFromFile();
1336 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1337 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1339 if ( theGroup1->GetType() != theGroup2->GetType() )
1340 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1344 // Create Intersection
1345 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1346 if ( aResGrp->_is_nil() )
1347 return aResGrp._retn();
1349 SMESHDS_GroupBase* groupDS1 = 0;
1350 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1351 groupDS1 = grp_i->GetGroupDS();
1353 SMESHDS_GroupBase* groupDS2 = 0;
1354 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1355 groupDS2 = grp_i->GetGroupDS();
1357 SMESHDS_Group* resGroupDS = 0;
1358 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1359 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1361 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1363 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1364 while ( elemIt1->more() )
1366 const SMDS_MeshElement* e = elemIt1->next();
1367 if ( groupDS2->Contains( e ))
1368 resGroupDS->SMDSGroup().Add( e );
1371 // Update Python script
1372 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1373 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1375 SMESH_CATCH( SMESH::throwCorbaException );
1377 return aResGrp._retn();
1380 //=============================================================================
1382 \brief Intersect list of groups. New group is created. All mesh elements that
1383 are present in all initial groups simultaneously are added to the new one.
1384 \param theGroups list of groups
1385 \param theName name of group to be created
1386 \return pointer on the group
1388 //=============================================================================
1389 SMESH::SMESH_Group_ptr
1390 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1391 const char* theName )
1392 throw (SALOME::SALOME_Exception)
1394 SMESH::SMESH_Group_var aResGrp;
1399 _preMeshInfo->FullLoadFromFile();
1402 return SMESH::SMESH_Group::_nil();
1404 // check types and get SMESHDS_GroupBase's
1405 SMESH::ElementType aType = SMESH::ALL;
1406 vector< SMESHDS_GroupBase* > groupVec;
1407 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1409 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1410 if ( CORBA::is_nil( aGrp ) )
1412 if ( aType == SMESH::ALL )
1413 aType = aGrp->GetType();
1414 else if ( aType != aGrp->GetType() )
1415 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1418 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1419 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1421 if ( grpDS->IsEmpty() )
1426 groupVec.push_back( grpDS );
1429 if ( aType == SMESH::ALL ) // all groups are nil
1430 return SMESH::SMESH_Group::_nil();
1435 aResGrp = CreateGroup( aType, theName );
1437 SMESHDS_Group* resGroupDS = 0;
1438 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1439 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1440 if ( !resGroupDS || groupVec.empty() )
1441 return aResGrp._retn();
1444 size_t i, nb = groupVec.size();
1445 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1446 while ( elemIt1->more() )
1448 const SMDS_MeshElement* e = elemIt1->next();
1450 for ( i = 1; ( i < nb && inAll ); ++i )
1451 inAll = groupVec[i]->Contains( e );
1454 resGroupDS->SMDSGroup().Add( e );
1457 // Update Python script
1458 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1459 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1461 SMESH_CATCH( SMESH::throwCorbaException );
1463 return aResGrp._retn();
1466 //=============================================================================
1468 * New group is created. All mesh elements that are present in
1469 * a main group but is not present in a tool group are added to the new one
1471 //=============================================================================
1473 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1474 SMESH::SMESH_GroupBase_ptr theGroup2,
1475 const char* theName )
1476 throw (SALOME::SALOME_Exception)
1478 SMESH::SMESH_Group_var aResGrp;
1483 _preMeshInfo->FullLoadFromFile();
1485 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1486 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1488 if ( theGroup1->GetType() != theGroup2->GetType() )
1489 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1493 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1494 if ( aResGrp->_is_nil() )
1495 return aResGrp._retn();
1497 SMESHDS_GroupBase* groupDS1 = 0;
1498 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1499 groupDS1 = grp_i->GetGroupDS();
1501 SMESHDS_GroupBase* groupDS2 = 0;
1502 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1503 groupDS2 = grp_i->GetGroupDS();
1505 SMESHDS_Group* resGroupDS = 0;
1506 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1507 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1509 if ( groupDS1 && groupDS2 && resGroupDS )
1511 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1512 while ( elemIt1->more() )
1514 const SMDS_MeshElement* e = elemIt1->next();
1515 if ( !groupDS2->Contains( e ))
1516 resGroupDS->SMDSGroup().Add( e );
1519 // Update Python script
1520 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1521 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1523 SMESH_CATCH( SMESH::throwCorbaException );
1525 return aResGrp._retn();
1528 //=============================================================================
1530 \brief Cut lists of groups. New group is created. All mesh elements that are
1531 present in main groups but do not present in tool groups are added to the new one
1532 \param theMainGroups list of main groups
1533 \param theToolGroups list of tool groups
1534 \param theName name of group to be created
1535 \return pointer on the group
1537 //=============================================================================
1538 SMESH::SMESH_Group_ptr
1539 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1540 const SMESH::ListOfGroups& theToolGroups,
1541 const char* theName )
1542 throw (SALOME::SALOME_Exception)
1544 SMESH::SMESH_Group_var aResGrp;
1549 _preMeshInfo->FullLoadFromFile();
1552 return SMESH::SMESH_Group::_nil();
1554 // check types and get SMESHDS_GroupBase's
1555 SMESH::ElementType aType = SMESH::ALL;
1556 vector< SMESHDS_GroupBase* > toolGroupVec;
1557 vector< SMDS_ElemIteratorPtr > mainIterVec;
1559 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1561 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1562 if ( CORBA::is_nil( aGrp ) )
1564 if ( aType == SMESH::ALL )
1565 aType = aGrp->GetType();
1566 else if ( aType != aGrp->GetType() )
1567 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1569 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1570 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1571 if ( !grpDS->IsEmpty() )
1572 mainIterVec.push_back( grpDS->GetElements() );
1574 if ( aType == SMESH::ALL ) // all main groups are nil
1575 return SMESH::SMESH_Group::_nil();
1576 if ( mainIterVec.empty() ) // all main groups are empty
1577 return aResGrp._retn();
1579 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1581 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1582 if ( CORBA::is_nil( aGrp ) )
1584 if ( aType != aGrp->GetType() )
1585 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1587 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1588 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1589 toolGroupVec.push_back( grpDS );
1595 aResGrp = CreateGroup( aType, theName );
1597 SMESHDS_Group* resGroupDS = 0;
1598 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1599 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1601 return aResGrp._retn();
1604 size_t i, nb = toolGroupVec.size();
1605 SMDS_ElemIteratorPtr mainElemIt
1606 ( new SMDS_IteratorOnIterators
1607 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1608 while ( mainElemIt->more() )
1610 const SMDS_MeshElement* e = mainElemIt->next();
1612 for ( i = 0; ( i < nb && !isIn ); ++i )
1613 isIn = toolGroupVec[i]->Contains( e );
1616 resGroupDS->SMDSGroup().Add( e );
1619 // Update Python script
1620 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1621 << ".CutListOfGroups( " << theMainGroups << ", "
1622 << theToolGroups << ", '" << theName << "' )";
1624 SMESH_CATCH( SMESH::throwCorbaException );
1626 return aResGrp._retn();
1629 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1631 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1632 bool & toStopChecking )
1634 toStopChecking = ( nbCommon < nbChecked );
1635 return nbCommon == nbNodes;
1637 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1638 bool & toStopChecking )
1640 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1641 return nbCommon == nbCorners;
1643 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1644 bool & toStopChecking )
1646 return nbCommon > 0;
1648 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1649 bool & toStopChecking )
1651 return nbCommon >= (nbNodes+1) / 2;
1655 //=============================================================================
1657 * Create a group of entities basing on nodes of other groups.
1658 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1659 * \param [in] anElemType - a type of elements to include to the new group.
1660 * \param [in] theName - a name of the new group.
1661 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1662 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1663 * new group provided that it is based on nodes of an element of \a aListOfGroups
1664 * \return SMESH_Group - the created group
1666 // IMP 19939, bug 22010, IMP 22635
1667 //=============================================================================
1669 SMESH::SMESH_Group_ptr
1670 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1671 SMESH::ElementType theElemType,
1672 const char* theName,
1673 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1674 CORBA::Boolean theUnderlyingOnly)
1675 throw (SALOME::SALOME_Exception)
1677 SMESH::SMESH_Group_var aResGrp;
1681 _preMeshInfo->FullLoadFromFile();
1683 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1685 if ( !theName || !aMeshDS )
1686 return SMESH::SMESH_Group::_nil();
1688 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1690 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1691 SMESH_Comment nbCoNoStr( "SMESH.");
1692 switch ( theNbCommonNodes ) {
1693 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1694 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1695 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1696 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1697 default: return aResGrp._retn();
1699 int nbChecked, nbCommon, nbNodes, nbCorners;
1705 aResGrp = CreateGroup( theElemType, theName );
1706 if ( aResGrp->_is_nil() )
1707 return SMESH::SMESH_Group::_nil();
1709 SMESHDS_GroupBase* groupBaseDS =
1710 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1711 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1713 vector<bool> isNodeInGroups;
1715 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1717 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1718 if ( CORBA::is_nil( aGrp ) )
1720 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1721 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1724 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1725 if ( !elIt ) continue;
1727 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1729 while ( elIt->more() ) {
1730 const SMDS_MeshElement* el = elIt->next();
1731 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1732 while ( nIt->more() )
1733 resGroupCore.Add( nIt->next() );
1736 // get elements of theElemType based on nodes of every element of group
1737 else if ( theUnderlyingOnly )
1739 while ( elIt->more() )
1741 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1742 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1743 TIDSortedElemSet checkedElems;
1744 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1745 while ( nIt->more() )
1747 const SMDS_MeshNode* n = nIt->next();
1748 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1749 // check nodes of elements of theElemType around el
1750 while ( elOfTypeIt->more() )
1752 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1753 if ( !checkedElems.insert( elOfType ).second ) continue;
1754 nbNodes = elOfType->NbNodes();
1755 nbCorners = elOfType->NbCornerNodes();
1757 bool toStopChecking = false;
1758 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1759 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1760 if ( elNodes.count( nIt2->next() ) &&
1761 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1763 resGroupCore.Add( elOfType );
1770 // get all nodes of elements of groups
1773 while ( elIt->more() )
1775 const SMDS_MeshElement* el = elIt->next(); // an element of group
1776 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1777 while ( nIt->more() )
1779 const SMDS_MeshNode* n = nIt->next();
1780 if ( n->GetID() >= (int) isNodeInGroups.size() )
1781 isNodeInGroups.resize( n->GetID() + 1, false );
1782 isNodeInGroups[ n->GetID() ] = true;
1788 // Get elements of theElemType based on a certain number of nodes of elements of groups
1789 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1791 const SMDS_MeshNode* n;
1792 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1793 const int isNodeInGroupsSize = isNodeInGroups.size();
1794 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1796 if ( !isNodeInGroups[ iN ] ||
1797 !( n = aMeshDS->FindNode( iN )))
1800 // check nodes of elements of theElemType around n
1801 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1802 while ( elOfTypeIt->more() )
1804 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1805 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1810 nbNodes = elOfType->NbNodes();
1811 nbCorners = elOfType->NbCornerNodes();
1813 bool toStopChecking = false;
1814 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1815 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1817 const int nID = nIt->next()->GetID();
1818 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1819 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1821 resGroupCore.Add( elOfType );
1829 // Update Python script
1830 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1831 << ".CreateDimGroup( "
1832 << theGroups << ", " << theElemType << ", '" << theName << "', "
1833 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1835 SMESH_CATCH( SMESH::throwCorbaException );
1837 return aResGrp._retn();
1840 //================================================================================
1842 * \brief Remember GEOM group data
1844 //================================================================================
1846 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1847 CORBA::Object_ptr theSmeshObj)
1849 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1852 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1853 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1854 if ( groupSO->_is_nil() )
1857 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1858 GEOM::GEOM_IGroupOperations_wrap groupOp =
1859 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1860 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1863 _geomGroupData.push_back( TGeomGroupData() );
1864 TGeomGroupData & groupData = _geomGroupData.back();
1866 CORBA::String_var entry = groupSO->GetID();
1867 groupData._groupEntry = entry.in();
1869 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1870 groupData._indices.insert( ids[i] );
1872 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1873 // shape index in SMESHDS
1874 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1875 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1878 //================================================================================
1880 * Remove GEOM group data relating to removed smesh object
1882 //================================================================================
1884 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1886 list<TGeomGroupData>::iterator
1887 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1888 for ( ; data != dataEnd; ++data ) {
1889 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1890 _geomGroupData.erase( data );
1896 //================================================================================
1898 * \brief Return new group contents if it has been changed and update group data
1900 //================================================================================
1902 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1904 TopoDS_Shape newShape;
1907 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1908 if ( study->_is_nil() ) return newShape; // means "not changed"
1909 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1910 if ( !groupSO->_is_nil() )
1912 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1913 if ( CORBA::is_nil( groupObj )) return newShape;
1914 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1916 // get indices of group items
1917 set<int> curIndices;
1918 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1919 GEOM::GEOM_IGroupOperations_wrap groupOp =
1920 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1921 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1922 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1923 curIndices.insert( ids[i] );
1925 if ( groupData._indices == curIndices )
1926 return newShape; // group not changed
1929 groupData._indices = curIndices;
1931 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1932 if ( !geomClient ) return newShape;
1933 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1934 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1935 newShape = _gen_i->GeomObjectToShape( geomGroup );
1938 if ( newShape.IsNull() ) {
1939 // geom group becomes empty - return empty compound
1940 TopoDS_Compound compound;
1941 BRep_Builder().MakeCompound(compound);
1942 newShape = compound;
1949 //-----------------------------------------------------------------------------
1951 * \brief Storage of shape and index used in CheckGeomGroupModif()
1953 struct TIndexedShape
1956 TopoDS_Shape _shape;
1957 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1959 //-----------------------------------------------------------------------------
1961 * \brief Data to re-create a group on geometry
1963 struct TGroupOnGeomData
1967 SMDSAbs_ElementType _type;
1969 Quantity_Color _color;
1973 //=============================================================================
1975 * \brief Update data if geometry changes
1979 //=============================================================================
1981 void SMESH_Mesh_i::CheckGeomModif()
1983 if ( !_impl->HasShapeToMesh() ) return;
1985 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1986 if ( study->_is_nil() ) return;
1988 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1989 //if ( mainGO->_is_nil() ) return;
1991 // Update after group modification
1993 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1994 called by other mesh (IPAL52735) */
1995 mainGO->GetType() == GEOM_GROUP ||
1996 mainGO->GetTick() == _mainShapeTick )
1998 CheckGeomGroupModif();
2002 // Update after shape transformation like Translate
2004 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2005 if ( !geomClient ) return;
2006 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2007 if ( geomGen->_is_nil() ) return;
2009 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2010 geomClient->RemoveShapeFromBuffer( ior.in() );
2012 // Update data taking into account that
2013 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2016 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2017 if ( newShape.IsNull() )
2020 _mainShapeTick = mainGO->GetTick();
2022 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2024 // store data of groups on geometry
2025 vector< TGroupOnGeomData > groupsData;
2026 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2027 groupsData.reserve( groups.size() );
2028 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2029 for ( ; g != groups.end(); ++g )
2030 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2032 TGroupOnGeomData data;
2033 data._oldID = group->GetID();
2034 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2035 data._type = group->GetType();
2036 data._name = group->GetStoreName();
2037 data._color = group->GetColor();
2038 groupsData.push_back( data );
2040 // store assigned hypotheses
2041 vector< pair< int, THypList > > ids2Hyps;
2042 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2043 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2045 const TopoDS_Shape& s = s2hyps.Key();
2046 const THypList& hyps = s2hyps.ChangeValue();
2047 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2050 // change shape to mesh
2051 int oldNbSubShapes = meshDS->MaxShapeIndex();
2052 _impl->ShapeToMesh( TopoDS_Shape() );
2053 _impl->ShapeToMesh( newShape );
2055 // re-add shapes of geom groups
2056 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2057 for ( ; data != _geomGroupData.end(); ++data )
2059 TopoDS_Shape newShape = newGroupShape( *data );
2060 if ( !newShape.IsNull() )
2062 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2064 TopoDS_Compound compound;
2065 BRep_Builder().MakeCompound( compound );
2066 BRep_Builder().Add( compound, newShape );
2067 newShape = compound;
2069 _impl->GetSubMesh( newShape );
2072 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2073 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2074 SALOME::INTERNAL_ERROR );
2076 // re-assign hypotheses
2077 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2079 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2080 const THypList& hyps = ids2Hyps[i].second;
2081 THypList::const_iterator h = hyps.begin();
2082 for ( ; h != hyps.end(); ++h )
2083 _impl->AddHypothesis( s, (*h)->GetID() );
2087 for ( size_t i = 0; i < groupsData.size(); ++i )
2089 const TGroupOnGeomData& data = groupsData[i];
2091 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2092 if ( i2g == _mapGroups.end() ) continue;
2094 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2095 if ( !gr_i ) continue;
2098 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2099 meshDS->IndexToShape( data._shapeID ));
2102 _mapGroups.erase( i2g );
2106 g->GetGroupDS()->SetColor( data._color );
2107 gr_i->changeLocalId( id );
2108 _mapGroups[ id ] = i2g->second;
2109 if ( data._oldID != id )
2110 _mapGroups.erase( i2g );
2114 // update _mapSubMesh
2115 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2116 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2117 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2121 //=============================================================================
2123 * \brief Update objects depending on changed geom groups
2125 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2126 * issue 0020210: Update of a smesh group after modification of the associated geom group
2128 //=============================================================================
2130 void SMESH_Mesh_i::CheckGeomGroupModif()
2132 if ( !_impl->HasShapeToMesh() ) return;
2134 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2135 if ( study->_is_nil() ) return;
2137 CORBA::Long nbEntities = NbNodes() + NbElements();
2139 // Check if group contents changed
2141 typedef map< string, TopoDS_Shape > TEntry2Geom;
2142 TEntry2Geom newGroupContents;
2144 list<TGeomGroupData>::iterator
2145 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2146 for ( ; data != dataEnd; ++data )
2148 pair< TEntry2Geom::iterator, bool > it_new =
2149 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2150 bool processedGroup = !it_new.second;
2151 TopoDS_Shape& newShape = it_new.first->second;
2152 if ( !processedGroup )
2153 newShape = newGroupShape( *data );
2154 if ( newShape.IsNull() )
2155 continue; // no changes
2158 _preMeshInfo->ForgetOrLoad();
2160 if ( processedGroup ) { // update group indices
2161 list<TGeomGroupData>::iterator data2 = data;
2162 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2163 data->_indices = data2->_indices;
2166 // Update SMESH objects according to new GEOM group contents
2168 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2169 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2171 int oldID = submesh->GetId();
2172 if ( !_mapSubMeshIor.count( oldID ))
2174 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2176 // update hypotheses
2177 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2178 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2179 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2181 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2182 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2184 // care of submeshes
2185 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2186 int newID = newSubmesh->GetId();
2187 if ( newID != oldID ) {
2188 _mapSubMesh [ newID ] = newSubmesh;
2189 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2190 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2191 _mapSubMesh. erase(oldID);
2192 _mapSubMesh_i. erase(oldID);
2193 _mapSubMeshIor.erase(oldID);
2194 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2199 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2200 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2201 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2203 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2205 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2206 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2207 ds->SetShape( newShape );
2212 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2213 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2215 // Remove groups and submeshes basing on removed sub-shapes
2217 TopTools_MapOfShape newShapeMap;
2218 TopoDS_Iterator shapeIt( newShape );
2219 for ( ; shapeIt.More(); shapeIt.Next() )
2220 newShapeMap.Add( shapeIt.Value() );
2222 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2223 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2225 if ( newShapeMap.Contains( shapeIt.Value() ))
2227 TopTools_IndexedMapOfShape oldShapeMap;
2228 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2229 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2231 const TopoDS_Shape& oldShape = oldShapeMap(i);
2232 int oldInd = meshDS->ShapeToIndex( oldShape );
2234 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2235 if ( i_smIor != _mapSubMeshIor.end() ) {
2236 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2239 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2240 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2242 // check if a group bases on oldInd shape
2243 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2244 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2245 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2246 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2248 RemoveGroup( i_grp->second ); // several groups can base on same shape
2249 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2254 // Reassign hypotheses and update groups after setting the new shape to mesh
2256 // collect anassigned hypotheses
2257 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2258 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2259 TShapeHypList assignedHyps;
2260 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2262 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2263 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2264 if ( !hyps.empty() ) {
2265 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2266 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2267 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2270 // collect shapes supporting groups
2271 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2272 TShapeTypeList groupData;
2273 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2274 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2275 for ( ; grIt != groups.end(); ++grIt )
2277 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2279 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2281 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2283 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2284 _impl->ShapeToMesh( newShape );
2286 // reassign hypotheses
2287 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2288 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2290 TIndexedShape& geom = indS_hyps->first;
2291 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2292 int oldID = geom._index;
2293 int newID = meshDS->ShapeToIndex( geom._shape );
2294 if ( oldID == 1 ) { // main shape
2296 geom._shape = newShape;
2300 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2301 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2302 // care of sub-meshes
2303 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2304 if ( newID != oldID ) {
2305 _mapSubMesh [ newID ] = newSubmesh;
2306 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2307 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2308 _mapSubMesh. erase(oldID);
2309 _mapSubMesh_i. erase(oldID);
2310 _mapSubMeshIor.erase(oldID);
2311 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2315 TShapeTypeList::iterator geomType = groupData.begin();
2316 for ( ; geomType != groupData.end(); ++geomType )
2318 const TIndexedShape& geom = geomType->first;
2319 int oldID = geom._index;
2320 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2323 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2324 CORBA::String_var name = groupSO->GetName();
2326 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2328 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2329 group_i->changeLocalId( newID );
2332 break; // everything has been updated
2335 } // loop on group data
2339 CORBA::Long newNbEntities = NbNodes() + NbElements();
2340 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2341 if ( newNbEntities != nbEntities )
2343 // Add all SObjects with icons to soToUpdateIcons
2344 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2346 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2347 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2348 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2350 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2351 i_gr != _mapGroups.end(); ++i_gr ) // groups
2352 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2355 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2356 for ( ; so != soToUpdateIcons.end(); ++so )
2357 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2360 //=============================================================================
2362 * \brief Create standalone group from a group on geometry or filter
2364 //=============================================================================
2366 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2367 throw (SALOME::SALOME_Exception)
2369 SMESH::SMESH_Group_var aGroup;
2374 _preMeshInfo->FullLoadFromFile();
2376 if ( theGroup->_is_nil() )
2377 return aGroup._retn();
2379 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2381 return aGroup._retn();
2383 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2385 const int anId = aGroupToRem->GetLocalID();
2386 if ( !_impl->ConvertToStandalone( anId ) )
2387 return aGroup._retn();
2388 removeGeomGroupData( theGroup );
2390 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2392 // remove old instance of group from own map
2393 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2394 _mapGroups.erase( anId );
2396 SALOMEDS::StudyBuilder_var builder;
2397 SALOMEDS::SObject_wrap aGroupSO;
2398 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2399 if ( !aStudy->_is_nil() ) {
2400 builder = aStudy->NewBuilder();
2401 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2402 if ( !aGroupSO->_is_nil() )
2404 // remove reference to geometry
2405 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2406 for ( ; chItr->More(); chItr->Next() )
2407 // Remove group's child SObject
2408 builder->RemoveObject( chItr->Value() );
2410 // Update Python script
2411 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2412 << ".ConvertToStandalone( " << aGroupSO << " )";
2414 // change icon of Group on Filter
2417 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2418 const int isEmpty = ( elemTypes->length() == 0 );
2421 SALOMEDS::GenericAttribute_wrap anAttr =
2422 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2423 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2424 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2430 // remember new group in own map
2431 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2432 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2434 // register CORBA object for persistence
2435 _gen_i->RegisterObject( aGroup );
2437 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2438 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2439 //aGroup->Register();
2440 aGroupToRem->UnRegister();
2442 SMESH_CATCH( SMESH::throwCorbaException );
2444 return aGroup._retn();
2447 //=============================================================================
2451 //=============================================================================
2453 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2455 if(MYDEBUG) MESSAGE( "createSubMesh" );
2456 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2457 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2458 const int subMeshId = mySubMesh->GetId();
2460 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2461 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2463 _mapSubMesh [subMeshId] = mySubMesh;
2464 _mapSubMesh_i [subMeshId] = subMeshServant;
2465 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2467 subMeshServant->Register();
2469 // register CORBA object for persistence
2470 int nextId = _gen_i->RegisterObject( subMesh );
2471 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2472 else { nextId = 0; } // avoid "unused variable" warning
2474 // to track changes of GEOM groups
2475 addGeomGroupData( theSubShapeObject, subMesh );
2477 return subMesh._retn();
2480 //=======================================================================
2481 //function : getSubMesh
2483 //=======================================================================
2485 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2487 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2488 if ( it == _mapSubMeshIor.end() )
2489 return SMESH::SMESH_subMesh::_nil();
2491 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2494 //=============================================================================
2498 //=============================================================================
2500 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2501 GEOM::GEOM_Object_ptr theSubShapeObject )
2503 bool isHypChanged = false;
2504 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2505 return isHypChanged;
2507 const int subMeshId = theSubMesh->GetId();
2509 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2511 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2513 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2516 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2517 isHypChanged = !hyps.empty();
2518 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2519 for ( ; hyp != hyps.end(); ++hyp )
2520 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2527 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2528 isHypChanged = ( aHypList->length() > 0 );
2529 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2530 removeHypothesis( theSubShapeObject, aHypList[i] );
2533 catch( const SALOME::SALOME_Exception& ) {
2534 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2536 removeGeomGroupData( theSubShapeObject );
2540 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2541 if ( id_smi != _mapSubMesh_i.end() )
2542 id_smi->second->UnRegister();
2544 // remove a CORBA object
2545 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2546 if ( id_smptr != _mapSubMeshIor.end() )
2547 SMESH::SMESH_subMesh_var( id_smptr->second );
2549 _mapSubMesh.erase(subMeshId);
2550 _mapSubMesh_i.erase(subMeshId);
2551 _mapSubMeshIor.erase(subMeshId);
2553 return isHypChanged;
2556 //=============================================================================
2560 //=============================================================================
2562 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2563 const char* theName,
2564 const TopoDS_Shape& theShape,
2565 const SMESH_PredicatePtr& thePredicate )
2567 std::string newName;
2568 if ( !theName || !theName[0] )
2570 std::set< std::string > presentNames;
2571 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2572 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2574 CORBA::String_var name = i_gr->second->GetName();
2575 presentNames.insert( name.in() );
2578 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2579 } while ( !presentNames.insert( newName ).second );
2580 theName = newName.c_str();
2583 SMESH::SMESH_GroupBase_var aGroup;
2584 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2586 SMESH_GroupBase_i* aGroupImpl;
2587 if ( !theShape.IsNull() )
2588 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2589 else if ( thePredicate )
2590 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2592 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2594 aGroup = aGroupImpl->_this();
2595 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2596 aGroupImpl->Register();
2598 // register CORBA object for persistence
2599 int nextId = _gen_i->RegisterObject( aGroup );
2600 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2601 else { nextId = 0; } // avoid "unused variable" warning in release mode
2603 // to track changes of GEOM groups
2604 if ( !theShape.IsNull() ) {
2605 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2606 addGeomGroupData( geom, aGroup );
2609 return aGroup._retn();
2612 //=============================================================================
2614 * SMESH_Mesh_i::removeGroup
2616 * Should be called by ~SMESH_Group_i()
2618 //=============================================================================
2620 void SMESH_Mesh_i::removeGroup( const int theId )
2622 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2623 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2624 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2625 _mapGroups.erase( theId );
2626 removeGeomGroupData( group );
2627 if ( !_impl->RemoveGroup( theId ))
2629 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2630 RemoveGroup( group );
2632 group->UnRegister();
2636 //=============================================================================
2640 //=============================================================================
2642 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2643 throw(SALOME::SALOME_Exception)
2645 SMESH::log_array_var aLog;
2649 _preMeshInfo->FullLoadFromFile();
2651 list < SMESHDS_Command * >logDS = _impl->GetLog();
2652 aLog = new SMESH::log_array;
2654 int lg = logDS.size();
2657 list < SMESHDS_Command * >::iterator its = logDS.begin();
2658 while(its != logDS.end()){
2659 SMESHDS_Command *com = *its;
2660 int comType = com->GetType();
2662 int lgcom = com->GetNumber();
2664 const list < int >&intList = com->GetIndexes();
2665 int inum = intList.size();
2667 list < int >::const_iterator ii = intList.begin();
2668 const list < double >&coordList = com->GetCoords();
2669 int rnum = coordList.size();
2671 list < double >::const_iterator ir = coordList.begin();
2672 aLog[indexLog].commandType = comType;
2673 aLog[indexLog].number = lgcom;
2674 aLog[indexLog].coords.length(rnum);
2675 aLog[indexLog].indexes.length(inum);
2676 for(int i = 0; i < rnum; i++){
2677 aLog[indexLog].coords[i] = *ir;
2678 //MESSAGE(" "<<i<<" "<<ir.Value());
2681 for(int i = 0; i < inum; i++){
2682 aLog[indexLog].indexes[i] = *ii;
2683 //MESSAGE(" "<<i<<" "<<ii.Value());
2692 SMESH_CATCH( SMESH::throwCorbaException );
2694 return aLog._retn();
2698 //=============================================================================
2702 //=============================================================================
2704 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2708 SMESH_CATCH( SMESH::throwCorbaException );
2711 //=============================================================================
2715 //=============================================================================
2717 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2722 //=============================================================================
2726 //=============================================================================
2728 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2733 //=============================================================================
2736 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2737 // issue 0020918: groups removal is caused by hyp modification
2738 // issue 0021208: to forget not loaded mesh data at hyp modification
2739 struct TCallUp_i : public SMESH_Mesh::TCallUp
2741 SMESH_Mesh_i* _mesh;
2742 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2743 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2744 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2745 virtual void Load () { _mesh->Load(); }
2749 //================================================================================
2751 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2753 //================================================================================
2755 void SMESH_Mesh_i::onHypothesisModified()
2758 _preMeshInfo->ForgetOrLoad();
2761 //=============================================================================
2765 //=============================================================================
2767 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2769 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2772 _impl->SetCallUp( new TCallUp_i(this));
2775 //=============================================================================
2779 //=============================================================================
2781 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2783 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2787 //=============================================================================
2789 * Return mesh editor
2791 //=============================================================================
2793 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2794 throw (SALOME::SALOME_Exception)
2796 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2800 _preMeshInfo->FullLoadFromFile();
2802 // Create MeshEditor
2804 _editor = new SMESH_MeshEditor_i( this, false );
2805 aMeshEdVar = _editor->_this();
2807 // Update Python script
2808 TPythonDump() << _editor << " = "
2809 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2811 SMESH_CATCH( SMESH::throwCorbaException );
2813 return aMeshEdVar._retn();
2816 //=============================================================================
2818 * Return mesh edition previewer
2820 //=============================================================================
2822 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2823 throw (SALOME::SALOME_Exception)
2825 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2829 _preMeshInfo->FullLoadFromFile();
2831 if ( !_previewEditor )
2832 _previewEditor = new SMESH_MeshEditor_i( this, true );
2833 aMeshEdVar = _previewEditor->_this();
2835 SMESH_CATCH( SMESH::throwCorbaException );
2837 return aMeshEdVar._retn();
2840 //================================================================================
2842 * \brief Return true if the mesh has been edited since a last total re-compute
2843 * and those modifications may prevent successful partial re-compute
2845 //================================================================================
2847 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2849 Unexpect aCatch(SALOME_SalomeException);
2850 return _impl->HasModificationsToDiscard();
2853 //================================================================================
2855 * \brief Returns a random unique color
2857 //================================================================================
2859 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2861 const int MAX_ATTEMPTS = 100;
2863 double tolerance = 0.5;
2864 SALOMEDS::Color col;
2868 // generate random color
2869 double red = (double)rand() / RAND_MAX;
2870 double green = (double)rand() / RAND_MAX;
2871 double blue = (double)rand() / RAND_MAX;
2872 // check existence in the list of the existing colors
2873 bool matched = false;
2874 std::list<SALOMEDS::Color>::const_iterator it;
2875 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2876 SALOMEDS::Color color = *it;
2877 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2878 matched = tol < tolerance;
2880 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2881 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2889 //=============================================================================
2891 * Sets auto-color mode. If it is on, groups get unique random colors
2893 //=============================================================================
2895 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2897 Unexpect aCatch(SALOME_SalomeException);
2898 _impl->SetAutoColor(theAutoColor);
2900 TPythonDump pyDump; // not to dump group->SetColor() from below code
2901 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2903 std::list<SALOMEDS::Color> aReservedColors;
2904 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2905 for ( ; it != _mapGroups.end(); it++ ) {
2906 if ( CORBA::is_nil( it->second )) continue;
2907 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2908 it->second->SetColor( aColor );
2909 aReservedColors.push_back( aColor );
2913 //=============================================================================
2915 * Returns true if auto-color mode is on
2917 //=============================================================================
2919 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2921 Unexpect aCatch(SALOME_SalomeException);
2922 return _impl->GetAutoColor();
2925 //=============================================================================
2927 * Checks if there are groups with equal names
2929 //=============================================================================
2931 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2933 return _impl->HasDuplicatedGroupNamesMED();
2936 //================================================================================
2938 * \brief Care of a file before exporting mesh into it
2940 //================================================================================
2942 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2944 SMESH_File aFile( file );
2946 if (aFile.exists()) {
2947 // existing filesystem node
2948 if ( !aFile.isDirectory() ) {
2949 if ( aFile.openForWriting() ) {
2950 if ( overwrite && ! aFile.remove()) {
2951 msg << "Can't replace " << aFile.getName();
2954 msg << "Can't write into " << aFile.getName();
2957 msg << "Location " << aFile.getName() << " is not a file";
2961 // nonexisting file; check if it can be created
2962 if ( !aFile.openForWriting() ) {
2963 msg << "You cannot create the file "
2965 << ". Check the directory existence and access rights";
2973 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2977 //================================================================================
2979 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2980 * \param file - file name
2981 * \param overwrite - to erase the file or not
2982 * \retval string - mesh name
2984 //================================================================================
2986 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2987 CORBA::Boolean overwrite)
2990 PrepareForWriting(file, overwrite);
2991 string aMeshName = "Mesh";
2992 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2993 if ( !aStudy->_is_nil() ) {
2994 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2995 if ( !aMeshSO->_is_nil() ) {
2996 CORBA::String_var name = aMeshSO->GetName();
2998 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2999 if ( !aStudy->GetProperties()->IsLocked() )
3001 SALOMEDS::GenericAttribute_wrap anAttr;
3002 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3003 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3004 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3005 ASSERT(!aFileName->_is_nil());
3006 aFileName->SetValue(file);
3007 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3008 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3009 ASSERT(!aFileType->_is_nil());
3010 aFileType->SetValue("FICHIERMED");
3014 // Update Python script
3015 // set name of mesh before export
3016 TPythonDump() << _gen_i << ".SetName("
3017 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3019 // check names of groups
3025 //================================================================================
3027 * \brief Export to med file
3029 //================================================================================
3031 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3032 CORBA::Boolean auto_groups,
3033 SMESH::MED_VERSION theVersion,
3034 CORBA::Boolean overwrite,
3035 CORBA::Boolean autoDimension)
3036 throw(SALOME::SALOME_Exception)
3038 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3041 _preMeshInfo->FullLoadFromFile();
3043 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3044 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3046 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3047 << file << "', " << auto_groups << ", "
3048 << theVersion << ", " << overwrite << ", "
3049 << autoDimension << " )";
3051 SMESH_CATCH( SMESH::throwCorbaException );
3054 //================================================================================
3056 * \brief Export a mesh to a med file
3058 //================================================================================
3060 void SMESH_Mesh_i::ExportToMED (const char* file,
3061 CORBA::Boolean auto_groups,
3062 SMESH::MED_VERSION theVersion)
3063 throw(SALOME::SALOME_Exception)
3065 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3066 ExportToMEDX(file,auto_groups,theVersion,true);
3069 //================================================================================
3071 * \brief Export a mesh to a med file
3073 //================================================================================
3075 void SMESH_Mesh_i::ExportMED (const char* file,
3076 CORBA::Boolean auto_groups)
3077 throw(SALOME::SALOME_Exception)
3079 //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST);
3080 ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true);
3083 //================================================================================
3085 * \brief Export a mesh to a SAUV file
3087 //================================================================================
3089 void SMESH_Mesh_i::ExportSAUV (const char* file,
3090 CORBA::Boolean auto_groups)
3091 throw(SALOME::SALOME_Exception)
3093 Unexpect aCatch(SALOME_SalomeException);
3095 _preMeshInfo->FullLoadFromFile();
3097 string aMeshName = prepareMeshNameAndGroups(file, true);
3098 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3099 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3100 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3104 //================================================================================
3106 * \brief Export a mesh to a DAT file
3108 //================================================================================
3110 void SMESH_Mesh_i::ExportDAT (const char *file)
3111 throw(SALOME::SALOME_Exception)
3113 Unexpect aCatch(SALOME_SalomeException);
3115 _preMeshInfo->FullLoadFromFile();
3117 // Update Python script
3118 // check names of groups
3120 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3123 PrepareForWriting(file);
3124 _impl->ExportDAT(file);
3127 //================================================================================
3129 * \brief Export a mesh to an UNV file
3131 //================================================================================
3133 void SMESH_Mesh_i::ExportUNV (const char *file)
3134 throw(SALOME::SALOME_Exception)
3136 Unexpect aCatch(SALOME_SalomeException);
3138 _preMeshInfo->FullLoadFromFile();
3140 // Update Python script
3141 // check names of groups
3143 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3146 PrepareForWriting(file);
3147 _impl->ExportUNV(file);
3150 //================================================================================
3152 * \brief Export a mesh to an STL file
3154 //================================================================================
3156 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3157 throw(SALOME::SALOME_Exception)
3159 Unexpect aCatch(SALOME_SalomeException);
3161 _preMeshInfo->FullLoadFromFile();
3163 // Update Python script
3164 // check names of groups
3166 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3167 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3169 CORBA::String_var name;
3170 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3171 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() );
3172 if ( !so->_is_nil() )
3173 name = so->GetName();
3176 PrepareForWriting( file );
3177 _impl->ExportSTL( file, isascii, name.in() );
3180 //================================================================================
3182 * \brief Export a part of mesh to a med file
3184 //================================================================================
3186 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3188 CORBA::Boolean auto_groups,
3189 SMESH::MED_VERSION version,
3190 CORBA::Boolean overwrite,
3191 CORBA::Boolean autoDimension,
3192 const GEOM::ListOfFields& fields,
3193 const char* geomAssocFields)
3194 throw (SALOME::SALOME_Exception)
3198 _preMeshInfo->FullLoadFromFile();
3201 bool have0dField = false;
3202 if ( fields.length() > 0 )
3204 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3205 if ( shapeToMesh->_is_nil() )
3206 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3208 for ( size_t i = 0; i < fields.length(); ++i )
3210 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3211 THROW_SALOME_CORBA_EXCEPTION
3212 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3213 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3214 if ( fieldShape->_is_nil() )
3215 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3216 if ( !fieldShape->IsSame( shapeToMesh ) )
3217 THROW_SALOME_CORBA_EXCEPTION
3218 ( "Field defined not on shape", SALOME::BAD_PARAM);
3219 if ( fields[i]->GetDimension() == 0 )
3222 if ( geomAssocFields )
3223 for ( int i = 0; geomAssocFields[i]; ++i )
3224 switch ( geomAssocFields[i] ) {
3225 case 'v':case 'e':case 'f':case 's': break;
3226 case 'V':case 'E':case 'F':case 'S': break;
3227 default: THROW_SALOME_CORBA_EXCEPTION
3228 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3232 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3236 string aMeshName = "Mesh";
3237 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3238 if ( CORBA::is_nil( meshPart ) ||
3239 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3241 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3242 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3243 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3244 meshDS = _impl->GetMeshDS();
3249 _preMeshInfo->FullLoadFromFile();
3251 PrepareForWriting(file, overwrite);
3253 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3254 if ( !aStudy->_is_nil() ) {
3255 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3256 if ( !SO->_is_nil() ) {
3257 CORBA::String_var name = SO->GetName();
3261 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3262 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3263 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3264 meshDS = tmpDSDeleter._obj = partDS;
3269 if ( _impl->HasShapeToMesh() )
3271 DriverMED_W_Field fieldWriter;
3272 fieldWriter.SetFile( file );
3273 fieldWriter.SetMeshName( aMeshName );
3274 fieldWriter.AddODOnVertices( have0dField );
3276 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3280 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3281 goList->length( fields.length() );
3282 for ( size_t i = 0; i < fields.length(); ++i )
3284 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3287 TPythonDump() << _this() << ".ExportPartToMED( "
3288 << meshPart << ", r'" << file << "', "
3289 << auto_groups << ", " << version << ", " << overwrite << ", "
3290 << autoDimension << ", " << goList
3291 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3293 SMESH_CATCH( SMESH::throwCorbaException );
3296 //================================================================================
3298 * Write GEOM fields to MED file
3300 //================================================================================
3302 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3303 SMESHDS_Mesh* meshDS,
3304 const GEOM::ListOfFields& fields,
3305 const char* geomAssocFields)
3307 #define METH "SMESH_Mesh_i::exportMEDFields() "
3309 if (( fields.length() < 1 ) &&
3310 ( !geomAssocFields || !geomAssocFields[0] ))
3313 std::vector< std::vector< double > > dblVals;
3314 std::vector< std::vector< int > > intVals;
3315 std::vector< int > subIdsByDim[ 4 ];
3316 const double noneDblValue = 0.;
3317 const double noneIntValue = 0;
3319 for ( size_t iF = 0; iF < fields.length(); ++iF )
3323 int dim = fields[ iF ]->GetDimension();
3324 SMDSAbs_ElementType elemType;
3325 TopAbs_ShapeEnum shapeType;
3327 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3328 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3329 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3330 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3332 continue; // skip fields on whole shape
3334 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3335 if ( dataType == GEOM::FDT_String )
3337 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3338 if ( stepIDs->length() < 1 )
3340 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3341 if ( comps->length() < 1 )
3343 CORBA::String_var name = fields[ iF ]->GetName();
3345 if ( !fieldWriter.Set( meshDS,
3349 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3352 for ( size_t iC = 0; iC < comps->length(); ++iC )
3353 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3355 dblVals.resize( comps->length() );
3356 intVals.resize( comps->length() );
3358 // find sub-shape IDs
3360 std::vector< int >& subIds = subIdsByDim[ dim ];
3361 if ( subIds.empty() )
3362 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3363 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3364 subIds.push_back( id );
3368 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3372 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3374 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3375 if ( step->_is_nil() )
3378 CORBA::Long stamp = step->GetStamp();
3379 CORBA::Long id = step->GetID();
3380 fieldWriter.SetDtIt( int( stamp ), int( id ));
3382 // fill dblVals or intVals
3383 for ( size_t iC = 0; iC < comps->length(); ++iC )
3384 if ( dataType == GEOM::FDT_Double )
3386 dblVals[ iC ].clear();
3387 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3391 intVals[ iC ].clear();
3392 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3396 case GEOM::FDT_Double:
3398 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3399 if ( dblStep->_is_nil() ) continue;
3400 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3401 if ( vv->length() != subIds.size() * comps->length() )
3402 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3403 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3404 for ( size_t iC = 0; iC < comps->length(); ++iC )
3405 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3410 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3411 if ( intStep->_is_nil() ) continue;
3412 GEOM::ListOfLong_var vv = intStep->GetValues();
3413 if ( vv->length() != subIds.size() * comps->length() )
3414 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3415 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3416 for ( size_t iC = 0; iC < comps->length(); ++iC )
3417 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3420 case GEOM::FDT_Bool:
3422 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3423 if ( boolStep->_is_nil() ) continue;
3424 GEOM::short_array_var vv = boolStep->GetValues();
3425 if ( vv->length() != subIds.size() * comps->length() )
3426 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3427 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3428 for ( size_t iC = 0; iC < comps->length(); ++iC )
3429 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3435 // pass values to fieldWriter
3436 elemIt = fieldWriter.GetOrderedElems();
3437 if ( dataType == GEOM::FDT_Double )
3438 while ( elemIt->more() )
3440 const SMDS_MeshElement* e = elemIt->next();
3441 const int shapeID = e->getshapeId();
3442 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3443 for ( size_t iC = 0; iC < comps->length(); ++iC )
3444 fieldWriter.AddValue( noneDblValue );
3446 for ( size_t iC = 0; iC < comps->length(); ++iC )
3447 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3450 while ( elemIt->more() )
3452 const SMDS_MeshElement* e = elemIt->next();
3453 const int shapeID = e->getshapeId();
3454 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3455 for ( size_t iC = 0; iC < comps->length(); ++iC )
3456 fieldWriter.AddValue( (double) noneIntValue );
3458 for ( size_t iC = 0; iC < comps->length(); ++iC )
3459 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3463 fieldWriter.Perform();
3464 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3465 if ( res && res->IsKO() )
3467 if ( res->myComment.empty() )
3468 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3470 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3476 if ( !geomAssocFields || !geomAssocFields[0] )
3479 // write geomAssocFields
3481 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3482 shapeDim[ TopAbs_COMPOUND ] = 3;
3483 shapeDim[ TopAbs_COMPSOLID ] = 3;
3484 shapeDim[ TopAbs_SOLID ] = 3;
3485 shapeDim[ TopAbs_SHELL ] = 2;
3486 shapeDim[ TopAbs_FACE ] = 2;
3487 shapeDim[ TopAbs_WIRE ] = 1;
3488 shapeDim[ TopAbs_EDGE ] = 1;
3489 shapeDim[ TopAbs_VERTEX ] = 0;
3490 shapeDim[ TopAbs_SHAPE ] = 3;
3492 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3494 std::vector< std::string > compNames;
3495 switch ( geomAssocFields[ iF ]) {
3497 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3498 compNames.push_back( "dim" );
3501 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3504 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3507 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3511 compNames.push_back( "id" );
3512 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3513 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3515 fieldWriter.SetDtIt( -1, -1 );
3517 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3521 if ( compNames.size() == 2 ) // _vertices_
3522 while ( elemIt->more() )
3524 const SMDS_MeshElement* e = elemIt->next();
3525 const int shapeID = e->getshapeId();
3528 fieldWriter.AddValue( (double) -1 );
3529 fieldWriter.AddValue( (double) -1 );
3533 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3534 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3535 fieldWriter.AddValue( (double) shapeID );
3539 while ( elemIt->more() )
3541 const SMDS_MeshElement* e = elemIt->next();
3542 const int shapeID = e->getshapeId();
3544 fieldWriter.AddValue( (double) -1 );
3546 fieldWriter.AddValue( (double) shapeID );
3550 fieldWriter.Perform();
3551 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3552 if ( res && res->IsKO() )
3554 if ( res->myComment.empty() )
3555 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3557 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3560 } // loop on geomAssocFields
3565 //================================================================================
3567 * \brief Export a part of mesh to a DAT file
3569 //================================================================================
3571 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3573 throw (SALOME::SALOME_Exception)
3575 Unexpect aCatch(SALOME_SalomeException);
3577 _preMeshInfo->FullLoadFromFile();
3579 PrepareForWriting(file);
3581 SMESH_MeshPartDS partDS( meshPart );
3582 _impl->ExportDAT(file,&partDS);
3584 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3585 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3587 //================================================================================
3589 * \brief Export a part of mesh to an UNV file
3591 //================================================================================
3593 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3595 throw (SALOME::SALOME_Exception)
3597 Unexpect aCatch(SALOME_SalomeException);
3599 _preMeshInfo->FullLoadFromFile();
3601 PrepareForWriting(file);
3603 SMESH_MeshPartDS partDS( meshPart );
3604 _impl->ExportUNV(file, &partDS);
3606 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3607 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3609 //================================================================================
3611 * \brief Export a part of mesh to an STL file
3613 //================================================================================
3615 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3617 ::CORBA::Boolean isascii)
3618 throw (SALOME::SALOME_Exception)
3620 Unexpect aCatch(SALOME_SalomeException);
3622 _preMeshInfo->FullLoadFromFile();
3624 PrepareForWriting(file);
3626 CORBA::String_var name;
3627 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3628 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3629 if ( !so->_is_nil() )
3630 name = so->GetName();
3632 SMESH_MeshPartDS partDS( meshPart );
3633 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3635 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3636 << meshPart<< ", r'" << file << "', " << isascii << ")";
3639 //================================================================================
3641 * \brief Export a part of mesh to an STL file
3643 //================================================================================
3645 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3647 CORBA::Boolean overwrite,
3648 CORBA::Boolean groupElemsByType)
3649 throw (SALOME::SALOME_Exception)
3652 Unexpect aCatch(SALOME_SalomeException);
3654 _preMeshInfo->FullLoadFromFile();
3656 PrepareForWriting(file,overwrite);
3658 std::string meshName("");
3659 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3660 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3661 if ( !so->_is_nil() )
3663 CORBA::String_var name = so->GetName();
3664 meshName = name.in();
3668 SMESH_MeshPartDS partDS( meshPart );
3669 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3671 SMESH_CATCH( SMESH::throwCorbaException );
3673 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3674 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3676 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3680 //================================================================================
3682 * \brief Export a part of mesh to a GMF file
3684 //================================================================================
3686 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3688 bool withRequiredGroups)
3689 throw (SALOME::SALOME_Exception)
3691 Unexpect aCatch(SALOME_SalomeException);
3693 _preMeshInfo->FullLoadFromFile();
3695 PrepareForWriting(file,/*overwrite=*/true);
3697 SMESH_MeshPartDS partDS( meshPart );
3698 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3700 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3701 << meshPart<< ", r'"
3703 << withRequiredGroups << ")";
3706 //=============================================================================
3708 * Return computation progress [0.,1]
3710 //=============================================================================
3712 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3716 return _impl->GetComputeProgress();
3718 SMESH_CATCH( SMESH::doNothing );
3722 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3724 Unexpect aCatch(SALOME_SalomeException);
3726 return _preMeshInfo->NbNodes();
3728 return _impl->NbNodes();
3731 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3733 Unexpect aCatch(SALOME_SalomeException);
3735 return _preMeshInfo->NbElements();
3737 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3740 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3742 Unexpect aCatch(SALOME_SalomeException);
3744 return _preMeshInfo->Nb0DElements();
3746 return _impl->Nb0DElements();
3749 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3751 Unexpect aCatch(SALOME_SalomeException);
3753 return _preMeshInfo->NbBalls();
3755 return _impl->NbBalls();
3758 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3760 Unexpect aCatch(SALOME_SalomeException);
3762 return _preMeshInfo->NbEdges();
3764 return _impl->NbEdges();
3767 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3768 throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3774 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3777 //=============================================================================
3779 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3781 Unexpect aCatch(SALOME_SalomeException);
3783 return _preMeshInfo->NbFaces();
3785 return _impl->NbFaces();
3788 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3790 Unexpect aCatch(SALOME_SalomeException);
3792 return _preMeshInfo->NbTriangles();
3794 return _impl->NbTriangles();
3797 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3799 Unexpect aCatch(SALOME_SalomeException);
3801 return _preMeshInfo->NbBiQuadTriangles();
3803 return _impl->NbBiQuadTriangles();
3806 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3808 Unexpect aCatch(SALOME_SalomeException);
3810 return _preMeshInfo->NbQuadrangles();
3812 return _impl->NbQuadrangles();
3815 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3817 Unexpect aCatch(SALOME_SalomeException);
3819 return _preMeshInfo->NbBiQuadQuadrangles();
3821 return _impl->NbBiQuadQuadrangles();
3824 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3826 Unexpect aCatch(SALOME_SalomeException);
3828 return _preMeshInfo->NbPolygons();
3830 return _impl->NbPolygons();
3833 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3835 Unexpect aCatch(SALOME_SalomeException);
3837 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3839 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3842 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3843 throw(SALOME::SALOME_Exception)
3845 Unexpect aCatch(SALOME_SalomeException);
3847 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3849 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3852 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3853 throw(SALOME::SALOME_Exception)
3855 Unexpect aCatch(SALOME_SalomeException);
3857 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3859 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3862 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3863 throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3869 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3872 //=============================================================================
3874 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3876 Unexpect aCatch(SALOME_SalomeException);
3878 return _preMeshInfo->NbVolumes();
3880 return _impl->NbVolumes();
3883 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3885 Unexpect aCatch(SALOME_SalomeException);
3887 return _preMeshInfo->NbTetras();
3889 return _impl->NbTetras();
3892 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3894 Unexpect aCatch(SALOME_SalomeException);
3896 return _preMeshInfo->NbHexas();
3898 return _impl->NbHexas();
3901 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3903 Unexpect aCatch(SALOME_SalomeException);
3905 return _preMeshInfo->NbTriQuadHexas();
3907 return _impl->NbTriQuadraticHexas();
3910 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3912 Unexpect aCatch(SALOME_SalomeException);
3914 return _preMeshInfo->NbPyramids();
3916 return _impl->NbPyramids();
3919 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3921 Unexpect aCatch(SALOME_SalomeException);
3923 return _preMeshInfo->NbPrisms();
3925 return _impl->NbPrisms();
3928 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3930 Unexpect aCatch(SALOME_SalomeException);
3932 return _preMeshInfo->NbHexPrisms();
3934 return _impl->NbHexagonalPrisms();
3937 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3939 Unexpect aCatch(SALOME_SalomeException);
3941 return _preMeshInfo->NbPolyhedrons();
3943 return _impl->NbPolyhedrons();
3946 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3947 throw(SALOME::SALOME_Exception)
3949 Unexpect aCatch(SALOME_SalomeException);
3951 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3953 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3956 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3957 throw(SALOME::SALOME_Exception)
3959 Unexpect aCatch(SALOME_SalomeException);
3961 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3963 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3966 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3967 throw(SALOME::SALOME_Exception)
3969 Unexpect aCatch(SALOME_SalomeException);
3971 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3973 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3976 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3977 throw(SALOME::SALOME_Exception)
3979 Unexpect aCatch(SALOME_SalomeException);
3981 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3983 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3986 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3987 throw(SALOME::SALOME_Exception)
3989 Unexpect aCatch(SALOME_SalomeException);
3991 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3993 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3996 //=============================================================================
3998 * Returns nb of published sub-meshes
4000 //=============================================================================
4002 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4004 Unexpect aCatch(SALOME_SalomeException);
4005 return _mapSubMesh_i.size();
4008 //=============================================================================
4010 * Dumps mesh into a string
4012 //=============================================================================
4014 char* SMESH_Mesh_i::Dump()
4018 return CORBA::string_dup( os.str().c_str() );
4021 //=============================================================================
4023 * Method of SMESH_IDSource interface
4025 //=============================================================================
4027 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4029 return GetElementsId();
4032 //=============================================================================
4034 * Returns ids of all elements
4036 //=============================================================================
4038 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4039 throw (SALOME::SALOME_Exception)
4041 Unexpect aCatch(SALOME_SalomeException);
4043 _preMeshInfo->FullLoadFromFile();
4045 SMESH::long_array_var aResult = new SMESH::long_array();
4046 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4048 if ( aSMESHDS_Mesh == NULL )
4049 return aResult._retn();
4051 long nbElements = NbElements();
4052 aResult->length( nbElements );
4053 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4054 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4055 aResult[i] = anIt->next()->GetID();
4057 return aResult._retn();
4061 //=============================================================================
4063 * Returns ids of all elements of given type
4065 //=============================================================================
4067 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4068 throw (SALOME::SALOME_Exception)
4070 Unexpect aCatch(SALOME_SalomeException);
4072 _preMeshInfo->FullLoadFromFile();
4074 SMESH::long_array_var aResult = new SMESH::long_array();
4075 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4077 if ( aSMESHDS_Mesh == NULL )
4078 return aResult._retn();
4080 long nbElements = NbElements();
4082 // No sense in returning ids of elements along with ids of nodes:
4083 // when theElemType == SMESH::ALL, return node ids only if
4084 // there are no elements
4085 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4086 return GetNodesId();
4088 aResult->length( nbElements );
4092 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4093 while ( i < nbElements && anIt->more() )
4094 aResult[i++] = anIt->next()->GetID();
4096 aResult->length( i );
4098 return aResult._retn();
4101 //=============================================================================
4103 * Returns ids of all nodes
4105 //=============================================================================
4107 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4108 throw (SALOME::SALOME_Exception)
4110 Unexpect aCatch(SALOME_SalomeException);
4112 _preMeshInfo->FullLoadFromFile();
4114 SMESH::long_array_var aResult = new SMESH::long_array();
4115 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4117 if ( aMeshDS == NULL )
4118 return aResult._retn();
4120 long nbNodes = NbNodes();
4121 aResult->length( nbNodes );
4122 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4123 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4124 aResult[i] = anIt->next()->GetID();
4126 return aResult._retn();
4129 //=============================================================================
4133 //=============================================================================
4135 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4136 throw (SALOME::SALOME_Exception)
4138 SMESH::ElementType type = SMESH::ALL;
4142 _preMeshInfo->FullLoadFromFile();
4144 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4146 SMESH_CATCH( SMESH::throwCorbaException );
4151 //=============================================================================
4155 //=============================================================================
4157 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4158 throw (SALOME::SALOME_Exception)
4161 _preMeshInfo->FullLoadFromFile();
4163 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4165 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4167 return ( SMESH::EntityType ) e->GetEntityType();
4170 //=============================================================================
4174 //=============================================================================
4176 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4177 throw (SALOME::SALOME_Exception)
4180 _preMeshInfo->FullLoadFromFile();
4182 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4184 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4186 return ( SMESH::GeometryType ) e->GetGeomType();
4189 //=============================================================================
4191 * Returns ID of elements for given submesh
4193 //=============================================================================
4194 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4195 throw (SALOME::SALOME_Exception)
4197 SMESH::long_array_var aResult = new SMESH::long_array();
4201 _preMeshInfo->FullLoadFromFile();
4203 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4204 if(!SM) return aResult._retn();
4206 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4207 if(!SDSM) return aResult._retn();
4209 aResult->length(SDSM->NbElements());
4211 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4213 while ( eIt->more() ) {
4214 aResult[i++] = eIt->next()->GetID();
4217 SMESH_CATCH( SMESH::throwCorbaException );
4219 return aResult._retn();
4222 //=============================================================================
4224 * Returns ID of nodes for given submesh
4225 * If param all==true - returns all nodes, else -
4226 * returns only nodes on shapes.
4228 //=============================================================================
4230 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4232 throw (SALOME::SALOME_Exception)
4234 SMESH::long_array_var aResult = new SMESH::long_array();
4238 _preMeshInfo->FullLoadFromFile();
4240 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4241 if(!SM) return aResult._retn();
4243 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4244 if(!SDSM) return aResult._retn();
4247 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4248 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4249 while ( nIt->more() ) {
4250 const SMDS_MeshNode* elem = nIt->next();
4251 theElems.insert( elem->GetID() );
4254 else { // all nodes of submesh elements
4255 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4256 while ( eIt->more() ) {
4257 const SMDS_MeshElement* anElem = eIt->next();
4258 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4259 while ( nIt->more() ) {
4260 const SMDS_MeshElement* elem = nIt->next();
4261 theElems.insert( elem->GetID() );
4266 aResult->length(theElems.size());
4267 set<int>::iterator itElem;
4269 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4270 aResult[i++] = *itElem;
4272 SMESH_CATCH( SMESH::throwCorbaException );
4274 return aResult._retn();
4277 //=============================================================================
4279 * Returns type of elements for given submesh
4281 //=============================================================================
4283 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4284 throw (SALOME::SALOME_Exception)
4286 SMESH::ElementType type = SMESH::ALL;
4290 _preMeshInfo->FullLoadFromFile();
4292 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4293 if(!SM) return SMESH::ALL;
4295 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4296 if(!SDSM) return SMESH::ALL;
4298 if(SDSM->NbElements()==0)
4299 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4301 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4302 const SMDS_MeshElement* anElem = eIt->next();
4304 type = ( SMESH::ElementType ) anElem->GetType();
4306 SMESH_CATCH( SMESH::throwCorbaException );
4312 //=============================================================================
4314 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4316 //=============================================================================
4318 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4321 _preMeshInfo->FullLoadFromFile();
4323 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4324 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4329 //=============================================================================
4331 * Get XYZ coordinates of node as list of double
4332 * If there is not node for given ID - returns empty list
4334 //=============================================================================
4336 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4339 _preMeshInfo->FullLoadFromFile();
4341 SMESH::double_array_var aResult = new SMESH::double_array();
4342 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4343 if ( aMeshDS == NULL )
4344 return aResult._retn();
4347 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4349 return aResult._retn();
4353 aResult[0] = aNode->X();
4354 aResult[1] = aNode->Y();
4355 aResult[2] = aNode->Z();
4356 return aResult._retn();
4360 //=============================================================================
4362 * For given node returns list of IDs of inverse elements
4363 * If there is not node for given ID - returns empty list
4365 //=============================================================================
4367 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4370 _preMeshInfo->FullLoadFromFile();
4372 SMESH::long_array_var aResult = new SMESH::long_array();
4373 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4374 if ( aMeshDS == NULL )
4375 return aResult._retn();
4378 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4380 return aResult._retn();
4382 // find inverse elements
4383 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4384 aResult->length( aNode->NbInverseElements() );
4385 for( int i = 0; eIt->more(); ++i )
4387 const SMDS_MeshElement* elem = eIt->next();
4388 aResult[ i ] = elem->GetID();
4390 return aResult._retn();
4393 //=============================================================================
4395 * \brief Return position of a node on shape
4397 //=============================================================================
4399 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4402 _preMeshInfo->FullLoadFromFile();
4404 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4405 aNodePosition->shapeID = 0;
4406 aNodePosition->shapeType = GEOM::SHAPE;
4408 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4409 if ( !mesh ) return aNodePosition;
4411 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4413 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4415 aNodePosition->shapeID = aNode->getshapeId();
4416 switch ( pos->GetTypeOfPosition() ) {
4418 aNodePosition->shapeType = GEOM::EDGE;
4419 aNodePosition->params.length(1);
4420 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4422 case SMDS_TOP_FACE: {
4423 SMDS_FacePositionPtr fPos = pos;
4424 aNodePosition->shapeType = GEOM::FACE;
4425 aNodePosition->params.length(2);
4426 aNodePosition->params[0] = fPos->GetUParameter();
4427 aNodePosition->params[1] = fPos->GetVParameter();
4430 case SMDS_TOP_VERTEX:
4431 aNodePosition->shapeType = GEOM::VERTEX;
4433 case SMDS_TOP_3DSPACE:
4434 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4435 aNodePosition->shapeType = GEOM::SOLID;
4436 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4437 aNodePosition->shapeType = GEOM::SHELL;
4443 return aNodePosition;
4446 //=============================================================================
4448 * \brief Return position of an element on shape
4450 //=============================================================================
4452 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4455 _preMeshInfo->FullLoadFromFile();
4457 SMESH::ElementPosition anElementPosition;
4458 anElementPosition.shapeID = 0;
4459 anElementPosition.shapeType = GEOM::SHAPE;
4461 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4462 if ( !mesh ) return anElementPosition;
4464 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4466 anElementPosition.shapeID = anElem->getshapeId();
4467 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4468 if ( !aSp.IsNull() ) {
4469 switch ( aSp.ShapeType() ) {
4471 anElementPosition.shapeType = GEOM::EDGE;
4474 anElementPosition.shapeType = GEOM::FACE;
4477 anElementPosition.shapeType = GEOM::VERTEX;
4480 anElementPosition.shapeType = GEOM::SOLID;
4483 anElementPosition.shapeType = GEOM::SHELL;
4489 return anElementPosition;
4492 //=============================================================================
4494 * If given element is node returns IDs of shape from position
4495 * If there is not node for given ID - returns -1
4497 //=============================================================================
4499 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4502 _preMeshInfo->FullLoadFromFile();
4504 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4505 if ( aMeshDS == NULL )
4509 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4511 return aNode->getshapeId();
4518 //=============================================================================
4520 * For given element returns ID of result shape after
4521 * ::FindShape() from SMESH_MeshEditor
4522 * If there is not element for given ID - returns -1
4524 //=============================================================================
4526 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4529 _preMeshInfo->FullLoadFromFile();
4531 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4532 if ( aMeshDS == NULL )
4535 // try to find element
4536 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4540 ::SMESH_MeshEditor aMeshEditor(_impl);
4541 int index = aMeshEditor.FindShape( elem );
4549 //=============================================================================
4551 * Returns number of nodes for given element
4552 * If there is not element for given ID - returns -1
4554 //=============================================================================
4556 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4559 _preMeshInfo->FullLoadFromFile();
4561 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4562 if ( aMeshDS == NULL ) return -1;
4563 // try to find element
4564 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4565 if(!elem) return -1;
4566 return elem->NbNodes();
4570 //=============================================================================
4572 * Returns ID of node by given index for given element
4573 * If there is not element for given ID - returns -1
4574 * If there is not node for given index - returns -2
4576 //=============================================================================
4578 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4581 _preMeshInfo->FullLoadFromFile();
4583 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4584 if ( aMeshDS == NULL ) return -1;
4585 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4586 if(!elem) return -1;
4587 if( index>=elem->NbNodes() || index<0 ) return -1;
4588 return elem->GetNode(index)->GetID();
4591 //=============================================================================
4593 * Returns IDs of nodes of given element
4595 //=============================================================================
4597 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4600 _preMeshInfo->FullLoadFromFile();
4602 SMESH::long_array_var aResult = new SMESH::long_array();
4603 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4605 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4607 aResult->length( elem->NbNodes() );
4608 for ( int i = 0; i < elem->NbNodes(); ++i )
4609 aResult[ i ] = elem->GetNode( i )->GetID();
4612 return aResult._retn();
4615 //=============================================================================
4617 * Returns true if given node is medium node
4618 * in given quadratic element
4620 //=============================================================================
4622 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4625 _preMeshInfo->FullLoadFromFile();
4627 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4628 if ( aMeshDS == NULL ) return false;
4630 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4631 if(!aNode) return false;
4632 // try to find element
4633 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4634 if(!elem) return false;
4636 return elem->IsMediumNode(aNode);
4640 //=============================================================================
4642 * Returns true if given node is medium node
4643 * in one of quadratic elements
4645 //=============================================================================
4647 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4648 SMESH::ElementType theElemType)
4651 _preMeshInfo->FullLoadFromFile();
4653 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4654 if ( aMeshDS == NULL ) return false;
4657 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4658 if(!aNode) return false;
4660 SMESH_MesherHelper aHelper( *(_impl) );
4662 SMDSAbs_ElementType aType;
4663 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4664 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4665 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4666 else aType = SMDSAbs_All;
4668 return aHelper.IsMedium(aNode,aType);
4672 //=============================================================================
4674 * Returns number of edges for given element
4676 //=============================================================================
4678 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4681 _preMeshInfo->FullLoadFromFile();
4683 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4684 if ( aMeshDS == NULL ) return -1;
4685 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4686 if(!elem) return -1;
4687 return elem->NbEdges();
4691 //=============================================================================
4693 * Returns number of faces for given element
4695 //=============================================================================
4697 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4700 _preMeshInfo->FullLoadFromFile();
4702 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4703 if ( aMeshDS == NULL ) return -1;
4704 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4705 if(!elem) return -1;
4706 return elem->NbFaces();
4709 //=======================================================================
4710 //function : GetElemFaceNodes
4711 //purpose : Returns nodes of given face (counted from zero) for given element.
4712 //=======================================================================
4714 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4715 CORBA::Short faceIndex)
4718 _preMeshInfo->FullLoadFromFile();
4720 SMESH::long_array_var aResult = new SMESH::long_array();
4721 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4723 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4725 SMDS_VolumeTool vtool( elem );
4726 if ( faceIndex < vtool.NbFaces() )
4728 aResult->length( vtool.NbFaceNodes( faceIndex ));
4729 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4730 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4731 aResult[ i ] = nn[ i ]->GetID();
4735 return aResult._retn();
4738 //=======================================================================
4739 //function : GetElemFaceNodes
4740 //purpose : Returns three components of normal of given mesh face.
4741 //=======================================================================
4743 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4744 CORBA::Boolean normalized)
4747 _preMeshInfo->FullLoadFromFile();
4749 SMESH::double_array_var aResult = new SMESH::double_array();
4751 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4754 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4756 aResult->length( 3 );
4757 aResult[ 0 ] = normal.X();
4758 aResult[ 1 ] = normal.Y();
4759 aResult[ 2 ] = normal.Z();
4762 return aResult._retn();
4765 //=======================================================================
4766 //function : FindElementByNodes
4767 //purpose : Returns an element based on all given nodes.
4768 //=======================================================================
4770 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4773 _preMeshInfo->FullLoadFromFile();
4775 CORBA::Long elemID(0);
4776 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4778 vector< const SMDS_MeshNode * > nn( nodes.length() );
4779 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4780 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4783 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4784 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4785 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4786 _impl->NbVolumes( ORDER_QUADRATIC )))
4787 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4789 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4794 //================================================================================
4796 * \brief Return elements including all given nodes.
4798 //================================================================================
4800 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4801 SMESH::ElementType elemType)
4804 _preMeshInfo->FullLoadFromFile();
4806 SMESH::long_array_var result = new SMESH::long_array();
4808 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4810 vector< const SMDS_MeshNode * > nn( nodes.length() );
4811 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4812 nn[i] = mesh->FindNode( nodes[i] );
4814 std::vector<const SMDS_MeshElement *> elems;
4815 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4816 result->length( elems.size() );
4817 for ( size_t i = 0; i < elems.size(); ++i )
4818 result[i] = elems[i]->GetID();
4820 return result._retn();
4823 //=============================================================================
4825 * Returns true if given element is polygon
4827 //=============================================================================
4829 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4832 _preMeshInfo->FullLoadFromFile();
4834 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4835 if ( aMeshDS == NULL ) return false;
4836 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4837 if(!elem) return false;
4838 return elem->IsPoly();
4842 //=============================================================================
4844 * Returns true if given element is quadratic
4846 //=============================================================================
4848 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4851 _preMeshInfo->FullLoadFromFile();
4853 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4854 if ( aMeshDS == NULL ) return false;
4855 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4856 if(!elem) return false;
4857 return elem->IsQuadratic();
4860 //=============================================================================
4862 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4864 //=============================================================================
4866 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4869 _preMeshInfo->FullLoadFromFile();
4871 if ( const SMDS_BallElement* ball =
4872 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4873 return ball->GetDiameter();
4878 //=============================================================================
4880 * Returns bary center for given element
4882 //=============================================================================
4884 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4887 _preMeshInfo->FullLoadFromFile();
4889 SMESH::double_array_var aResult = new SMESH::double_array();
4890 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4891 if ( aMeshDS == NULL )
4892 return aResult._retn();
4894 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4896 return aResult._retn();
4898 if(elem->GetType()==SMDSAbs_Volume) {
4899 SMDS_VolumeTool aTool;
4900 if(aTool.Set(elem)) {
4902 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4907 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4909 double x=0., y=0., z=0.;
4910 for(; anIt->more(); ) {
4912 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4926 return aResult._retn();
4929 //================================================================================
4931 * \brief Create a group of elements preventing computation of a sub-shape
4933 //================================================================================
4935 SMESH::ListOfGroups*
4936 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4937 const char* theGroupName )
4938 throw ( SALOME::SALOME_Exception )
4940 Unexpect aCatch(SALOME_SalomeException);
4942 if ( !theGroupName || strlen( theGroupName) == 0 )
4943 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4945 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4946 ::SMESH_MeshEditor::ElemFeatures elemType;
4948 // submesh by subshape id
4949 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4950 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4953 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4954 if ( error && error->HasBadElems() )
4956 // sort bad elements by type
4957 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4958 const list<const SMDS_MeshElement*>& badElems =
4959 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4960 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4961 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4962 for ( ; elemIt != elemEnd; ++elemIt )
4964 const SMDS_MeshElement* elem = *elemIt;
4965 if ( !elem ) continue;
4967 if ( elem->GetID() < 1 )
4969 // elem is a temporary element, make a real element
4970 vector< const SMDS_MeshNode* > nodes;
4971 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4972 while ( nIt->more() && elem )
4974 nodes.push_back( nIt->next() );
4975 if ( nodes.back()->GetID() < 1 )
4976 elem = 0; // a temporary element on temporary nodes
4980 ::SMESH_MeshEditor editor( _impl );
4981 elem = editor.AddElement( nodes, elemType.Init( elem ));
4985 elemsByType[ elem->GetType() ].push_back( elem );
4988 // how many groups to create?
4990 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4991 nbTypes += int( !elemsByType[ i ].empty() );
4992 groups->length( nbTypes );
4995 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4997 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4998 if ( elems.empty() ) continue;
5000 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5001 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5003 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
5004 SMESH::SMESH_Mesh_var mesh = _this();
5005 SALOMEDS::SObject_wrap aSO =
5006 _gen_i->PublishGroup( study, mesh, groups[ iG ],
5007 GEOM::GEOM_Object::_nil(), theGroupName);
5009 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5010 if ( !grp_i ) continue;
5012 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5013 for ( size_t iE = 0; iE < elems.size(); ++iE )
5014 grpDS->SMDSGroup().Add( elems[ iE ]);
5019 return groups._retn();
5022 //=============================================================================
5024 * Create and publish group servants if any groups were imported or created anyhow
5026 //=============================================================================
5028 void SMESH_Mesh_i::CreateGroupServants()
5030 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5031 SMESH::SMESH_Mesh_var aMesh = _this();
5034 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5035 while ( groupIt->more() )
5037 ::SMESH_Group* group = groupIt->next();
5038 int anId = group->GetGroupDS()->GetID();
5040 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5041 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5043 addedIDs.insert( anId );
5045 SMESH_GroupBase_i* aGroupImpl;
5047 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5048 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5050 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5051 shape = groupOnGeom->GetShape();
5054 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5057 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5058 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5059 aGroupImpl->Register();
5061 // register CORBA object for persistence
5062 int nextId = _gen_i->RegisterObject( groupVar );
5063 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5064 else { nextId = 0; } // avoid "unused variable" warning in release mode
5066 // publishing the groups in the study
5067 if ( !aStudy->_is_nil() ) {
5068 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5069 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5072 if ( !addedIDs.empty() )
5075 set<int>::iterator id = addedIDs.begin();
5076 for ( ; id != addedIDs.end(); ++id )
5078 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5079 int i = std::distance( _mapGroups.begin(), it );
5080 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5085 //=============================================================================
5087 * \brief Return groups cantained in _mapGroups by their IDs
5089 //=============================================================================
5091 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5093 int nbGroups = groupIDs.size();
5094 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5095 aList->length( nbGroups );
5097 list<int>::const_iterator ids = groupIDs.begin();
5098 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5100 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5101 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5102 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5104 aList->length( nbGroups );
5105 return aList._retn();
5108 //=============================================================================
5110 * \brief Return information about imported file
5112 //=============================================================================
5114 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5116 SMESH::MedFileInfo_var res( _medFileInfo );
5117 if ( !res.operator->() ) {
5118 res = new SMESH::MedFileInfo;
5120 res->fileSize = res->major = res->minor = res->release = -1;
5125 //=============================================================================
5127 * \brief Pass names of mesh groups from study to mesh DS
5129 //=============================================================================
5131 void SMESH_Mesh_i::checkGroupNames()
5133 int nbGrp = NbGroups();
5137 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5138 if ( aStudy->_is_nil() )
5139 return; // nothing to do
5141 SMESH::ListOfGroups* grpList = 0;
5142 // avoid dump of "GetGroups"
5144 // store python dump into a local variable inside local scope
5145 SMESH::TPythonDump pDump; // do not delete this line of code
5146 grpList = GetGroups();
5149 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5150 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5153 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5154 if ( aGrpSO->_is_nil() )
5156 // correct name of the mesh group if necessary
5157 const char* guiName = aGrpSO->GetName();
5158 if ( strcmp(guiName, aGrp->GetName()) )
5159 aGrp->SetName( guiName );
5163 //=============================================================================
5165 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5167 //=============================================================================
5168 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5170 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5174 //=============================================================================
5176 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5178 //=============================================================================
5180 char* SMESH_Mesh_i::GetParameters()
5182 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5185 //=============================================================================
5187 * \brief Returns list of notebook variables used for last Mesh operation
5189 //=============================================================================
5190 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5192 SMESH::string_array_var aResult = new SMESH::string_array();
5193 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5195 CORBA::String_var aParameters = GetParameters();
5196 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5197 if ( !aStudy->_is_nil()) {
5198 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5199 if ( aSections->length() > 0 ) {
5200 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5201 aResult->length( aVars.length() );
5202 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5203 aResult[i] = CORBA::string_dup( aVars[i] );
5207 return aResult._retn();
5210 //=======================================================================
5211 //function : GetTypes
5212 //purpose : Returns types of elements it contains
5213 //=======================================================================
5215 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5218 return _preMeshInfo->GetTypes();
5220 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5224 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5225 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5226 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5227 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5228 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5229 if (_impl->NbNodes() &&
5230 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5231 types->length( nbTypes );
5233 return types._retn();
5236 //=======================================================================
5237 //function : GetMesh
5238 //purpose : Returns self
5239 //=======================================================================
5241 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5243 return SMESH::SMESH_Mesh::_duplicate( _this() );
5246 //=======================================================================
5247 //function : IsMeshInfoCorrect
5248 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5249 // * happen if mesh data is not yet fully loaded from the file of study.
5250 //=======================================================================
5252 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5254 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5257 //=============================================================================
5259 * \brief Returns number of mesh elements per each \a EntityType
5261 //=============================================================================
5263 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5266 return _preMeshInfo->GetMeshInfo();
5268 SMESH::long_array_var aRes = new SMESH::long_array();
5269 aRes->length(SMESH::Entity_Last);
5270 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5272 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5274 return aRes._retn();
5275 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5276 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5277 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5278 return aRes._retn();
5281 //=============================================================================
5283 * \brief Returns number of mesh elements per each \a ElementType
5285 //=============================================================================
5287 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5289 SMESH::long_array_var aRes = new SMESH::long_array();
5290 aRes->length(SMESH::NB_ELEMENT_TYPES);
5291 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5294 const SMDS_MeshInfo* meshInfo = 0;
5296 meshInfo = _preMeshInfo;
5297 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5298 meshInfo = & meshDS->GetMeshInfo();
5301 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5302 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5304 return aRes._retn();
5307 //=============================================================================
5309 * Collect statistic of mesh elements given by iterator
5311 //=============================================================================
5313 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5314 SMESH::long_array& theInfo)
5316 if (!theItr) return;
5317 while (theItr->more())
5318 theInfo[ theItr->next()->GetEntityType() ]++;
5320 //=============================================================================
5322 * Returns mesh unstructed grid information.
5324 //=============================================================================
5326 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5328 SALOMEDS::TMPFile_var SeqFile;
5329 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5330 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5332 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5333 aWriter->WriteToOutputStringOn();
5334 aWriter->SetInputData(aGrid);
5335 aWriter->SetFileTypeToBinary();
5337 char* str = aWriter->GetOutputString();
5338 int size = aWriter->GetOutputStringLength();
5340 //Allocate octect buffer of required size
5341 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5342 //Copy ostrstream content to the octect buffer
5343 memcpy(OctetBuf, str, size);
5344 //Create and return TMPFile
5345 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5349 return SeqFile._retn();
5352 //=============================================================================
5353 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5354 * SMESH::ElementType type) */
5356 using namespace SMESH::Controls;
5357 //-----------------------------------------------------------------------------
5358 struct PredicateIterator : public SMDS_ElemIterator
5360 SMDS_ElemIteratorPtr _elemIter;
5361 PredicatePtr _predicate;
5362 const SMDS_MeshElement* _elem;
5364 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5365 PredicatePtr predicate):
5366 _elemIter(iterator), _predicate(predicate)
5374 virtual const SMDS_MeshElement* next()
5376 const SMDS_MeshElement* res = _elem;
5378 while ( _elemIter->more() && !_elem )
5380 _elem = _elemIter->next();
5381 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5388 //-----------------------------------------------------------------------------
5389 struct IDSourceIterator : public SMDS_ElemIterator
5391 const CORBA::Long* _idPtr;
5392 const CORBA::Long* _idEndPtr;
5393 SMESH::long_array_var _idArray;
5394 const SMDS_Mesh* _mesh;
5395 const SMDSAbs_ElementType _type;
5396 const SMDS_MeshElement* _elem;
5398 IDSourceIterator( const SMDS_Mesh* mesh,
5399 const CORBA::Long* ids,
5401 SMDSAbs_ElementType type):
5402 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5404 if ( _idPtr && nbIds && _mesh )
5407 IDSourceIterator( const SMDS_Mesh* mesh,
5408 SMESH::long_array* idArray,
5409 SMDSAbs_ElementType type):
5410 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5412 if ( idArray && _mesh )
5414 _idPtr = &_idArray[0];
5415 _idEndPtr = _idPtr + _idArray->length();
5423 virtual const SMDS_MeshElement* next()
5425 const SMDS_MeshElement* res = _elem;
5427 while ( _idPtr < _idEndPtr && !_elem )
5429 if ( _type == SMDSAbs_Node )
5431 _elem = _mesh->FindNode( *_idPtr++ );
5433 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5434 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5442 //-----------------------------------------------------------------------------
5444 struct NodeOfElemIterator : public SMDS_ElemIterator
5446 TColStd_MapOfInteger _checkedNodeIDs;
5447 SMDS_ElemIteratorPtr _elemIter;
5448 SMDS_ElemIteratorPtr _nodeIter;
5449 const SMDS_MeshElement* _node;
5451 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5453 if ( _elemIter && _elemIter->more() )
5455 _nodeIter = _elemIter->next()->nodesIterator();
5463 virtual const SMDS_MeshElement* next()
5465 const SMDS_MeshElement* res = _node;
5467 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5469 if ( _nodeIter->more() )
5471 _node = _nodeIter->next();
5472 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5477 _nodeIter = _elemIter->next()->nodesIterator();
5485 //=============================================================================
5487 * Return iterator on elements of given type in given object
5489 //=============================================================================
5491 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5492 SMESH::ElementType theType)
5494 SMDS_ElemIteratorPtr elemIt;
5495 bool typeOK = ( theType == SMESH::ALL );
5496 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5498 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5499 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5500 if ( !mesh_i ) return elemIt;
5501 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5503 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5505 elemIt = meshDS->elementsIterator( elemType );
5508 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5510 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5513 elemIt = sm->GetElements();
5514 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5516 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5517 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5521 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5523 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5524 if ( groupDS && ( elemType == groupDS->GetType() ||
5525 elemType == SMDSAbs_Node ||
5526 elemType == SMDSAbs_All ))
5528 elemIt = groupDS->GetElements();
5529 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5532 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5534 if ( filter_i->GetElementType() == theType ||
5535 elemType == SMDSAbs_Node ||
5536 elemType == SMDSAbs_All)
5538 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5539 if ( pred_i && pred_i->GetPredicate() )
5541 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5542 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5543 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5544 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5550 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5551 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5552 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5554 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5557 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5558 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5562 SMESH::long_array_var ids = theObject->GetIDs();
5563 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5565 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5568 if ( elemIt && elemIt->more() && !typeOK )
5570 if ( elemType == SMDSAbs_Node )
5572 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5576 elemIt = SMDS_ElemIteratorPtr();
5582 //=============================================================================
5583 namespace // Finding concurrent hypotheses
5584 //=============================================================================
5588 * \brief mapping of mesh dimension into shape type
5590 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5592 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5594 case 0: aType = TopAbs_VERTEX; break;
5595 case 1: aType = TopAbs_EDGE; break;
5596 case 2: aType = TopAbs_FACE; break;
5598 default:aType = TopAbs_SOLID; break;
5603 //-----------------------------------------------------------------------------
5605 * \brief Internal structure used to find concurrent submeshes
5607 * It represents a pair < submesh, concurrent dimension >, where
5608 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5609 * with another submesh. In other words, it is dimension of a hypothesis assigned
5616 int _dim; //!< a dimension the algo can build (concurrent dimension)
5617 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5618 TopTools_MapOfShape _shapeMap;
5619 SMESH_subMesh* _subMesh;
5620 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5622 //-----------------------------------------------------------------------------
5623 // Return the algorithm
5624 const SMESH_Algo* GetAlgo() const
5625 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5627 //-----------------------------------------------------------------------------
5629 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5631 const TopoDS_Shape& theShape)
5633 _subMesh = (SMESH_subMesh*)theSubMesh;
5634 SetShape( theDim, theShape );
5637 //-----------------------------------------------------------------------------
5639 void SetShape(const int theDim,
5640 const TopoDS_Shape& theShape)
5643 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5644 if (_dim >= _ownDim)
5645 _shapeMap.Add( theShape );
5647 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5648 for( ; anExp.More(); anExp.Next() )
5649 _shapeMap.Add( anExp.Current() );
5653 //-----------------------------------------------------------------------------
5654 //! Check sharing of sub-shapes
5655 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5656 const TopTools_MapOfShape& theToFind,
5657 const TopAbs_ShapeEnum theType)
5659 bool isShared = false;
5660 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5661 for (; !isShared && anItr.More(); anItr.Next() )
5663 const TopoDS_Shape aSubSh = anItr.Key();
5664 // check for case when concurrent dimensions are same
5665 isShared = theToFind.Contains( aSubSh );
5666 // check for sub-shape with concurrent dimension
5667 TopExp_Explorer anExp( aSubSh, theType );
5668 for ( ; !isShared && anExp.More(); anExp.Next() )
5669 isShared = theToFind.Contains( anExp.Current() );
5674 //-----------------------------------------------------------------------------
5675 //! check algorithms
5676 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5677 const SMESHDS_Hypothesis* theA2)
5679 if ( !theA1 || !theA2 ||
5680 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5681 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5682 return false; // one of the hypothesis is not algorithm
5683 // check algorithm names (should be equal)
5684 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5688 //-----------------------------------------------------------------------------
5689 //! Check if sub-shape hypotheses are concurrent
5690 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5692 if ( _subMesh == theOther->_subMesh )
5693 return false; // same sub-shape - should not be
5695 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5696 // any of the two submeshes is not on COMPOUND shape )
5697 // -> no concurrency
5698 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5699 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5700 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5701 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5702 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5705 // bool checkSubShape = ( _dim >= theOther->_dim )
5706 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5707 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5708 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5709 if ( !checkSubShape )
5712 // check algorithms to be same
5713 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5714 return true; // different algorithms -> concurrency !
5716 // check hypothesises for concurrence (skip first as algorithm)
5718 // pointers should be same, because it is referened from mesh hypothesis partition
5719 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5720 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5721 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5722 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5724 // the submeshes are concurrent if their algorithms has different parameters
5725 return nbSame != (int)theOther->_hypotheses.size() - 1;
5728 // Return true if algorithm of this SMESH_DimHyp is used if no
5729 // sub-mesh order is imposed by the user
5730 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5732 // NeedDiscreteBoundary() algo has a higher priority
5733 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5734 theOther->GetAlgo()->NeedDiscreteBoundary() )
5735 return !this->GetAlgo()->NeedDiscreteBoundary();
5737 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5740 }; // end of SMESH_DimHyp
5741 //-----------------------------------------------------------------------------
5743 typedef list<const SMESH_DimHyp*> TDimHypList;
5745 //-----------------------------------------------------------------------------
5747 void addDimHypInstance(const int theDim,
5748 const TopoDS_Shape& theShape,
5749 const SMESH_Algo* theAlgo,
5750 const SMESH_subMesh* theSubMesh,
5751 const list <const SMESHDS_Hypothesis*>& theHypList,
5752 TDimHypList* theDimHypListArr )
5754 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5755 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5756 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5757 dimHyp->_hypotheses.push_front(theAlgo);
5758 listOfdimHyp.push_back( dimHyp );
5761 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5762 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5763 theHypList.begin(), theHypList.end() );
5766 //-----------------------------------------------------------------------------
5767 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5768 TDimHypList& theListOfConcurr)
5770 if ( theListOfConcurr.empty() )
5772 theListOfConcurr.push_back( theDimHyp );
5776 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5777 while ( hypIt != theListOfConcurr.end() &&
5778 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5780 theListOfConcurr.insert( hypIt, theDimHyp );
5784 //-----------------------------------------------------------------------------
5785 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5786 const TDimHypList& theListOfDimHyp,
5787 TDimHypList& theListOfConcurrHyp,
5788 set<int>& theSetOfConcurrId )
5790 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5791 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5793 const SMESH_DimHyp* curDimHyp = *rIt;
5794 if ( curDimHyp == theDimHyp )
5795 break; // meet own dimHyp pointer in same dimension
5797 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5798 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5800 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5805 //-----------------------------------------------------------------------------
5806 void unionLists(TListOfInt& theListOfId,
5807 TListOfListOfInt& theListOfListOfId,
5810 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5811 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5813 continue; //skip already treated lists
5814 // check if other list has any same submesh object
5815 TListOfInt& otherListOfId = *it;
5816 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5817 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5820 // union two lists (from source into target)
5821 TListOfInt::iterator it2 = otherListOfId.begin();
5822 for ( ; it2 != otherListOfId.end(); it2++ ) {
5823 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5824 theListOfId.push_back(*it2);
5826 // clear source list
5827 otherListOfId.clear();
5830 //-----------------------------------------------------------------------------
5832 //! free memory allocated for dimension-hypothesis objects
5833 void removeDimHyps( TDimHypList* theArrOfList )
5835 for (int i = 0; i < 4; i++ ) {
5836 TDimHypList& listOfdimHyp = theArrOfList[i];
5837 TDimHypList::const_iterator it = listOfdimHyp.begin();
5838 for ( ; it != listOfdimHyp.end(); it++ )
5843 //-----------------------------------------------------------------------------
5845 * \brief find common submeshes with given submesh
5846 * \param theSubMeshList list of already collected submesh to check
5847 * \param theSubMesh given submesh to intersect with other
5848 * \param theCommonSubMeshes collected common submeshes
5850 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5851 const SMESH_subMesh* theSubMesh,
5852 set<const SMESH_subMesh*>& theCommon )
5856 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5857 for ( ; it != theSubMeshList.end(); it++ )
5858 theSubMesh->FindIntersection( *it, theCommon );
5859 theSubMeshList.push_back( theSubMesh );
5860 //theCommon.insert( theSubMesh );
5863 //-----------------------------------------------------------------------------
5864 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5866 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5867 for ( ; listsIt != smLists.end(); ++listsIt )
5869 const TListOfInt& smIDs = *listsIt;
5870 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5878 //=============================================================================
5880 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5882 //=============================================================================
5884 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5886 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5887 if ( isSubMeshInList( submeshID, anOrder ))
5890 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5891 return isSubMeshInList( submeshID, allConurrent );
5894 //=============================================================================
5896 * \brief Return submesh objects list in meshing order
5898 //=============================================================================
5900 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5902 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5904 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5906 return aResult._retn();
5908 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5909 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5910 anOrder.splice( anOrder.end(), allConurrent );
5913 TListOfListOfInt::iterator listIt = anOrder.begin();
5914 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5915 unionLists( *listIt, anOrder, listIndx + 1 );
5917 // convert submesh ids into interface instances
5918 // and dump command into python
5919 convertMeshOrder( anOrder, aResult, false );
5921 return aResult._retn();
5924 //=============================================================================
5926 * \brief Finds concurrent sub-meshes
5928 //=============================================================================
5930 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5932 TListOfListOfInt anOrder;
5933 ::SMESH_Mesh& mesh = GetImpl();
5935 // collect submeshes and detect concurrent algorithms and hypothesises
5936 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5938 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5939 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5940 ::SMESH_subMesh* sm = (*i_sm).second;
5942 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5944 // list of assigned hypothesises
5945 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5946 // Find out dimensions where the submesh can be concurrent.
5947 // We define the dimensions by algo of each of hypotheses in hypList
5948 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5949 for( ; hypIt != hypList.end(); hypIt++ ) {
5950 SMESH_Algo* anAlgo = 0;
5951 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5952 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5953 // hyp it-self is algo
5954 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5956 // try to find algorithm with help of sub-shapes
5957 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5958 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5959 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5962 continue; // no algorithm assigned to a current submesh
5964 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5965 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5967 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5968 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5969 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5971 } // end iterations on submesh
5973 // iterate on created dimension-hypotheses and check for concurrents
5974 for ( int i = 0; i < 4; i++ ) {
5975 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5976 // check for concurrents in own and other dimensions (step-by-step)
5977 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5978 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5979 const SMESH_DimHyp* dimHyp = *dhIt;
5980 TDimHypList listOfConcurr;
5981 set<int> setOfConcurrIds;
5982 // looking for concurrents and collect into own list
5983 for ( int j = i; j < 4; j++ )
5984 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5985 // check if any concurrents found
5986 if ( listOfConcurr.size() > 0 ) {
5987 // add own submesh to list of concurrent
5988 addInOrderOfPriority( dimHyp, listOfConcurr );
5989 list<int> listOfConcurrIds;
5990 TDimHypList::iterator hypIt = listOfConcurr.begin();
5991 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5992 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5993 anOrder.push_back( listOfConcurrIds );
5998 removeDimHyps(dimHypListArr);
6000 // now, minimize the number of concurrent groups
6001 // Here we assume that lists of submeshes can have same submesh
6002 // in case of multi-dimension algorithms, as result
6003 // list with common submesh has to be united into one list
6005 TListOfListOfInt::iterator listIt = anOrder.begin();
6006 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6007 unionLists( *listIt, anOrder, listIndx + 1 );
6013 //=============================================================================
6015 * \brief Set submesh object order
6016 * \param theSubMeshArray submesh array order
6018 //=============================================================================
6020 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6023 _preMeshInfo->ForgetOrLoad();
6026 ::SMESH_Mesh& mesh = GetImpl();
6028 TPythonDump aPythonDump; // prevent dump of called methods
6029 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6031 TListOfListOfInt subMeshOrder;
6032 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6034 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6035 TListOfInt subMeshIds;
6037 aPythonDump << ", ";
6038 aPythonDump << "[ ";
6039 // Collect subMeshes which should be clear
6040 // do it list-by-list, because modification of submesh order
6041 // take effect between concurrent submeshes only
6042 set<const SMESH_subMesh*> subMeshToClear;
6043 list<const SMESH_subMesh*> subMeshList;
6044 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6046 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6048 aPythonDump << ", ";
6049 aPythonDump << subMesh;
6050 subMeshIds.push_back( subMesh->GetId() );
6051 // detect common parts of submeshes
6052 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6053 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6055 aPythonDump << " ]";
6056 subMeshOrder.push_back( subMeshIds );
6058 // clear collected submeshes
6059 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6060 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6061 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6062 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6064 aPythonDump << " ])";
6066 mesh.SetMeshOrder( subMeshOrder );
6072 //=============================================================================
6074 * \brief Convert submesh ids into submesh interfaces
6076 //=============================================================================
6078 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6079 SMESH::submesh_array_array& theResOrder,
6080 const bool theIsDump)
6082 int nbSet = theIdsOrder.size();
6083 TPythonDump aPythonDump; // prevent dump of called methods
6085 aPythonDump << "[ ";
6086 theResOrder.length(nbSet);
6087 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6089 for( ; it != theIdsOrder.end(); it++ ) {
6090 // translate submesh identificators into submesh objects
6091 // takeing into account real number of concurrent lists
6092 const TListOfInt& aSubOrder = (*it);
6093 if (!aSubOrder.size())
6096 aPythonDump << "[ ";
6097 // convert shape indices into interfaces
6098 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6099 aResSubSet->length(aSubOrder.size());
6100 TListOfInt::const_iterator subIt = aSubOrder.begin();
6102 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6103 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6105 SMESH::SMESH_subMesh_var subMesh =
6106 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6109 aPythonDump << ", ";
6110 aPythonDump << subMesh;
6112 aResSubSet[ j++ ] = subMesh;
6115 aPythonDump << " ]";
6117 theResOrder[ listIndx++ ] = aResSubSet;
6119 // correct number of lists
6120 theResOrder.length( listIndx );
6123 // finilise python dump
6124 aPythonDump << " ]";
6125 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6129 namespace // utils used by SMESH_MeshPartDS
6132 * \brief Class used to access to protected data of SMDS_MeshInfo
6134 struct TMeshInfo : public SMDS_MeshInfo
6136 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6139 * \brief Element holing its ID only
6141 struct TElemID : public SMDS_LinearEdge
6143 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6147 //================================================================================
6149 // Implementation of SMESH_MeshPartDS
6151 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6152 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6154 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6155 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6158 _meshDS = mesh_i->GetImpl().GetMeshDS();
6160 SetPersistentId( _meshDS->GetPersistentId() );
6162 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6164 // <meshPart> is the whole mesh
6165 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6167 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6168 myGroupSet = _meshDS->GetGroups();
6173 SMESH::long_array_var anIDs = meshPart->GetIDs();
6174 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6175 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6177 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6178 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6179 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6184 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6185 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6186 if ( _elements[ e->GetType() ].insert( e ).second )
6189 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6190 while ( nIt->more() )
6192 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6193 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6200 ShapeToMesh( _meshDS->ShapeToMesh() );
6202 _meshDS = 0; // to enforce iteration on _elements and _nodes
6205 // -------------------------------------------------------------------------------------
6206 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6207 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6210 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6211 for ( ; partIt != meshPart.end(); ++partIt )
6212 if ( const SMDS_MeshElement * e = *partIt )
6213 if ( _elements[ e->GetType() ].insert( e ).second )
6216 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6217 while ( nIt->more() )
6219 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6220 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6226 // -------------------------------------------------------------------------------------
6227 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6229 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6231 TElemID elem( IDelem );
6232 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6233 if ( !_elements[ iType ].empty() )
6235 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6236 if ( it != _elements[ iType ].end() )
6241 // -------------------------------------------------------------------------------------
6242 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6244 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6246 typedef SMDS_SetIterator
6247 <const SMDS_MeshElement*,
6248 TIDSortedElemSet::const_iterator,
6249 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6250 SMDS_MeshElement::GeomFilter
6253 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6255 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6256 _elements[type].end(),
6257 SMDS_MeshElement::GeomFilter( geomType )));
6259 // -------------------------------------------------------------------------------------
6260 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6262 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6264 typedef SMDS_SetIterator
6265 <const SMDS_MeshElement*,
6266 TIDSortedElemSet::const_iterator,
6267 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6268 SMDS_MeshElement::EntityFilter
6271 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6273 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6274 _elements[type].end(),
6275 SMDS_MeshElement::EntityFilter( entity )));
6277 // -------------------------------------------------------------------------------------
6278 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6280 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6281 if ( type == SMDSAbs_All && !_meshDS )
6283 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6285 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6286 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6288 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6290 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6291 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6293 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6294 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6296 // -------------------------------------------------------------------------------------
6297 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6298 iterType SMESH_MeshPartDS::methName() const \
6300 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6301 return _meshDS ? _meshDS->methName() : iterType \
6302 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6304 // -------------------------------------------------------------------------------------
6305 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6306 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6307 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6308 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6309 #undef _GET_ITER_DEFINE
6311 // END Implementation of SMESH_MeshPartDS
6313 //================================================================================