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 )
1133 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1134 nodeIds.push_back( nIt->next()->GetID() );
1136 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1140 _impl->GetMeshDS()->RemoveElement( elems[i] );
1144 // Remove free nodes
1145 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1146 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1147 if ( n->NbInverseElements() == 0 )
1148 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1150 // Update Python script (theGroup must be alive for this)
1151 pyDump << SMESH::SMESH_Mesh_var(_this())
1152 << ".RemoveGroupWithContents( " << theGroup << " )";
1154 SMESH_CATCH( SMESH::throwCorbaException );
1157 //================================================================================
1159 * \brief Get the list of groups existing in the mesh
1160 * \retval SMESH::ListOfGroups * - list of groups
1162 //================================================================================
1164 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1166 Unexpect aCatch(SALOME_SalomeException);
1167 if (MYDEBUG) MESSAGE("GetGroups");
1169 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1172 TPythonDump aPythonDump;
1173 if ( !_mapGroups.empty() )
1175 aPythonDump << "[ ";
1177 aList->length( _mapGroups.size() );
1179 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1180 for ( ; it != _mapGroups.end(); it++ ) {
1181 if ( CORBA::is_nil( it->second )) continue;
1182 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1184 if (i > 1) aPythonDump << ", ";
1185 aPythonDump << it->second;
1189 catch(SALOME_Exception & S_ex) {
1190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1192 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1194 return aList._retn();
1197 //=============================================================================
1199 * Get number of groups existing in the mesh
1201 //=============================================================================
1203 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1205 Unexpect aCatch(SALOME_SalomeException);
1206 return _mapGroups.size();
1209 //=============================================================================
1211 * New group including all mesh elements present in initial groups is created.
1213 //=============================================================================
1215 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1216 SMESH::SMESH_GroupBase_ptr theGroup2,
1217 const char* theName )
1218 throw (SALOME::SALOME_Exception)
1220 SMESH::SMESH_Group_var aResGrp;
1224 _preMeshInfo->FullLoadFromFile();
1226 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1227 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1229 if ( theGroup1->GetType() != theGroup2->GetType() )
1230 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1235 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1236 if ( aResGrp->_is_nil() )
1237 return SMESH::SMESH_Group::_nil();
1239 aResGrp->AddFrom( theGroup1 );
1240 aResGrp->AddFrom( theGroup2 );
1242 // Update Python script
1243 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1244 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1246 SMESH_CATCH( SMESH::throwCorbaException );
1248 return aResGrp._retn();
1251 //=============================================================================
1253 * \brief New group including all mesh elements present in initial groups is created.
1254 * \param theGroups list of groups
1255 * \param theName name of group to be created
1256 * \return pointer to the new group
1258 //=============================================================================
1260 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1261 const char* theName )
1262 throw (SALOME::SALOME_Exception)
1264 SMESH::SMESH_Group_var aResGrp;
1267 _preMeshInfo->FullLoadFromFile();
1270 return SMESH::SMESH_Group::_nil();
1275 SMESH::ElementType aType = SMESH::ALL;
1276 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1278 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1279 if ( CORBA::is_nil( aGrp ) )
1281 if ( aType == SMESH::ALL )
1282 aType = aGrp->GetType();
1283 else if ( aType != aGrp->GetType() )
1284 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1287 if ( aType == SMESH::ALL )
1288 return SMESH::SMESH_Group::_nil();
1293 aResGrp = CreateGroup( aType, theName );
1294 if ( aResGrp->_is_nil() )
1295 return SMESH::SMESH_Group::_nil();
1297 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1298 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1300 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1301 if ( !CORBA::is_nil( aGrp ) )
1303 aResGrp->AddFrom( aGrp );
1304 if ( g > 0 ) pyDump << ", ";
1308 pyDump << " ], '" << theName << "' )";
1310 SMESH_CATCH( SMESH::throwCorbaException );
1312 return aResGrp._retn();
1315 //=============================================================================
1317 * New group is created. All mesh elements that are
1318 * present in both initial groups are added to the new one.
1320 //=============================================================================
1322 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1323 SMESH::SMESH_GroupBase_ptr theGroup2,
1324 const char* theName )
1325 throw (SALOME::SALOME_Exception)
1327 SMESH::SMESH_Group_var aResGrp;
1332 _preMeshInfo->FullLoadFromFile();
1334 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1335 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1337 if ( theGroup1->GetType() != theGroup2->GetType() )
1338 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1342 // Create Intersection
1343 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1344 if ( aResGrp->_is_nil() )
1345 return aResGrp._retn();
1347 SMESHDS_GroupBase* groupDS1 = 0;
1348 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1349 groupDS1 = grp_i->GetGroupDS();
1351 SMESHDS_GroupBase* groupDS2 = 0;
1352 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1353 groupDS2 = grp_i->GetGroupDS();
1355 SMESHDS_Group* resGroupDS = 0;
1356 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1357 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1359 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1361 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1362 while ( elemIt1->more() )
1364 const SMDS_MeshElement* e = elemIt1->next();
1365 if ( groupDS2->Contains( e ))
1366 resGroupDS->SMDSGroup().Add( e );
1369 // Update Python script
1370 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1371 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1373 SMESH_CATCH( SMESH::throwCorbaException );
1375 return aResGrp._retn();
1378 //=============================================================================
1380 \brief Intersect list of groups. New group is created. All mesh elements that
1381 are present in all initial groups simultaneously are added to the new one.
1382 \param theGroups list of groups
1383 \param theName name of group to be created
1384 \return pointer on the group
1386 //=============================================================================
1387 SMESH::SMESH_Group_ptr
1388 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1389 const char* theName )
1390 throw (SALOME::SALOME_Exception)
1392 SMESH::SMESH_Group_var aResGrp;
1397 _preMeshInfo->FullLoadFromFile();
1400 return SMESH::SMESH_Group::_nil();
1402 // check types and get SMESHDS_GroupBase's
1403 SMESH::ElementType aType = SMESH::ALL;
1404 vector< SMESHDS_GroupBase* > groupVec;
1405 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1407 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1408 if ( CORBA::is_nil( aGrp ) )
1410 if ( aType == SMESH::ALL )
1411 aType = aGrp->GetType();
1412 else if ( aType != aGrp->GetType() )
1413 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1416 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1417 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1419 if ( grpDS->IsEmpty() )
1424 groupVec.push_back( grpDS );
1427 if ( aType == SMESH::ALL ) // all groups are nil
1428 return SMESH::SMESH_Group::_nil();
1433 aResGrp = CreateGroup( aType, theName );
1435 SMESHDS_Group* resGroupDS = 0;
1436 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1437 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1438 if ( !resGroupDS || groupVec.empty() )
1439 return aResGrp._retn();
1442 size_t i, nb = groupVec.size();
1443 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1444 while ( elemIt1->more() )
1446 const SMDS_MeshElement* e = elemIt1->next();
1448 for ( i = 1; ( i < nb && inAll ); ++i )
1449 inAll = groupVec[i]->Contains( e );
1452 resGroupDS->SMDSGroup().Add( e );
1455 // Update Python script
1456 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1457 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1459 SMESH_CATCH( SMESH::throwCorbaException );
1461 return aResGrp._retn();
1464 //=============================================================================
1466 * New group is created. All mesh elements that are present in
1467 * a main group but is not present in a tool group are added to the new one
1469 //=============================================================================
1471 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1472 SMESH::SMESH_GroupBase_ptr theGroup2,
1473 const char* theName )
1474 throw (SALOME::SALOME_Exception)
1476 SMESH::SMESH_Group_var aResGrp;
1481 _preMeshInfo->FullLoadFromFile();
1483 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1484 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1486 if ( theGroup1->GetType() != theGroup2->GetType() )
1487 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1491 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1492 if ( aResGrp->_is_nil() )
1493 return aResGrp._retn();
1495 SMESHDS_GroupBase* groupDS1 = 0;
1496 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1497 groupDS1 = grp_i->GetGroupDS();
1499 SMESHDS_GroupBase* groupDS2 = 0;
1500 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1501 groupDS2 = grp_i->GetGroupDS();
1503 SMESHDS_Group* resGroupDS = 0;
1504 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1505 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1507 if ( groupDS1 && groupDS2 && resGroupDS )
1509 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1510 while ( elemIt1->more() )
1512 const SMDS_MeshElement* e = elemIt1->next();
1513 if ( !groupDS2->Contains( e ))
1514 resGroupDS->SMDSGroup().Add( e );
1517 // Update Python script
1518 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1519 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1521 SMESH_CATCH( SMESH::throwCorbaException );
1523 return aResGrp._retn();
1526 //=============================================================================
1528 \brief Cut lists of groups. New group is created. All mesh elements that are
1529 present in main groups but do not present in tool groups are added to the new one
1530 \param theMainGroups list of main groups
1531 \param theToolGroups list of tool groups
1532 \param theName name of group to be created
1533 \return pointer on the group
1535 //=============================================================================
1536 SMESH::SMESH_Group_ptr
1537 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1538 const SMESH::ListOfGroups& theToolGroups,
1539 const char* theName )
1540 throw (SALOME::SALOME_Exception)
1542 SMESH::SMESH_Group_var aResGrp;
1547 _preMeshInfo->FullLoadFromFile();
1550 return SMESH::SMESH_Group::_nil();
1552 // check types and get SMESHDS_GroupBase's
1553 SMESH::ElementType aType = SMESH::ALL;
1554 vector< SMESHDS_GroupBase* > toolGroupVec;
1555 vector< SMDS_ElemIteratorPtr > mainIterVec;
1557 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1559 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1560 if ( CORBA::is_nil( aGrp ) )
1562 if ( aType == SMESH::ALL )
1563 aType = aGrp->GetType();
1564 else if ( aType != aGrp->GetType() )
1565 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1567 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1568 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1569 if ( !grpDS->IsEmpty() )
1570 mainIterVec.push_back( grpDS->GetElements() );
1572 if ( aType == SMESH::ALL ) // all main groups are nil
1573 return SMESH::SMESH_Group::_nil();
1574 if ( mainIterVec.empty() ) // all main groups are empty
1575 return aResGrp._retn();
1577 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1579 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1580 if ( CORBA::is_nil( aGrp ) )
1582 if ( aType != aGrp->GetType() )
1583 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1585 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1586 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1587 toolGroupVec.push_back( grpDS );
1593 aResGrp = CreateGroup( aType, theName );
1595 SMESHDS_Group* resGroupDS = 0;
1596 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1597 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1599 return aResGrp._retn();
1602 size_t i, nb = toolGroupVec.size();
1603 SMDS_ElemIteratorPtr mainElemIt
1604 ( new SMDS_IteratorOnIterators
1605 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1606 while ( mainElemIt->more() )
1608 const SMDS_MeshElement* e = mainElemIt->next();
1610 for ( i = 0; ( i < nb && !isIn ); ++i )
1611 isIn = toolGroupVec[i]->Contains( e );
1614 resGroupDS->SMDSGroup().Add( e );
1617 // Update Python script
1618 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1619 << ".CutListOfGroups( " << theMainGroups << ", "
1620 << theToolGroups << ", '" << theName << "' )";
1622 SMESH_CATCH( SMESH::throwCorbaException );
1624 return aResGrp._retn();
1627 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1629 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1630 bool & toStopChecking )
1632 toStopChecking = ( nbCommon < nbChecked );
1633 return nbCommon == nbNodes;
1635 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1636 bool & toStopChecking )
1638 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1639 return nbCommon == nbCorners;
1641 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1642 bool & toStopChecking )
1644 return nbCommon > 0;
1646 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1647 bool & toStopChecking )
1649 return nbCommon >= (nbNodes+1) / 2;
1653 //=============================================================================
1655 * Create a group of entities basing on nodes of other groups.
1656 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1657 * \param [in] anElemType - a type of elements to include to the new group.
1658 * \param [in] theName - a name of the new group.
1659 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1660 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1661 * new group provided that it is based on nodes of an element of \a aListOfGroups
1662 * \return SMESH_Group - the created group
1664 // IMP 19939, bug 22010, IMP 22635
1665 //=============================================================================
1667 SMESH::SMESH_Group_ptr
1668 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1669 SMESH::ElementType theElemType,
1670 const char* theName,
1671 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1672 CORBA::Boolean theUnderlyingOnly)
1673 throw (SALOME::SALOME_Exception)
1675 SMESH::SMESH_Group_var aResGrp;
1679 _preMeshInfo->FullLoadFromFile();
1681 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1683 if ( !theName || !aMeshDS )
1684 return SMESH::SMESH_Group::_nil();
1686 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1688 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1689 SMESH_Comment nbCoNoStr( "SMESH.");
1690 switch ( theNbCommonNodes ) {
1691 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1692 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1693 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1694 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1695 default: return aResGrp._retn();
1697 int nbChecked, nbCommon, nbNodes, nbCorners;
1703 aResGrp = CreateGroup( theElemType, theName );
1704 if ( aResGrp->_is_nil() )
1705 return SMESH::SMESH_Group::_nil();
1707 SMESHDS_GroupBase* groupBaseDS =
1708 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1709 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1711 vector<bool> isNodeInGroups;
1713 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1715 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1716 if ( CORBA::is_nil( aGrp ) )
1718 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1719 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1722 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1723 if ( !elIt ) continue;
1725 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1727 while ( elIt->more() ) {
1728 const SMDS_MeshElement* el = elIt->next();
1729 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1730 while ( nIt->more() )
1731 resGroupCore.Add( nIt->next() );
1734 // get elements of theElemType based on nodes of every element of group
1735 else if ( theUnderlyingOnly )
1737 while ( elIt->more() )
1739 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1740 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1741 TIDSortedElemSet checkedElems;
1742 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1743 while ( nIt->more() )
1745 const SMDS_MeshNode* n = nIt->next();
1746 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1747 // check nodes of elements of theElemType around el
1748 while ( elOfTypeIt->more() )
1750 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1751 if ( !checkedElems.insert( elOfType ).second ) continue;
1752 nbNodes = elOfType->NbNodes();
1753 nbCorners = elOfType->NbCornerNodes();
1755 bool toStopChecking = false;
1756 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1757 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1758 if ( elNodes.count( nIt2->next() ) &&
1759 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1761 resGroupCore.Add( elOfType );
1768 // get all nodes of elements of groups
1771 while ( elIt->more() )
1773 const SMDS_MeshElement* el = elIt->next(); // an element of group
1774 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1775 while ( nIt->more() )
1777 const SMDS_MeshNode* n = nIt->next();
1778 if ( n->GetID() >= (int) isNodeInGroups.size() )
1779 isNodeInGroups.resize( n->GetID() + 1, false );
1780 isNodeInGroups[ n->GetID() ] = true;
1786 // Get elements of theElemType based on a certain number of nodes of elements of groups
1787 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1789 const SMDS_MeshNode* n;
1790 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1791 const int isNodeInGroupsSize = isNodeInGroups.size();
1792 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1794 if ( !isNodeInGroups[ iN ] ||
1795 !( n = aMeshDS->FindNode( iN )))
1798 // check nodes of elements of theElemType around n
1799 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1800 while ( elOfTypeIt->more() )
1802 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1803 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1808 nbNodes = elOfType->NbNodes();
1809 nbCorners = elOfType->NbCornerNodes();
1811 bool toStopChecking = false;
1812 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1813 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1815 const int nID = nIt->next()->GetID();
1816 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1817 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1819 resGroupCore.Add( elOfType );
1827 // Update Python script
1828 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1829 << ".CreateDimGroup( "
1830 << theGroups << ", " << theElemType << ", '" << theName << "', "
1831 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1833 SMESH_CATCH( SMESH::throwCorbaException );
1835 return aResGrp._retn();
1838 //================================================================================
1840 * \brief Remember GEOM group data
1842 //================================================================================
1844 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1845 CORBA::Object_ptr theSmeshObj)
1847 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1850 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1851 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1852 if ( groupSO->_is_nil() )
1855 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1856 GEOM::GEOM_IGroupOperations_wrap groupOp =
1857 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1858 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1861 _geomGroupData.push_back( TGeomGroupData() );
1862 TGeomGroupData & groupData = _geomGroupData.back();
1864 CORBA::String_var entry = groupSO->GetID();
1865 groupData._groupEntry = entry.in();
1867 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1868 groupData._indices.insert( ids[i] );
1870 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1871 // shape index in SMESHDS
1872 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1873 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1876 //================================================================================
1878 * Remove GEOM group data relating to removed smesh object
1880 //================================================================================
1882 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1884 list<TGeomGroupData>::iterator
1885 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1886 for ( ; data != dataEnd; ++data ) {
1887 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1888 _geomGroupData.erase( data );
1894 //================================================================================
1896 * \brief Return new group contents if it has been changed and update group data
1898 //================================================================================
1900 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1902 TopoDS_Shape newShape;
1905 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1906 if ( study->_is_nil() ) return newShape; // means "not changed"
1907 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1908 if ( !groupSO->_is_nil() )
1910 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1911 if ( CORBA::is_nil( groupObj )) return newShape;
1912 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1914 // get indices of group items
1915 set<int> curIndices;
1916 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1917 GEOM::GEOM_IGroupOperations_wrap groupOp =
1918 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1919 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1920 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1921 curIndices.insert( ids[i] );
1923 if ( groupData._indices == curIndices )
1924 return newShape; // group not changed
1927 groupData._indices = curIndices;
1929 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1930 if ( !geomClient ) return newShape;
1931 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1932 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1933 newShape = _gen_i->GeomObjectToShape( geomGroup );
1936 if ( newShape.IsNull() ) {
1937 // geom group becomes empty - return empty compound
1938 TopoDS_Compound compound;
1939 BRep_Builder().MakeCompound(compound);
1940 newShape = compound;
1947 //-----------------------------------------------------------------------------
1949 * \brief Storage of shape and index used in CheckGeomGroupModif()
1951 struct TIndexedShape
1954 TopoDS_Shape _shape;
1955 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1957 //-----------------------------------------------------------------------------
1959 * \brief Data to re-create a group on geometry
1961 struct TGroupOnGeomData
1965 SMDSAbs_ElementType _type;
1967 Quantity_Color _color;
1971 //=============================================================================
1973 * \brief Update data if geometry changes
1977 //=============================================================================
1979 void SMESH_Mesh_i::CheckGeomModif()
1981 if ( !_impl->HasShapeToMesh() ) return;
1983 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1984 if ( study->_is_nil() ) return;
1986 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1987 //if ( mainGO->_is_nil() ) return;
1989 // Update after group modification
1991 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1992 called by other mesh (IPAL52735) */
1993 mainGO->GetType() == GEOM_GROUP ||
1994 mainGO->GetTick() == _mainShapeTick )
1996 CheckGeomGroupModif();
2000 // Update after shape transformation like Translate
2002 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2003 if ( !geomClient ) return;
2004 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2005 if ( geomGen->_is_nil() ) return;
2007 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2008 geomClient->RemoveShapeFromBuffer( ior.in() );
2010 // Update data taking into account that
2011 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2014 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2015 if ( newShape.IsNull() )
2018 _mainShapeTick = mainGO->GetTick();
2020 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2022 // store data of groups on geometry
2023 vector< TGroupOnGeomData > groupsData;
2024 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2025 groupsData.reserve( groups.size() );
2026 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2027 for ( ; g != groups.end(); ++g )
2028 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2030 TGroupOnGeomData data;
2031 data._oldID = group->GetID();
2032 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2033 data._type = group->GetType();
2034 data._name = group->GetStoreName();
2035 data._color = group->GetColor();
2036 groupsData.push_back( data );
2038 // store assigned hypotheses
2039 vector< pair< int, THypList > > ids2Hyps;
2040 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2041 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2043 const TopoDS_Shape& s = s2hyps.Key();
2044 const THypList& hyps = s2hyps.ChangeValue();
2045 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2048 // change shape to mesh
2049 int oldNbSubShapes = meshDS->MaxShapeIndex();
2050 _impl->ShapeToMesh( TopoDS_Shape() );
2051 _impl->ShapeToMesh( newShape );
2053 // re-add shapes of geom groups
2054 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2055 for ( ; data != _geomGroupData.end(); ++data )
2057 TopoDS_Shape newShape = newGroupShape( *data );
2058 if ( !newShape.IsNull() )
2060 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2062 TopoDS_Compound compound;
2063 BRep_Builder().MakeCompound( compound );
2064 BRep_Builder().Add( compound, newShape );
2065 newShape = compound;
2067 _impl->GetSubMesh( newShape );
2070 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2071 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2072 SALOME::INTERNAL_ERROR );
2074 // re-assign hypotheses
2075 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2077 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2078 const THypList& hyps = ids2Hyps[i].second;
2079 THypList::const_iterator h = hyps.begin();
2080 for ( ; h != hyps.end(); ++h )
2081 _impl->AddHypothesis( s, (*h)->GetID() );
2085 for ( size_t i = 0; i < groupsData.size(); ++i )
2087 const TGroupOnGeomData& data = groupsData[i];
2089 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2090 if ( i2g == _mapGroups.end() ) continue;
2092 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2093 if ( !gr_i ) continue;
2096 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2097 meshDS->IndexToShape( data._shapeID ));
2100 _mapGroups.erase( i2g );
2104 g->GetGroupDS()->SetColor( data._color );
2105 gr_i->changeLocalId( id );
2106 _mapGroups[ id ] = i2g->second;
2107 if ( data._oldID != id )
2108 _mapGroups.erase( i2g );
2112 // update _mapSubMesh
2113 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2114 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2115 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2119 //=============================================================================
2121 * \brief Update objects depending on changed geom groups
2123 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2124 * issue 0020210: Update of a smesh group after modification of the associated geom group
2126 //=============================================================================
2128 void SMESH_Mesh_i::CheckGeomGroupModif()
2130 if ( !_impl->HasShapeToMesh() ) return;
2132 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2133 if ( study->_is_nil() ) return;
2135 CORBA::Long nbEntities = NbNodes() + NbElements();
2137 // Check if group contents changed
2139 typedef map< string, TopoDS_Shape > TEntry2Geom;
2140 TEntry2Geom newGroupContents;
2142 list<TGeomGroupData>::iterator
2143 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2144 for ( ; data != dataEnd; ++data )
2146 pair< TEntry2Geom::iterator, bool > it_new =
2147 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2148 bool processedGroup = !it_new.second;
2149 TopoDS_Shape& newShape = it_new.first->second;
2150 if ( !processedGroup )
2151 newShape = newGroupShape( *data );
2152 if ( newShape.IsNull() )
2153 continue; // no changes
2156 _preMeshInfo->ForgetOrLoad();
2158 if ( processedGroup ) { // update group indices
2159 list<TGeomGroupData>::iterator data2 = data;
2160 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2161 data->_indices = data2->_indices;
2164 // Update SMESH objects according to new GEOM group contents
2166 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2167 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2169 int oldID = submesh->GetId();
2170 if ( !_mapSubMeshIor.count( oldID ))
2172 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2174 // update hypotheses
2175 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2176 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2177 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2179 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2180 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2182 // care of submeshes
2183 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2184 int newID = newSubmesh->GetId();
2185 if ( newID != oldID ) {
2186 _mapSubMesh [ newID ] = newSubmesh;
2187 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2188 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2189 _mapSubMesh. erase(oldID);
2190 _mapSubMesh_i. erase(oldID);
2191 _mapSubMeshIor.erase(oldID);
2192 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2197 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2198 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2199 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2201 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2203 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2204 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2205 ds->SetShape( newShape );
2210 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2211 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2213 // Remove groups and submeshes basing on removed sub-shapes
2215 TopTools_MapOfShape newShapeMap;
2216 TopoDS_Iterator shapeIt( newShape );
2217 for ( ; shapeIt.More(); shapeIt.Next() )
2218 newShapeMap.Add( shapeIt.Value() );
2220 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2221 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2223 if ( newShapeMap.Contains( shapeIt.Value() ))
2225 TopTools_IndexedMapOfShape oldShapeMap;
2226 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2227 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2229 const TopoDS_Shape& oldShape = oldShapeMap(i);
2230 int oldInd = meshDS->ShapeToIndex( oldShape );
2232 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2233 if ( i_smIor != _mapSubMeshIor.end() ) {
2234 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2237 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2238 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2240 // check if a group bases on oldInd shape
2241 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2242 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2243 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2244 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2246 RemoveGroup( i_grp->second ); // several groups can base on same shape
2247 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2252 // Reassign hypotheses and update groups after setting the new shape to mesh
2254 // collect anassigned hypotheses
2255 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2256 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2257 TShapeHypList assignedHyps;
2258 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2260 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2261 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2262 if ( !hyps.empty() ) {
2263 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2264 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2265 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2268 // collect shapes supporting groups
2269 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2270 TShapeTypeList groupData;
2271 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2272 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2273 for ( ; grIt != groups.end(); ++grIt )
2275 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2277 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2279 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2281 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2282 _impl->ShapeToMesh( newShape );
2284 // reassign hypotheses
2285 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2286 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2288 TIndexedShape& geom = indS_hyps->first;
2289 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2290 int oldID = geom._index;
2291 int newID = meshDS->ShapeToIndex( geom._shape );
2292 if ( oldID == 1 ) { // main shape
2294 geom._shape = newShape;
2298 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2299 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2300 // care of sub-meshes
2301 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2302 if ( newID != oldID ) {
2303 _mapSubMesh [ newID ] = newSubmesh;
2304 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2305 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2306 _mapSubMesh. erase(oldID);
2307 _mapSubMesh_i. erase(oldID);
2308 _mapSubMeshIor.erase(oldID);
2309 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2313 TShapeTypeList::iterator geomType = groupData.begin();
2314 for ( ; geomType != groupData.end(); ++geomType )
2316 const TIndexedShape& geom = geomType->first;
2317 int oldID = geom._index;
2318 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2321 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2322 CORBA::String_var name = groupSO->GetName();
2324 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2326 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2327 group_i->changeLocalId( newID );
2330 break; // everything has been updated
2333 } // loop on group data
2337 CORBA::Long newNbEntities = NbNodes() + NbElements();
2338 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2339 if ( newNbEntities != nbEntities )
2341 // Add all SObjects with icons to soToUpdateIcons
2342 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2344 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2345 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2346 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2348 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2349 i_gr != _mapGroups.end(); ++i_gr ) // groups
2350 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2353 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2354 for ( ; so != soToUpdateIcons.end(); ++so )
2355 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2358 //=============================================================================
2360 * \brief Create standalone group from a group on geometry or filter
2362 //=============================================================================
2364 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2365 throw (SALOME::SALOME_Exception)
2367 SMESH::SMESH_Group_var aGroup;
2372 _preMeshInfo->FullLoadFromFile();
2374 if ( theGroup->_is_nil() )
2375 return aGroup._retn();
2377 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2379 return aGroup._retn();
2381 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2383 const int anId = aGroupToRem->GetLocalID();
2384 if ( !_impl->ConvertToStandalone( anId ) )
2385 return aGroup._retn();
2386 removeGeomGroupData( theGroup );
2388 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2390 // remove old instance of group from own map
2391 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2392 _mapGroups.erase( anId );
2394 SALOMEDS::StudyBuilder_var builder;
2395 SALOMEDS::SObject_wrap aGroupSO;
2396 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2397 if ( !aStudy->_is_nil() ) {
2398 builder = aStudy->NewBuilder();
2399 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2400 if ( !aGroupSO->_is_nil() )
2402 // remove reference to geometry
2403 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2404 for ( ; chItr->More(); chItr->Next() )
2405 // Remove group's child SObject
2406 builder->RemoveObject( chItr->Value() );
2408 // Update Python script
2409 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2410 << ".ConvertToStandalone( " << aGroupSO << " )";
2412 // change icon of Group on Filter
2415 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2416 const int isEmpty = ( elemTypes->length() == 0 );
2419 SALOMEDS::GenericAttribute_wrap anAttr =
2420 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2421 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2422 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2428 // remember new group in own map
2429 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2430 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2432 // register CORBA object for persistence
2433 _gen_i->RegisterObject( aGroup );
2435 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2436 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2437 //aGroup->Register();
2438 aGroupToRem->UnRegister();
2440 SMESH_CATCH( SMESH::throwCorbaException );
2442 return aGroup._retn();
2445 //=============================================================================
2449 //=============================================================================
2451 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2453 if(MYDEBUG) MESSAGE( "createSubMesh" );
2454 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2455 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2458 SMESH_subMesh_i * subMeshServant;
2461 subMeshId = mySubMesh->GetId();
2462 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2464 else // "invalid sub-mesh"
2466 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2467 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2468 if ( _mapSubMesh.empty() )
2471 subMeshId = _mapSubMesh.begin()->first - 1;
2472 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2475 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2477 _mapSubMesh [subMeshId] = mySubMesh;
2478 _mapSubMesh_i [subMeshId] = subMeshServant;
2479 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2481 subMeshServant->Register();
2483 // register CORBA object for persistence
2484 int nextId = _gen_i->RegisterObject( subMesh );
2485 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2486 else { nextId = 0; } // avoid "unused variable" warning
2488 // to track changes of GEOM groups
2489 if ( subMeshId > 0 )
2490 addGeomGroupData( theSubShapeObject, subMesh );
2492 return subMesh._retn();
2495 //=======================================================================
2496 //function : getSubMesh
2498 //=======================================================================
2500 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2502 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2503 if ( it == _mapSubMeshIor.end() )
2504 return SMESH::SMESH_subMesh::_nil();
2506 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2509 //=============================================================================
2513 //=============================================================================
2515 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2516 GEOM::GEOM_Object_ptr theSubShapeObject )
2518 bool isHypChanged = false;
2519 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2520 return isHypChanged;
2522 const int subMeshId = theSubMesh->GetId();
2524 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2526 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end() &&
2527 _mapSubMesh[ subMeshId ])
2529 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2532 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2533 isHypChanged = !hyps.empty();
2534 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2535 for ( ; hyp != hyps.end(); ++hyp )
2536 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2543 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2544 isHypChanged = ( aHypList->length() > 0 );
2545 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2546 removeHypothesis( theSubShapeObject, aHypList[i] );
2549 catch( const SALOME::SALOME_Exception& ) {
2550 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2552 removeGeomGroupData( theSubShapeObject );
2556 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2557 if ( id_smi != _mapSubMesh_i.end() )
2558 id_smi->second->UnRegister();
2560 // remove a CORBA object
2561 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2562 if ( id_smptr != _mapSubMeshIor.end() )
2563 SMESH::SMESH_subMesh_var( id_smptr->second );
2565 _mapSubMesh.erase(subMeshId);
2566 _mapSubMesh_i.erase(subMeshId);
2567 _mapSubMeshIor.erase(subMeshId);
2569 return isHypChanged;
2572 //=============================================================================
2576 //=============================================================================
2578 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2579 const char* theName,
2580 const TopoDS_Shape& theShape,
2581 const SMESH_PredicatePtr& thePredicate )
2583 std::string newName;
2584 if ( !theName || !theName[0] )
2586 std::set< std::string > presentNames;
2587 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2588 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2590 CORBA::String_var name = i_gr->second->GetName();
2591 presentNames.insert( name.in() );
2594 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2595 } while ( !presentNames.insert( newName ).second );
2596 theName = newName.c_str();
2599 SMESH::SMESH_GroupBase_var aGroup;
2600 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2602 SMESH_GroupBase_i* aGroupImpl;
2603 if ( !theShape.IsNull() )
2604 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2605 else if ( thePredicate )
2606 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2608 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2610 aGroup = aGroupImpl->_this();
2611 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2612 aGroupImpl->Register();
2614 // register CORBA object for persistence
2615 int nextId = _gen_i->RegisterObject( aGroup );
2616 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2617 else { nextId = 0; } // avoid "unused variable" warning in release mode
2619 // to track changes of GEOM groups
2620 if ( !theShape.IsNull() ) {
2621 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2622 addGeomGroupData( geom, aGroup );
2625 return aGroup._retn();
2628 //=============================================================================
2630 * SMESH_Mesh_i::removeGroup
2632 * Should be called by ~SMESH_Group_i()
2634 //=============================================================================
2636 void SMESH_Mesh_i::removeGroup( const int theId )
2638 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2639 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2640 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2641 _mapGroups.erase( theId );
2642 removeGeomGroupData( group );
2643 if ( !_impl->RemoveGroup( theId ))
2645 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2646 RemoveGroup( group );
2648 group->UnRegister();
2652 //=============================================================================
2656 //=============================================================================
2658 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2659 throw(SALOME::SALOME_Exception)
2661 SMESH::log_array_var aLog;
2665 _preMeshInfo->FullLoadFromFile();
2667 list < SMESHDS_Command * >logDS = _impl->GetLog();
2668 aLog = new SMESH::log_array;
2670 int lg = logDS.size();
2673 list < SMESHDS_Command * >::iterator its = logDS.begin();
2674 while(its != logDS.end()){
2675 SMESHDS_Command *com = *its;
2676 int comType = com->GetType();
2678 int lgcom = com->GetNumber();
2680 const list < int >&intList = com->GetIndexes();
2681 int inum = intList.size();
2683 list < int >::const_iterator ii = intList.begin();
2684 const list < double >&coordList = com->GetCoords();
2685 int rnum = coordList.size();
2687 list < double >::const_iterator ir = coordList.begin();
2688 aLog[indexLog].commandType = comType;
2689 aLog[indexLog].number = lgcom;
2690 aLog[indexLog].coords.length(rnum);
2691 aLog[indexLog].indexes.length(inum);
2692 for(int i = 0; i < rnum; i++){
2693 aLog[indexLog].coords[i] = *ir;
2694 //MESSAGE(" "<<i<<" "<<ir.Value());
2697 for(int i = 0; i < inum; i++){
2698 aLog[indexLog].indexes[i] = *ii;
2699 //MESSAGE(" "<<i<<" "<<ii.Value());
2708 SMESH_CATCH( SMESH::throwCorbaException );
2710 return aLog._retn();
2714 //=============================================================================
2718 //=============================================================================
2720 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2724 SMESH_CATCH( SMESH::throwCorbaException );
2727 //=============================================================================
2731 //=============================================================================
2733 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2738 //=============================================================================
2742 //=============================================================================
2744 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2749 //=============================================================================
2752 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2753 // issue 0020918: groups removal is caused by hyp modification
2754 // issue 0021208: to forget not loaded mesh data at hyp modification
2755 struct TCallUp_i : public SMESH_Mesh::TCallUp
2757 SMESH_Mesh_i* _mesh;
2758 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2759 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2760 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
2761 virtual void Load () { _mesh->Load(); }
2765 //================================================================================
2767 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2769 //================================================================================
2771 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
2774 _preMeshInfo->ForgetOrLoad();
2776 // mark a hypothesis as valid after edition
2777 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2778 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent( study );
2779 SALOMEDS::SObject_wrap hypRoot;
2780 if ( !smeshComp->_is_nil() &&
2781 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
2783 SALOMEDS::ChildIterator_wrap anIter = study->NewChildIterator( hypRoot );
2784 for ( ; anIter->More(); anIter->Next() )
2786 SALOMEDS::SObject_wrap hypSO = anIter->Value();
2787 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
2788 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
2789 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
2790 _gen_i->HighLightInvalid( hyp, false );
2795 //=============================================================================
2799 //=============================================================================
2801 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2803 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2806 _impl->SetCallUp( new TCallUp_i(this));
2809 //=============================================================================
2813 //=============================================================================
2815 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2817 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2821 //=============================================================================
2823 * Return mesh editor
2825 //=============================================================================
2827 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2828 throw (SALOME::SALOME_Exception)
2830 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2834 _preMeshInfo->FullLoadFromFile();
2836 // Create MeshEditor
2838 _editor = new SMESH_MeshEditor_i( this, false );
2839 aMeshEdVar = _editor->_this();
2841 // Update Python script
2842 TPythonDump() << _editor << " = "
2843 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2845 SMESH_CATCH( SMESH::throwCorbaException );
2847 return aMeshEdVar._retn();
2850 //=============================================================================
2852 * Return mesh edition previewer
2854 //=============================================================================
2856 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2857 throw (SALOME::SALOME_Exception)
2859 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2863 _preMeshInfo->FullLoadFromFile();
2865 if ( !_previewEditor )
2866 _previewEditor = new SMESH_MeshEditor_i( this, true );
2867 aMeshEdVar = _previewEditor->_this();
2869 SMESH_CATCH( SMESH::throwCorbaException );
2871 return aMeshEdVar._retn();
2874 //================================================================================
2876 * \brief Return true if the mesh has been edited since a last total re-compute
2877 * and those modifications may prevent successful partial re-compute
2879 //================================================================================
2881 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2883 Unexpect aCatch(SALOME_SalomeException);
2884 return _impl->HasModificationsToDiscard();
2887 //================================================================================
2889 * \brief Returns a random unique color
2891 //================================================================================
2893 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2895 const int MAX_ATTEMPTS = 100;
2897 double tolerance = 0.5;
2898 SALOMEDS::Color col;
2902 // generate random color
2903 double red = (double)rand() / RAND_MAX;
2904 double green = (double)rand() / RAND_MAX;
2905 double blue = (double)rand() / RAND_MAX;
2906 // check existence in the list of the existing colors
2907 bool matched = false;
2908 std::list<SALOMEDS::Color>::const_iterator it;
2909 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2910 SALOMEDS::Color color = *it;
2911 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2912 matched = tol < tolerance;
2914 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2915 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2923 //=============================================================================
2925 * Sets auto-color mode. If it is on, groups get unique random colors
2927 //=============================================================================
2929 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2931 Unexpect aCatch(SALOME_SalomeException);
2932 _impl->SetAutoColor(theAutoColor);
2934 TPythonDump pyDump; // not to dump group->SetColor() from below code
2935 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2937 std::list<SALOMEDS::Color> aReservedColors;
2938 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2939 for ( ; it != _mapGroups.end(); it++ ) {
2940 if ( CORBA::is_nil( it->second )) continue;
2941 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2942 it->second->SetColor( aColor );
2943 aReservedColors.push_back( aColor );
2947 //=============================================================================
2949 * Returns true if auto-color mode is on
2951 //=============================================================================
2953 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2955 Unexpect aCatch(SALOME_SalomeException);
2956 return _impl->GetAutoColor();
2959 //=============================================================================
2961 * Checks if there are groups with equal names
2963 //=============================================================================
2965 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2967 return _impl->HasDuplicatedGroupNamesMED();
2970 //================================================================================
2972 * \brief Care of a file before exporting mesh into it
2974 //================================================================================
2976 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2978 SMESH_File aFile( file );
2980 if (aFile.exists()) {
2981 // existing filesystem node
2982 if ( !aFile.isDirectory() ) {
2983 if ( aFile.openForWriting() ) {
2984 if ( overwrite && ! aFile.remove()) {
2985 msg << "Can't replace " << aFile.getName();
2988 msg << "Can't write into " << aFile.getName();
2991 msg << "Location " << aFile.getName() << " is not a file";
2995 // nonexisting file; check if it can be created
2996 if ( !aFile.openForWriting() ) {
2997 msg << "You cannot create the file "
2999 << ". Check the directory existence and access rights";
3007 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3011 //================================================================================
3013 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3014 * \param file - file name
3015 * \param overwrite - to erase the file or not
3016 * \retval string - mesh name
3018 //================================================================================
3020 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3021 CORBA::Boolean overwrite)
3024 PrepareForWriting(file, overwrite);
3025 string aMeshName = "Mesh";
3026 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3027 if ( !aStudy->_is_nil() ) {
3028 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
3029 if ( !aMeshSO->_is_nil() ) {
3030 CORBA::String_var name = aMeshSO->GetName();
3032 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3033 if ( !aStudy->GetProperties()->IsLocked() )
3035 SALOMEDS::GenericAttribute_wrap anAttr;
3036 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3037 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3038 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3039 ASSERT(!aFileName->_is_nil());
3040 aFileName->SetValue(file);
3041 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3042 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3043 ASSERT(!aFileType->_is_nil());
3044 aFileType->SetValue("FICHIERMED");
3048 // Update Python script
3049 // set name of mesh before export
3050 TPythonDump() << _gen_i << ".SetName("
3051 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3053 // check names of groups
3059 //================================================================================
3061 * \brief Export to med file
3063 //================================================================================
3065 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3066 CORBA::Boolean auto_groups,
3067 SMESH::MED_VERSION theVersion,
3068 CORBA::Boolean overwrite,
3069 CORBA::Boolean autoDimension)
3070 throw(SALOME::SALOME_Exception)
3072 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3075 _preMeshInfo->FullLoadFromFile();
3077 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3078 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3080 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3081 << file << "', " << auto_groups << ", "
3082 << theVersion << ", " << overwrite << ", "
3083 << autoDimension << " )";
3085 SMESH_CATCH( SMESH::throwCorbaException );
3088 //================================================================================
3090 * \brief Export a mesh to a med file
3092 //================================================================================
3094 void SMESH_Mesh_i::ExportToMED (const char* file,
3095 CORBA::Boolean auto_groups,
3096 SMESH::MED_VERSION theVersion)
3097 throw(SALOME::SALOME_Exception)
3099 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3100 ExportToMEDX(file,auto_groups,theVersion,true);
3103 //================================================================================
3105 * \brief Export a mesh to a med file
3107 //================================================================================
3109 void SMESH_Mesh_i::ExportMED (const char* file,
3110 CORBA::Boolean auto_groups)
3111 throw(SALOME::SALOME_Exception)
3113 //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST);
3114 ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true);
3117 //================================================================================
3119 * \brief Export a mesh to a SAUV file
3121 //================================================================================
3123 void SMESH_Mesh_i::ExportSAUV (const char* file,
3124 CORBA::Boolean auto_groups)
3125 throw(SALOME::SALOME_Exception)
3127 Unexpect aCatch(SALOME_SalomeException);
3129 _preMeshInfo->FullLoadFromFile();
3131 string aMeshName = prepareMeshNameAndGroups(file, true);
3132 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3133 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3134 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3138 //================================================================================
3140 * \brief Export a mesh to a DAT file
3142 //================================================================================
3144 void SMESH_Mesh_i::ExportDAT (const char *file)
3145 throw(SALOME::SALOME_Exception)
3147 Unexpect aCatch(SALOME_SalomeException);
3149 _preMeshInfo->FullLoadFromFile();
3151 // Update Python script
3152 // check names of groups
3154 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3157 PrepareForWriting(file);
3158 _impl->ExportDAT(file);
3161 //================================================================================
3163 * \brief Export a mesh to an UNV file
3165 //================================================================================
3167 void SMESH_Mesh_i::ExportUNV (const char *file)
3168 throw(SALOME::SALOME_Exception)
3170 Unexpect aCatch(SALOME_SalomeException);
3172 _preMeshInfo->FullLoadFromFile();
3174 // Update Python script
3175 // check names of groups
3177 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3180 PrepareForWriting(file);
3181 _impl->ExportUNV(file);
3184 //================================================================================
3186 * \brief Export a mesh to an STL file
3188 //================================================================================
3190 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3191 throw(SALOME::SALOME_Exception)
3193 Unexpect aCatch(SALOME_SalomeException);
3195 _preMeshInfo->FullLoadFromFile();
3197 // Update Python script
3198 // check names of groups
3200 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3201 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3203 CORBA::String_var name;
3204 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3205 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() );
3206 if ( !so->_is_nil() )
3207 name = so->GetName();
3210 PrepareForWriting( file );
3211 _impl->ExportSTL( file, isascii, name.in() );
3214 //================================================================================
3216 * \brief Export a part of mesh to a med file
3218 //================================================================================
3220 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3222 CORBA::Boolean auto_groups,
3223 SMESH::MED_VERSION version,
3224 CORBA::Boolean overwrite,
3225 CORBA::Boolean autoDimension,
3226 const GEOM::ListOfFields& fields,
3227 const char* geomAssocFields)
3228 throw (SALOME::SALOME_Exception)
3232 _preMeshInfo->FullLoadFromFile();
3235 bool have0dField = false;
3236 if ( fields.length() > 0 )
3238 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3239 if ( shapeToMesh->_is_nil() )
3240 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3242 for ( size_t i = 0; i < fields.length(); ++i )
3244 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3245 THROW_SALOME_CORBA_EXCEPTION
3246 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3247 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3248 if ( fieldShape->_is_nil() )
3249 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3250 if ( !fieldShape->IsSame( shapeToMesh ) )
3251 THROW_SALOME_CORBA_EXCEPTION
3252 ( "Field defined not on shape", SALOME::BAD_PARAM);
3253 if ( fields[i]->GetDimension() == 0 )
3256 if ( geomAssocFields )
3257 for ( int i = 0; geomAssocFields[i]; ++i )
3258 switch ( geomAssocFields[i] ) {
3259 case 'v':case 'e':case 'f':case 's': break;
3260 case 'V':case 'E':case 'F':case 'S': break;
3261 default: THROW_SALOME_CORBA_EXCEPTION
3262 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3266 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3270 string aMeshName = "Mesh";
3271 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3272 if ( CORBA::is_nil( meshPart ) ||
3273 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3275 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3276 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3277 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3278 meshDS = _impl->GetMeshDS();
3283 _preMeshInfo->FullLoadFromFile();
3285 PrepareForWriting(file, overwrite);
3287 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3288 if ( !aStudy->_is_nil() ) {
3289 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3290 if ( !SO->_is_nil() ) {
3291 CORBA::String_var name = SO->GetName();
3295 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3296 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3297 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3298 meshDS = tmpDSDeleter._obj = partDS;
3303 if ( _impl->HasShapeToMesh() )
3305 DriverMED_W_Field fieldWriter;
3306 fieldWriter.SetFile( file );
3307 fieldWriter.SetMeshName( aMeshName );
3308 fieldWriter.AddODOnVertices( have0dField );
3310 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3314 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3315 goList->length( fields.length() );
3316 for ( size_t i = 0; i < fields.length(); ++i )
3318 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3321 TPythonDump() << _this() << ".ExportPartToMED( "
3322 << meshPart << ", r'" << file << "', "
3323 << auto_groups << ", " << version << ", " << overwrite << ", "
3324 << autoDimension << ", " << goList
3325 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3327 SMESH_CATCH( SMESH::throwCorbaException );
3330 //================================================================================
3332 * Write GEOM fields to MED file
3334 //================================================================================
3336 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3337 SMESHDS_Mesh* meshDS,
3338 const GEOM::ListOfFields& fields,
3339 const char* geomAssocFields)
3341 #define METH "SMESH_Mesh_i::exportMEDFields() "
3343 if (( fields.length() < 1 ) &&
3344 ( !geomAssocFields || !geomAssocFields[0] ))
3347 std::vector< std::vector< double > > dblVals;
3348 std::vector< std::vector< int > > intVals;
3349 std::vector< int > subIdsByDim[ 4 ];
3350 const double noneDblValue = 0.;
3351 const double noneIntValue = 0;
3353 for ( size_t iF = 0; iF < fields.length(); ++iF )
3357 int dim = fields[ iF ]->GetDimension();
3358 SMDSAbs_ElementType elemType;
3359 TopAbs_ShapeEnum shapeType;
3361 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3362 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3363 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3364 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3366 continue; // skip fields on whole shape
3368 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3369 if ( dataType == GEOM::FDT_String )
3371 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3372 if ( stepIDs->length() < 1 )
3374 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3375 if ( comps->length() < 1 )
3377 CORBA::String_var name = fields[ iF ]->GetName();
3379 if ( !fieldWriter.Set( meshDS,
3383 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3386 for ( size_t iC = 0; iC < comps->length(); ++iC )
3387 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3389 dblVals.resize( comps->length() );
3390 intVals.resize( comps->length() );
3392 // find sub-shape IDs
3394 std::vector< int >& subIds = subIdsByDim[ dim ];
3395 if ( subIds.empty() )
3396 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3397 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3398 subIds.push_back( id );
3402 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3406 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3408 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3409 if ( step->_is_nil() )
3412 CORBA::Long stamp = step->GetStamp();
3413 CORBA::Long id = step->GetID();
3414 fieldWriter.SetDtIt( int( stamp ), int( id ));
3416 // fill dblVals or intVals
3417 for ( size_t iC = 0; iC < comps->length(); ++iC )
3418 if ( dataType == GEOM::FDT_Double )
3420 dblVals[ iC ].clear();
3421 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3425 intVals[ iC ].clear();
3426 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3430 case GEOM::FDT_Double:
3432 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3433 if ( dblStep->_is_nil() ) continue;
3434 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3435 if ( vv->length() != subIds.size() * comps->length() )
3436 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3437 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3438 for ( size_t iC = 0; iC < comps->length(); ++iC )
3439 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3444 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3445 if ( intStep->_is_nil() ) continue;
3446 GEOM::ListOfLong_var vv = intStep->GetValues();
3447 if ( vv->length() != subIds.size() * comps->length() )
3448 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3449 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3450 for ( size_t iC = 0; iC < comps->length(); ++iC )
3451 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3454 case GEOM::FDT_Bool:
3456 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3457 if ( boolStep->_is_nil() ) continue;
3458 GEOM::short_array_var vv = boolStep->GetValues();
3459 if ( vv->length() != subIds.size() * comps->length() )
3460 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3461 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3462 for ( size_t iC = 0; iC < comps->length(); ++iC )
3463 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3469 // pass values to fieldWriter
3470 elemIt = fieldWriter.GetOrderedElems();
3471 if ( dataType == GEOM::FDT_Double )
3472 while ( elemIt->more() )
3474 const SMDS_MeshElement* e = elemIt->next();
3475 const int shapeID = e->getshapeId();
3476 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3477 for ( size_t iC = 0; iC < comps->length(); ++iC )
3478 fieldWriter.AddValue( noneDblValue );
3480 for ( size_t iC = 0; iC < comps->length(); ++iC )
3481 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3484 while ( elemIt->more() )
3486 const SMDS_MeshElement* e = elemIt->next();
3487 const int shapeID = e->getshapeId();
3488 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3489 for ( size_t iC = 0; iC < comps->length(); ++iC )
3490 fieldWriter.AddValue( (double) noneIntValue );
3492 for ( size_t iC = 0; iC < comps->length(); ++iC )
3493 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3497 fieldWriter.Perform();
3498 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3499 if ( res && res->IsKO() )
3501 if ( res->myComment.empty() )
3502 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3504 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3510 if ( !geomAssocFields || !geomAssocFields[0] )
3513 // write geomAssocFields
3515 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3516 shapeDim[ TopAbs_COMPOUND ] = 3;
3517 shapeDim[ TopAbs_COMPSOLID ] = 3;
3518 shapeDim[ TopAbs_SOLID ] = 3;
3519 shapeDim[ TopAbs_SHELL ] = 2;
3520 shapeDim[ TopAbs_FACE ] = 2;
3521 shapeDim[ TopAbs_WIRE ] = 1;
3522 shapeDim[ TopAbs_EDGE ] = 1;
3523 shapeDim[ TopAbs_VERTEX ] = 0;
3524 shapeDim[ TopAbs_SHAPE ] = 3;
3526 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3528 std::vector< std::string > compNames;
3529 switch ( geomAssocFields[ iF ]) {
3531 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3532 compNames.push_back( "dim" );
3535 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3538 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3541 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3545 compNames.push_back( "id" );
3546 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3547 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3549 fieldWriter.SetDtIt( -1, -1 );
3551 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3555 if ( compNames.size() == 2 ) // _vertices_
3556 while ( elemIt->more() )
3558 const SMDS_MeshElement* e = elemIt->next();
3559 const int shapeID = e->getshapeId();
3562 fieldWriter.AddValue( (double) -1 );
3563 fieldWriter.AddValue( (double) -1 );
3567 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3568 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3569 fieldWriter.AddValue( (double) shapeID );
3573 while ( elemIt->more() )
3575 const SMDS_MeshElement* e = elemIt->next();
3576 const int shapeID = e->getshapeId();
3578 fieldWriter.AddValue( (double) -1 );
3580 fieldWriter.AddValue( (double) shapeID );
3584 fieldWriter.Perform();
3585 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3586 if ( res && res->IsKO() )
3588 if ( res->myComment.empty() )
3589 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3591 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3594 } // loop on geomAssocFields
3599 //================================================================================
3601 * \brief Export a part of mesh to a DAT file
3603 //================================================================================
3605 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3607 throw (SALOME::SALOME_Exception)
3609 Unexpect aCatch(SALOME_SalomeException);
3611 _preMeshInfo->FullLoadFromFile();
3613 PrepareForWriting(file);
3615 SMESH_MeshPartDS partDS( meshPart );
3616 _impl->ExportDAT(file,&partDS);
3618 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3619 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3621 //================================================================================
3623 * \brief Export a part of mesh to an UNV file
3625 //================================================================================
3627 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3629 throw (SALOME::SALOME_Exception)
3631 Unexpect aCatch(SALOME_SalomeException);
3633 _preMeshInfo->FullLoadFromFile();
3635 PrepareForWriting(file);
3637 SMESH_MeshPartDS partDS( meshPart );
3638 _impl->ExportUNV(file, &partDS);
3640 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3641 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3643 //================================================================================
3645 * \brief Export a part of mesh to an STL file
3647 //================================================================================
3649 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3651 ::CORBA::Boolean isascii)
3652 throw (SALOME::SALOME_Exception)
3654 Unexpect aCatch(SALOME_SalomeException);
3656 _preMeshInfo->FullLoadFromFile();
3658 PrepareForWriting(file);
3660 CORBA::String_var name;
3661 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3662 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3663 if ( !so->_is_nil() )
3664 name = so->GetName();
3666 SMESH_MeshPartDS partDS( meshPart );
3667 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3669 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3670 << meshPart<< ", r'" << file << "', " << isascii << ")";
3673 //================================================================================
3675 * \brief Export a part of mesh to an STL file
3677 //================================================================================
3679 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3681 CORBA::Boolean overwrite,
3682 CORBA::Boolean groupElemsByType)
3683 throw (SALOME::SALOME_Exception)
3686 Unexpect aCatch(SALOME_SalomeException);
3688 _preMeshInfo->FullLoadFromFile();
3690 PrepareForWriting(file,overwrite);
3692 std::string meshName("");
3693 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3694 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3695 if ( !so->_is_nil() )
3697 CORBA::String_var name = so->GetName();
3698 meshName = name.in();
3702 SMESH_MeshPartDS partDS( meshPart );
3703 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3705 SMESH_CATCH( SMESH::throwCorbaException );
3707 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3708 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3710 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3714 //================================================================================
3716 * \brief Export a part of mesh to a GMF file
3718 //================================================================================
3720 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3722 bool withRequiredGroups)
3723 throw (SALOME::SALOME_Exception)
3725 Unexpect aCatch(SALOME_SalomeException);
3727 _preMeshInfo->FullLoadFromFile();
3729 PrepareForWriting(file,/*overwrite=*/true);
3731 SMESH_MeshPartDS partDS( meshPart );
3732 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3734 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3735 << meshPart<< ", r'"
3737 << withRequiredGroups << ")";
3740 //=============================================================================
3742 * Return computation progress [0.,1]
3744 //=============================================================================
3746 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3750 return _impl->GetComputeProgress();
3752 SMESH_CATCH( SMESH::doNothing );
3756 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3758 Unexpect aCatch(SALOME_SalomeException);
3760 return _preMeshInfo->NbNodes();
3762 return _impl->NbNodes();
3765 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3767 Unexpect aCatch(SALOME_SalomeException);
3769 return _preMeshInfo->NbElements();
3771 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3774 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3776 Unexpect aCatch(SALOME_SalomeException);
3778 return _preMeshInfo->Nb0DElements();
3780 return _impl->Nb0DElements();
3783 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3785 Unexpect aCatch(SALOME_SalomeException);
3787 return _preMeshInfo->NbBalls();
3789 return _impl->NbBalls();
3792 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3794 Unexpect aCatch(SALOME_SalomeException);
3796 return _preMeshInfo->NbEdges();
3798 return _impl->NbEdges();
3801 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3802 throw(SALOME::SALOME_Exception)
3804 Unexpect aCatch(SALOME_SalomeException);
3806 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3808 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3811 //=============================================================================
3813 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3815 Unexpect aCatch(SALOME_SalomeException);
3817 return _preMeshInfo->NbFaces();
3819 return _impl->NbFaces();
3822 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 return _preMeshInfo->NbTriangles();
3828 return _impl->NbTriangles();
3831 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3833 Unexpect aCatch(SALOME_SalomeException);
3835 return _preMeshInfo->NbBiQuadTriangles();
3837 return _impl->NbBiQuadTriangles();
3840 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3842 Unexpect aCatch(SALOME_SalomeException);
3844 return _preMeshInfo->NbQuadrangles();
3846 return _impl->NbQuadrangles();
3849 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3851 Unexpect aCatch(SALOME_SalomeException);
3853 return _preMeshInfo->NbBiQuadQuadrangles();
3855 return _impl->NbBiQuadQuadrangles();
3858 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3860 Unexpect aCatch(SALOME_SalomeException);
3862 return _preMeshInfo->NbPolygons();
3864 return _impl->NbPolygons();
3867 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3873 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3876 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3877 throw(SALOME::SALOME_Exception)
3879 Unexpect aCatch(SALOME_SalomeException);
3881 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3883 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3886 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3887 throw(SALOME::SALOME_Exception)
3889 Unexpect aCatch(SALOME_SalomeException);
3891 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3893 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3896 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3897 throw(SALOME::SALOME_Exception)
3899 Unexpect aCatch(SALOME_SalomeException);
3901 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3903 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3906 //=============================================================================
3908 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbVolumes();
3914 return _impl->NbVolumes();
3917 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3919 Unexpect aCatch(SALOME_SalomeException);
3921 return _preMeshInfo->NbTetras();
3923 return _impl->NbTetras();
3926 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3928 Unexpect aCatch(SALOME_SalomeException);
3930 return _preMeshInfo->NbHexas();
3932 return _impl->NbHexas();
3935 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3937 Unexpect aCatch(SALOME_SalomeException);
3939 return _preMeshInfo->NbTriQuadHexas();
3941 return _impl->NbTriQuadraticHexas();
3944 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3946 Unexpect aCatch(SALOME_SalomeException);
3948 return _preMeshInfo->NbPyramids();
3950 return _impl->NbPyramids();
3953 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3955 Unexpect aCatch(SALOME_SalomeException);
3957 return _preMeshInfo->NbPrisms();
3959 return _impl->NbPrisms();
3962 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3964 Unexpect aCatch(SALOME_SalomeException);
3966 return _preMeshInfo->NbHexPrisms();
3968 return _impl->NbHexagonalPrisms();
3971 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3973 Unexpect aCatch(SALOME_SalomeException);
3975 return _preMeshInfo->NbPolyhedrons();
3977 return _impl->NbPolyhedrons();
3980 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3981 throw(SALOME::SALOME_Exception)
3983 Unexpect aCatch(SALOME_SalomeException);
3985 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3987 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3990 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3991 throw(SALOME::SALOME_Exception)
3993 Unexpect aCatch(SALOME_SalomeException);
3995 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3997 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4000 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4001 throw(SALOME::SALOME_Exception)
4003 Unexpect aCatch(SALOME_SalomeException);
4005 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4007 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4010 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4011 throw(SALOME::SALOME_Exception)
4013 Unexpect aCatch(SALOME_SalomeException);
4015 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4017 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4020 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4021 throw(SALOME::SALOME_Exception)
4023 Unexpect aCatch(SALOME_SalomeException);
4025 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4027 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4030 //=============================================================================
4032 * Returns nb of published sub-meshes
4034 //=============================================================================
4036 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4038 Unexpect aCatch(SALOME_SalomeException);
4039 return _mapSubMesh_i.size();
4042 //=============================================================================
4044 * Dumps mesh into a string
4046 //=============================================================================
4048 char* SMESH_Mesh_i::Dump()
4052 return CORBA::string_dup( os.str().c_str() );
4055 //=============================================================================
4057 * Method of SMESH_IDSource interface
4059 //=============================================================================
4061 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4063 return GetElementsId();
4066 //=============================================================================
4068 * Returns ids of all elements
4070 //=============================================================================
4072 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4073 throw (SALOME::SALOME_Exception)
4075 Unexpect aCatch(SALOME_SalomeException);
4077 _preMeshInfo->FullLoadFromFile();
4079 SMESH::long_array_var aResult = new SMESH::long_array();
4080 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4082 if ( aSMESHDS_Mesh == NULL )
4083 return aResult._retn();
4085 long nbElements = NbElements();
4086 aResult->length( nbElements );
4087 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4088 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4089 aResult[i] = anIt->next()->GetID();
4091 return aResult._retn();
4095 //=============================================================================
4097 * Returns ids of all elements of given type
4099 //=============================================================================
4101 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4102 throw (SALOME::SALOME_Exception)
4104 Unexpect aCatch(SALOME_SalomeException);
4106 _preMeshInfo->FullLoadFromFile();
4108 SMESH::long_array_var aResult = new SMESH::long_array();
4109 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4111 if ( aSMESHDS_Mesh == NULL )
4112 return aResult._retn();
4114 long nbElements = NbElements();
4116 // No sense in returning ids of elements along with ids of nodes:
4117 // when theElemType == SMESH::ALL, return node ids only if
4118 // there are no elements
4119 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4120 return GetNodesId();
4122 aResult->length( nbElements );
4126 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4127 while ( i < nbElements && anIt->more() )
4128 aResult[i++] = anIt->next()->GetID();
4130 aResult->length( i );
4132 return aResult._retn();
4135 //=============================================================================
4137 * Returns ids of all nodes
4139 //=============================================================================
4141 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4142 throw (SALOME::SALOME_Exception)
4144 Unexpect aCatch(SALOME_SalomeException);
4146 _preMeshInfo->FullLoadFromFile();
4148 SMESH::long_array_var aResult = new SMESH::long_array();
4149 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4151 if ( aMeshDS == NULL )
4152 return aResult._retn();
4154 long nbNodes = NbNodes();
4155 aResult->length( nbNodes );
4156 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4157 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4158 aResult[i] = anIt->next()->GetID();
4160 return aResult._retn();
4163 //=============================================================================
4167 //=============================================================================
4169 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4170 throw (SALOME::SALOME_Exception)
4172 SMESH::ElementType type = SMESH::ALL;
4176 _preMeshInfo->FullLoadFromFile();
4178 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4180 SMESH_CATCH( SMESH::throwCorbaException );
4185 //=============================================================================
4189 //=============================================================================
4191 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4192 throw (SALOME::SALOME_Exception)
4195 _preMeshInfo->FullLoadFromFile();
4197 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4199 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4201 return ( SMESH::EntityType ) e->GetEntityType();
4204 //=============================================================================
4208 //=============================================================================
4210 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4211 throw (SALOME::SALOME_Exception)
4214 _preMeshInfo->FullLoadFromFile();
4216 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4218 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4220 return ( SMESH::GeometryType ) e->GetGeomType();
4223 //=============================================================================
4225 * Returns ID of elements for given submesh
4227 //=============================================================================
4228 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4229 throw (SALOME::SALOME_Exception)
4231 SMESH::long_array_var aResult = new SMESH::long_array();
4235 _preMeshInfo->FullLoadFromFile();
4237 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4238 if(!SM) return aResult._retn();
4240 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4241 if(!SDSM) return aResult._retn();
4243 aResult->length(SDSM->NbElements());
4245 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4247 while ( eIt->more() ) {
4248 aResult[i++] = eIt->next()->GetID();
4251 SMESH_CATCH( SMESH::throwCorbaException );
4253 return aResult._retn();
4256 //=============================================================================
4258 * Returns ID of nodes for given submesh
4259 * If param all==true - returns all nodes, else -
4260 * returns only nodes on shapes.
4262 //=============================================================================
4264 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4266 throw (SALOME::SALOME_Exception)
4268 SMESH::long_array_var aResult = new SMESH::long_array();
4272 _preMeshInfo->FullLoadFromFile();
4274 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4275 if(!SM) return aResult._retn();
4277 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4278 if(!SDSM) return aResult._retn();
4281 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4282 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4283 while ( nIt->more() ) {
4284 const SMDS_MeshNode* elem = nIt->next();
4285 theElems.insert( elem->GetID() );
4288 else { // all nodes of submesh elements
4289 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4290 while ( eIt->more() ) {
4291 const SMDS_MeshElement* anElem = eIt->next();
4292 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4293 while ( nIt->more() ) {
4294 const SMDS_MeshElement* elem = nIt->next();
4295 theElems.insert( elem->GetID() );
4300 aResult->length(theElems.size());
4301 set<int>::iterator itElem;
4303 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4304 aResult[i++] = *itElem;
4306 SMESH_CATCH( SMESH::throwCorbaException );
4308 return aResult._retn();
4311 //=============================================================================
4313 * Returns type of elements for given submesh
4315 //=============================================================================
4317 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4318 throw (SALOME::SALOME_Exception)
4320 SMESH::ElementType type = SMESH::ALL;
4324 _preMeshInfo->FullLoadFromFile();
4326 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4327 if(!SM) return SMESH::ALL;
4329 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4330 if(!SDSM) return SMESH::ALL;
4332 if(SDSM->NbElements()==0)
4333 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4335 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4336 const SMDS_MeshElement* anElem = eIt->next();
4338 type = ( SMESH::ElementType ) anElem->GetType();
4340 SMESH_CATCH( SMESH::throwCorbaException );
4346 //=============================================================================
4348 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4350 //=============================================================================
4352 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4355 _preMeshInfo->FullLoadFromFile();
4357 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4358 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4363 //=============================================================================
4365 * Get XYZ coordinates of node as list of double
4366 * If there is not node for given ID - returns empty list
4368 //=============================================================================
4370 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4373 _preMeshInfo->FullLoadFromFile();
4375 SMESH::double_array_var aResult = new SMESH::double_array();
4376 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4377 if ( aMeshDS == NULL )
4378 return aResult._retn();
4381 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4383 return aResult._retn();
4387 aResult[0] = aNode->X();
4388 aResult[1] = aNode->Y();
4389 aResult[2] = aNode->Z();
4390 return aResult._retn();
4394 //=============================================================================
4396 * For given node returns list of IDs of inverse elements
4397 * If there is not node for given ID - returns empty list
4399 //=============================================================================
4401 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4404 _preMeshInfo->FullLoadFromFile();
4406 SMESH::long_array_var aResult = new SMESH::long_array();
4407 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4408 if ( aMeshDS == NULL )
4409 return aResult._retn();
4412 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4414 return aResult._retn();
4416 // find inverse elements
4417 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4418 aResult->length( aNode->NbInverseElements() );
4419 for( int i = 0; eIt->more(); ++i )
4421 const SMDS_MeshElement* elem = eIt->next();
4422 aResult[ i ] = elem->GetID();
4424 return aResult._retn();
4427 //=============================================================================
4429 * \brief Return position of a node on shape
4431 //=============================================================================
4433 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4436 _preMeshInfo->FullLoadFromFile();
4438 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4439 aNodePosition->shapeID = 0;
4440 aNodePosition->shapeType = GEOM::SHAPE;
4442 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4443 if ( !mesh ) return aNodePosition;
4445 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4447 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4449 aNodePosition->shapeID = aNode->getshapeId();
4450 switch ( pos->GetTypeOfPosition() ) {
4452 aNodePosition->shapeType = GEOM::EDGE;
4453 aNodePosition->params.length(1);
4454 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4456 case SMDS_TOP_FACE: {
4457 SMDS_FacePositionPtr fPos = pos;
4458 aNodePosition->shapeType = GEOM::FACE;
4459 aNodePosition->params.length(2);
4460 aNodePosition->params[0] = fPos->GetUParameter();
4461 aNodePosition->params[1] = fPos->GetVParameter();
4464 case SMDS_TOP_VERTEX:
4465 aNodePosition->shapeType = GEOM::VERTEX;
4467 case SMDS_TOP_3DSPACE:
4468 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4469 aNodePosition->shapeType = GEOM::SOLID;
4470 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4471 aNodePosition->shapeType = GEOM::SHELL;
4477 return aNodePosition;
4480 //=============================================================================
4482 * \brief Return position of an element on shape
4484 //=============================================================================
4486 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4489 _preMeshInfo->FullLoadFromFile();
4491 SMESH::ElementPosition anElementPosition;
4492 anElementPosition.shapeID = 0;
4493 anElementPosition.shapeType = GEOM::SHAPE;
4495 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4496 if ( !mesh ) return anElementPosition;
4498 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4500 anElementPosition.shapeID = anElem->getshapeId();
4501 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4502 if ( !aSp.IsNull() ) {
4503 switch ( aSp.ShapeType() ) {
4505 anElementPosition.shapeType = GEOM::EDGE;
4508 anElementPosition.shapeType = GEOM::FACE;
4511 anElementPosition.shapeType = GEOM::VERTEX;
4514 anElementPosition.shapeType = GEOM::SOLID;
4517 anElementPosition.shapeType = GEOM::SHELL;
4523 return anElementPosition;
4526 //=============================================================================
4528 * If given element is node returns IDs of shape from position
4529 * If there is not node for given ID - returns -1
4531 //=============================================================================
4533 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4536 _preMeshInfo->FullLoadFromFile();
4538 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4539 if ( aMeshDS == NULL )
4543 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4545 return aNode->getshapeId();
4552 //=============================================================================
4554 * For given element returns ID of result shape after
4555 * ::FindShape() from SMESH_MeshEditor
4556 * If there is not element for given ID - returns -1
4558 //=============================================================================
4560 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4563 _preMeshInfo->FullLoadFromFile();
4565 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4566 if ( aMeshDS == NULL )
4569 // try to find element
4570 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4574 ::SMESH_MeshEditor aMeshEditor(_impl);
4575 int index = aMeshEditor.FindShape( elem );
4583 //=============================================================================
4585 * Returns number of nodes for given element
4586 * If there is not element for given ID - returns -1
4588 //=============================================================================
4590 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4593 _preMeshInfo->FullLoadFromFile();
4595 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4596 if ( aMeshDS == NULL ) return -1;
4597 // try to find element
4598 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4599 if(!elem) return -1;
4600 return elem->NbNodes();
4604 //=============================================================================
4606 * Returns ID of node by given index for given element
4607 * If there is not element for given ID - returns -1
4608 * If there is not node for given index - returns -2
4610 //=============================================================================
4612 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4615 _preMeshInfo->FullLoadFromFile();
4617 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4618 if ( aMeshDS == NULL ) return -1;
4619 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4620 if(!elem) return -1;
4621 if( index>=elem->NbNodes() || index<0 ) return -1;
4622 return elem->GetNode(index)->GetID();
4625 //=============================================================================
4627 * Returns IDs of nodes of given element
4629 //=============================================================================
4631 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4634 _preMeshInfo->FullLoadFromFile();
4636 SMESH::long_array_var aResult = new SMESH::long_array();
4637 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4639 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4641 aResult->length( elem->NbNodes() );
4642 for ( int i = 0; i < elem->NbNodes(); ++i )
4643 aResult[ i ] = elem->GetNode( i )->GetID();
4646 return aResult._retn();
4649 //=============================================================================
4651 * Returns true if given node is medium node
4652 * in given quadratic element
4654 //=============================================================================
4656 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4659 _preMeshInfo->FullLoadFromFile();
4661 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4662 if ( aMeshDS == NULL ) return false;
4664 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4665 if(!aNode) return false;
4666 // try to find element
4667 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4668 if(!elem) return false;
4670 return elem->IsMediumNode(aNode);
4674 //=============================================================================
4676 * Returns true if given node is medium node
4677 * in one of quadratic elements
4679 //=============================================================================
4681 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4682 SMESH::ElementType theElemType)
4685 _preMeshInfo->FullLoadFromFile();
4687 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4688 if ( aMeshDS == NULL ) return false;
4691 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4692 if(!aNode) return false;
4694 SMESH_MesherHelper aHelper( *(_impl) );
4696 SMDSAbs_ElementType aType;
4697 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4698 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4699 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4700 else aType = SMDSAbs_All;
4702 return aHelper.IsMedium(aNode,aType);
4706 //=============================================================================
4708 * Returns number of edges for given element
4710 //=============================================================================
4712 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4715 _preMeshInfo->FullLoadFromFile();
4717 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4718 if ( aMeshDS == NULL ) return -1;
4719 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4720 if(!elem) return -1;
4721 return elem->NbEdges();
4725 //=============================================================================
4727 * Returns number of faces for given element
4729 //=============================================================================
4731 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4734 _preMeshInfo->FullLoadFromFile();
4736 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4737 if ( aMeshDS == NULL ) return -1;
4738 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4739 if(!elem) return -1;
4740 return elem->NbFaces();
4743 //=======================================================================
4744 //function : GetElemFaceNodes
4745 //purpose : Returns nodes of given face (counted from zero) for given element.
4746 //=======================================================================
4748 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4749 CORBA::Short faceIndex)
4752 _preMeshInfo->FullLoadFromFile();
4754 SMESH::long_array_var aResult = new SMESH::long_array();
4755 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4757 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4759 SMDS_VolumeTool vtool( elem );
4760 if ( faceIndex < vtool.NbFaces() )
4762 aResult->length( vtool.NbFaceNodes( faceIndex ));
4763 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4764 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4765 aResult[ i ] = nn[ i ]->GetID();
4769 return aResult._retn();
4772 //=======================================================================
4773 //function : GetElemFaceNodes
4774 //purpose : Returns three components of normal of given mesh face.
4775 //=======================================================================
4777 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4778 CORBA::Boolean normalized)
4781 _preMeshInfo->FullLoadFromFile();
4783 SMESH::double_array_var aResult = new SMESH::double_array();
4785 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4788 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4790 aResult->length( 3 );
4791 aResult[ 0 ] = normal.X();
4792 aResult[ 1 ] = normal.Y();
4793 aResult[ 2 ] = normal.Z();
4796 return aResult._retn();
4799 //=======================================================================
4800 //function : FindElementByNodes
4801 //purpose : Returns an element based on all given nodes.
4802 //=======================================================================
4804 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4807 _preMeshInfo->FullLoadFromFile();
4809 CORBA::Long elemID(0);
4810 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4812 vector< const SMDS_MeshNode * > nn( nodes.length() );
4813 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4814 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4817 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4818 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4819 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4820 _impl->NbVolumes( ORDER_QUADRATIC )))
4821 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4823 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4828 //================================================================================
4830 * \brief Return elements including all given nodes.
4832 //================================================================================
4834 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4835 SMESH::ElementType elemType)
4838 _preMeshInfo->FullLoadFromFile();
4840 SMESH::long_array_var result = new SMESH::long_array();
4842 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4844 vector< const SMDS_MeshNode * > nn( nodes.length() );
4845 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4846 nn[i] = mesh->FindNode( nodes[i] );
4848 std::vector<const SMDS_MeshElement *> elems;
4849 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4850 result->length( elems.size() );
4851 for ( size_t i = 0; i < elems.size(); ++i )
4852 result[i] = elems[i]->GetID();
4854 return result._retn();
4857 //=============================================================================
4859 * Returns true if given element is polygon
4861 //=============================================================================
4863 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4866 _preMeshInfo->FullLoadFromFile();
4868 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4869 if ( aMeshDS == NULL ) return false;
4870 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4871 if(!elem) return false;
4872 return elem->IsPoly();
4876 //=============================================================================
4878 * Returns true if given element is quadratic
4880 //=============================================================================
4882 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4885 _preMeshInfo->FullLoadFromFile();
4887 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4888 if ( aMeshDS == NULL ) return false;
4889 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4890 if(!elem) return false;
4891 return elem->IsQuadratic();
4894 //=============================================================================
4896 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4898 //=============================================================================
4900 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4903 _preMeshInfo->FullLoadFromFile();
4905 if ( const SMDS_BallElement* ball =
4906 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4907 return ball->GetDiameter();
4912 //=============================================================================
4914 * Returns bary center for given element
4916 //=============================================================================
4918 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4921 _preMeshInfo->FullLoadFromFile();
4923 SMESH::double_array_var aResult = new SMESH::double_array();
4924 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4925 if ( aMeshDS == NULL )
4926 return aResult._retn();
4928 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4930 return aResult._retn();
4932 if(elem->GetType()==SMDSAbs_Volume) {
4933 SMDS_VolumeTool aTool;
4934 if(aTool.Set(elem)) {
4936 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4941 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4943 double x=0., y=0., z=0.;
4944 for(; anIt->more(); ) {
4946 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4960 return aResult._retn();
4963 //================================================================================
4965 * \brief Create a group of elements preventing computation of a sub-shape
4967 //================================================================================
4969 SMESH::ListOfGroups*
4970 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4971 const char* theGroupName )
4972 throw ( SALOME::SALOME_Exception )
4974 Unexpect aCatch(SALOME_SalomeException);
4976 if ( !theGroupName || strlen( theGroupName) == 0 )
4977 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4979 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4980 ::SMESH_MeshEditor::ElemFeatures elemType;
4982 // submesh by subshape id
4983 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4984 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4987 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4988 if ( error && error->HasBadElems() )
4990 // sort bad elements by type
4991 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4992 const list<const SMDS_MeshElement*>& badElems =
4993 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4994 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4995 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4996 for ( ; elemIt != elemEnd; ++elemIt )
4998 const SMDS_MeshElement* elem = *elemIt;
4999 if ( !elem ) continue;
5001 if ( elem->GetID() < 1 )
5003 // elem is a temporary element, make a real element
5004 vector< const SMDS_MeshNode* > nodes;
5005 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5006 while ( nIt->more() && elem )
5008 nodes.push_back( nIt->next() );
5009 if ( nodes.back()->GetID() < 1 )
5010 elem = 0; // a temporary element on temporary nodes
5014 ::SMESH_MeshEditor editor( _impl );
5015 elem = editor.AddElement( nodes, elemType.Init( elem ));
5019 elemsByType[ elem->GetType() ].push_back( elem );
5022 // how many groups to create?
5024 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5025 nbTypes += int( !elemsByType[ i ].empty() );
5026 groups->length( nbTypes );
5029 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5031 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5032 if ( elems.empty() ) continue;
5034 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5035 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5037 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
5038 SMESH::SMESH_Mesh_var mesh = _this();
5039 SALOMEDS::SObject_wrap aSO =
5040 _gen_i->PublishGroup( study, mesh, groups[ iG ],
5041 GEOM::GEOM_Object::_nil(), theGroupName);
5043 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5044 if ( !grp_i ) continue;
5046 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5047 for ( size_t iE = 0; iE < elems.size(); ++iE )
5048 grpDS->SMDSGroup().Add( elems[ iE ]);
5053 return groups._retn();
5056 //=============================================================================
5058 * Create and publish group servants if any groups were imported or created anyhow
5060 //=============================================================================
5062 void SMESH_Mesh_i::CreateGroupServants()
5064 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5065 SMESH::SMESH_Mesh_var aMesh = _this();
5068 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5069 while ( groupIt->more() )
5071 ::SMESH_Group* group = groupIt->next();
5072 int anId = group->GetGroupDS()->GetID();
5074 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5075 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5077 addedIDs.insert( anId );
5079 SMESH_GroupBase_i* aGroupImpl;
5081 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5082 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5084 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5085 shape = groupOnGeom->GetShape();
5088 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5091 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5092 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5093 aGroupImpl->Register();
5095 // register CORBA object for persistence
5096 int nextId = _gen_i->RegisterObject( groupVar );
5097 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5098 else { nextId = 0; } // avoid "unused variable" warning in release mode
5100 // publishing the groups in the study
5101 if ( !aStudy->_is_nil() ) {
5102 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5103 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5106 if ( !addedIDs.empty() )
5109 set<int>::iterator id = addedIDs.begin();
5110 for ( ; id != addedIDs.end(); ++id )
5112 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5113 int i = std::distance( _mapGroups.begin(), it );
5114 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5119 //=============================================================================
5121 * \brief Return groups cantained in _mapGroups by their IDs
5123 //=============================================================================
5125 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5127 int nbGroups = groupIDs.size();
5128 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5129 aList->length( nbGroups );
5131 list<int>::const_iterator ids = groupIDs.begin();
5132 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5134 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5135 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5136 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5138 aList->length( nbGroups );
5139 return aList._retn();
5142 //=============================================================================
5144 * \brief Return information about imported file
5146 //=============================================================================
5148 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5150 SMESH::MedFileInfo_var res( _medFileInfo );
5151 if ( !res.operator->() ) {
5152 res = new SMESH::MedFileInfo;
5154 res->fileSize = res->major = res->minor = res->release = -1;
5159 //=============================================================================
5161 * \brief Pass names of mesh groups from study to mesh DS
5163 //=============================================================================
5165 void SMESH_Mesh_i::checkGroupNames()
5167 int nbGrp = NbGroups();
5171 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5172 if ( aStudy->_is_nil() )
5173 return; // nothing to do
5175 SMESH::ListOfGroups* grpList = 0;
5176 // avoid dump of "GetGroups"
5178 // store python dump into a local variable inside local scope
5179 SMESH::TPythonDump pDump; // do not delete this line of code
5180 grpList = GetGroups();
5183 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5184 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5187 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5188 if ( aGrpSO->_is_nil() )
5190 // correct name of the mesh group if necessary
5191 const char* guiName = aGrpSO->GetName();
5192 if ( strcmp(guiName, aGrp->GetName()) )
5193 aGrp->SetName( guiName );
5197 //=============================================================================
5199 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5201 //=============================================================================
5202 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5204 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5208 //=============================================================================
5210 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5212 //=============================================================================
5214 char* SMESH_Mesh_i::GetParameters()
5216 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5219 //=============================================================================
5221 * \brief Returns list of notebook variables used for last Mesh operation
5223 //=============================================================================
5224 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5226 SMESH::string_array_var aResult = new SMESH::string_array();
5227 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5229 CORBA::String_var aParameters = GetParameters();
5230 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5231 if ( !aStudy->_is_nil()) {
5232 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5233 if ( aSections->length() > 0 ) {
5234 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5235 aResult->length( aVars.length() );
5236 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5237 aResult[i] = CORBA::string_dup( aVars[i] );
5241 return aResult._retn();
5244 //=======================================================================
5245 //function : GetTypes
5246 //purpose : Returns types of elements it contains
5247 //=======================================================================
5249 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5252 return _preMeshInfo->GetTypes();
5254 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5258 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5259 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5260 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5261 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5262 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5263 if (_impl->NbNodes() &&
5264 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5265 types->length( nbTypes );
5267 return types._retn();
5270 //=======================================================================
5271 //function : GetMesh
5272 //purpose : Returns self
5273 //=======================================================================
5275 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5277 return SMESH::SMESH_Mesh::_duplicate( _this() );
5280 //=======================================================================
5281 //function : IsMeshInfoCorrect
5282 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5283 // * happen if mesh data is not yet fully loaded from the file of study.
5284 //=======================================================================
5286 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5288 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5291 //=============================================================================
5293 * \brief Returns number of mesh elements per each \a EntityType
5295 //=============================================================================
5297 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5300 return _preMeshInfo->GetMeshInfo();
5302 SMESH::long_array_var aRes = new SMESH::long_array();
5303 aRes->length(SMESH::Entity_Last);
5304 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5306 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5308 return aRes._retn();
5309 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5310 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5311 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5312 return aRes._retn();
5315 //=============================================================================
5317 * \brief Returns number of mesh elements per each \a ElementType
5319 //=============================================================================
5321 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5323 SMESH::long_array_var aRes = new SMESH::long_array();
5324 aRes->length(SMESH::NB_ELEMENT_TYPES);
5325 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5328 const SMDS_MeshInfo* meshInfo = 0;
5330 meshInfo = _preMeshInfo;
5331 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5332 meshInfo = & meshDS->GetMeshInfo();
5335 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5336 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5338 return aRes._retn();
5341 //=============================================================================
5343 * Collect statistic of mesh elements given by iterator
5345 //=============================================================================
5347 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5348 SMESH::long_array& theInfo)
5350 if (!theItr) return;
5351 while (theItr->more())
5352 theInfo[ theItr->next()->GetEntityType() ]++;
5354 //=============================================================================
5356 * Returns mesh unstructed grid information.
5358 //=============================================================================
5360 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5362 SALOMEDS::TMPFile_var SeqFile;
5363 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5364 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5366 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5367 aWriter->WriteToOutputStringOn();
5368 aWriter->SetInputData(aGrid);
5369 aWriter->SetFileTypeToBinary();
5371 char* str = aWriter->GetOutputString();
5372 int size = aWriter->GetOutputStringLength();
5374 //Allocate octect buffer of required size
5375 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5376 //Copy ostrstream content to the octect buffer
5377 memcpy(OctetBuf, str, size);
5378 //Create and return TMPFile
5379 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5383 return SeqFile._retn();
5386 //=============================================================================
5387 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5388 * SMESH::ElementType type) */
5390 using namespace SMESH::Controls;
5391 //-----------------------------------------------------------------------------
5392 struct PredicateIterator : public SMDS_ElemIterator
5394 SMDS_ElemIteratorPtr _elemIter;
5395 PredicatePtr _predicate;
5396 const SMDS_MeshElement* _elem;
5398 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5399 PredicatePtr predicate):
5400 _elemIter(iterator), _predicate(predicate)
5408 virtual const SMDS_MeshElement* next()
5410 const SMDS_MeshElement* res = _elem;
5412 while ( _elemIter->more() && !_elem )
5414 _elem = _elemIter->next();
5415 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5422 //-----------------------------------------------------------------------------
5423 struct IDSourceIterator : public SMDS_ElemIterator
5425 const CORBA::Long* _idPtr;
5426 const CORBA::Long* _idEndPtr;
5427 SMESH::long_array_var _idArray;
5428 const SMDS_Mesh* _mesh;
5429 const SMDSAbs_ElementType _type;
5430 const SMDS_MeshElement* _elem;
5432 IDSourceIterator( const SMDS_Mesh* mesh,
5433 const CORBA::Long* ids,
5435 SMDSAbs_ElementType type):
5436 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5438 if ( _idPtr && nbIds && _mesh )
5441 IDSourceIterator( const SMDS_Mesh* mesh,
5442 SMESH::long_array* idArray,
5443 SMDSAbs_ElementType type):
5444 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5446 if ( idArray && _mesh )
5448 _idPtr = &_idArray[0];
5449 _idEndPtr = _idPtr + _idArray->length();
5457 virtual const SMDS_MeshElement* next()
5459 const SMDS_MeshElement* res = _elem;
5461 while ( _idPtr < _idEndPtr && !_elem )
5463 if ( _type == SMDSAbs_Node )
5465 _elem = _mesh->FindNode( *_idPtr++ );
5467 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5468 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5476 //-----------------------------------------------------------------------------
5478 struct NodeOfElemIterator : public SMDS_ElemIterator
5480 TColStd_MapOfInteger _checkedNodeIDs;
5481 SMDS_ElemIteratorPtr _elemIter;
5482 SMDS_ElemIteratorPtr _nodeIter;
5483 const SMDS_MeshElement* _node;
5485 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5487 if ( _elemIter && _elemIter->more() )
5489 _nodeIter = _elemIter->next()->nodesIterator();
5497 virtual const SMDS_MeshElement* next()
5499 const SMDS_MeshElement* res = _node;
5501 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5503 if ( _nodeIter->more() )
5505 _node = _nodeIter->next();
5506 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5511 _nodeIter = _elemIter->next()->nodesIterator();
5519 //=============================================================================
5521 * Return iterator on elements of given type in given object
5523 //=============================================================================
5525 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5526 SMESH::ElementType theType)
5528 SMDS_ElemIteratorPtr elemIt;
5529 bool typeOK = ( theType == SMESH::ALL );
5530 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5532 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5533 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5534 if ( !mesh_i ) return elemIt;
5535 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5537 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5539 elemIt = meshDS->elementsIterator( elemType );
5542 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5544 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5547 elemIt = sm->GetElements();
5548 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5550 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5551 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5555 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5557 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5558 if ( groupDS && ( elemType == groupDS->GetType() ||
5559 elemType == SMDSAbs_Node ||
5560 elemType == SMDSAbs_All ))
5562 elemIt = groupDS->GetElements();
5563 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5566 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5568 if ( filter_i->GetElementType() == theType ||
5569 elemType == SMDSAbs_Node ||
5570 elemType == SMDSAbs_All)
5572 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5573 if ( pred_i && pred_i->GetPredicate() )
5575 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5576 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5577 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5578 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5584 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5585 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5586 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5588 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5591 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5592 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5596 SMESH::long_array_var ids = theObject->GetIDs();
5597 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5599 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5602 if ( elemIt && elemIt->more() && !typeOK )
5604 if ( elemType == SMDSAbs_Node )
5606 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5610 elemIt = SMDS_ElemIteratorPtr();
5616 //=============================================================================
5617 namespace // Finding concurrent hypotheses
5618 //=============================================================================
5622 * \brief mapping of mesh dimension into shape type
5624 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5626 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5628 case 0: aType = TopAbs_VERTEX; break;
5629 case 1: aType = TopAbs_EDGE; break;
5630 case 2: aType = TopAbs_FACE; break;
5632 default:aType = TopAbs_SOLID; break;
5637 //-----------------------------------------------------------------------------
5639 * \brief Internal structure used to find concurrent submeshes
5641 * It represents a pair < submesh, concurrent dimension >, where
5642 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5643 * with another submesh. In other words, it is dimension of a hypothesis assigned
5650 int _dim; //!< a dimension the algo can build (concurrent dimension)
5651 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5652 TopTools_MapOfShape _shapeMap;
5653 SMESH_subMesh* _subMesh;
5654 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5656 //-----------------------------------------------------------------------------
5657 // Return the algorithm
5658 const SMESH_Algo* GetAlgo() const
5659 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5661 //-----------------------------------------------------------------------------
5663 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5665 const TopoDS_Shape& theShape)
5667 _subMesh = (SMESH_subMesh*)theSubMesh;
5668 SetShape( theDim, theShape );
5671 //-----------------------------------------------------------------------------
5673 void SetShape(const int theDim,
5674 const TopoDS_Shape& theShape)
5677 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5678 if (_dim >= _ownDim)
5679 _shapeMap.Add( theShape );
5681 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5682 for( ; anExp.More(); anExp.Next() )
5683 _shapeMap.Add( anExp.Current() );
5687 //-----------------------------------------------------------------------------
5688 //! Check sharing of sub-shapes
5689 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5690 const TopTools_MapOfShape& theToFind,
5691 const TopAbs_ShapeEnum theType)
5693 bool isShared = false;
5694 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5695 for (; !isShared && anItr.More(); anItr.Next() )
5697 const TopoDS_Shape aSubSh = anItr.Key();
5698 // check for case when concurrent dimensions are same
5699 isShared = theToFind.Contains( aSubSh );
5700 // check for sub-shape with concurrent dimension
5701 TopExp_Explorer anExp( aSubSh, theType );
5702 for ( ; !isShared && anExp.More(); anExp.Next() )
5703 isShared = theToFind.Contains( anExp.Current() );
5708 //-----------------------------------------------------------------------------
5709 //! check algorithms
5710 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5711 const SMESHDS_Hypothesis* theA2)
5713 if ( !theA1 || !theA2 ||
5714 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5715 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5716 return false; // one of the hypothesis is not algorithm
5717 // check algorithm names (should be equal)
5718 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5722 //-----------------------------------------------------------------------------
5723 //! Check if sub-shape hypotheses are concurrent
5724 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5726 if ( _subMesh == theOther->_subMesh )
5727 return false; // same sub-shape - should not be
5729 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5730 // any of the two submeshes is not on COMPOUND shape )
5731 // -> no concurrency
5732 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5733 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5734 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5735 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5736 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5739 // bool checkSubShape = ( _dim >= theOther->_dim )
5740 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5741 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5742 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5743 if ( !checkSubShape )
5746 // check algorithms to be same
5747 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5748 return true; // different algorithms -> concurrency !
5750 // check hypothesises for concurrence (skip first as algorithm)
5752 // pointers should be same, because it is referened from mesh hypothesis partition
5753 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5754 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5755 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5756 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5758 // the submeshes are concurrent if their algorithms has different parameters
5759 return nbSame != (int)theOther->_hypotheses.size() - 1;
5762 // Return true if algorithm of this SMESH_DimHyp is used if no
5763 // sub-mesh order is imposed by the user
5764 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5766 // NeedDiscreteBoundary() algo has a higher priority
5767 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5768 theOther->GetAlgo()->NeedDiscreteBoundary() )
5769 return !this->GetAlgo()->NeedDiscreteBoundary();
5771 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5774 }; // end of SMESH_DimHyp
5775 //-----------------------------------------------------------------------------
5777 typedef list<const SMESH_DimHyp*> TDimHypList;
5779 //-----------------------------------------------------------------------------
5781 void addDimHypInstance(const int theDim,
5782 const TopoDS_Shape& theShape,
5783 const SMESH_Algo* theAlgo,
5784 const SMESH_subMesh* theSubMesh,
5785 const list <const SMESHDS_Hypothesis*>& theHypList,
5786 TDimHypList* theDimHypListArr )
5788 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5789 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5790 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5791 dimHyp->_hypotheses.push_front(theAlgo);
5792 listOfdimHyp.push_back( dimHyp );
5795 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5796 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5797 theHypList.begin(), theHypList.end() );
5800 //-----------------------------------------------------------------------------
5801 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5802 TDimHypList& theListOfConcurr)
5804 if ( theListOfConcurr.empty() )
5806 theListOfConcurr.push_back( theDimHyp );
5810 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5811 while ( hypIt != theListOfConcurr.end() &&
5812 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5814 theListOfConcurr.insert( hypIt, theDimHyp );
5818 //-----------------------------------------------------------------------------
5819 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5820 const TDimHypList& theListOfDimHyp,
5821 TDimHypList& theListOfConcurrHyp,
5822 set<int>& theSetOfConcurrId )
5824 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5825 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5827 const SMESH_DimHyp* curDimHyp = *rIt;
5828 if ( curDimHyp == theDimHyp )
5829 break; // meet own dimHyp pointer in same dimension
5831 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5832 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5834 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5839 //-----------------------------------------------------------------------------
5840 void unionLists(TListOfInt& theListOfId,
5841 TListOfListOfInt& theListOfListOfId,
5844 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5845 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5847 continue; //skip already treated lists
5848 // check if other list has any same submesh object
5849 TListOfInt& otherListOfId = *it;
5850 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5851 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5854 // union two lists (from source into target)
5855 TListOfInt::iterator it2 = otherListOfId.begin();
5856 for ( ; it2 != otherListOfId.end(); it2++ ) {
5857 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5858 theListOfId.push_back(*it2);
5860 // clear source list
5861 otherListOfId.clear();
5864 //-----------------------------------------------------------------------------
5866 //! free memory allocated for dimension-hypothesis objects
5867 void removeDimHyps( TDimHypList* theArrOfList )
5869 for (int i = 0; i < 4; i++ ) {
5870 TDimHypList& listOfdimHyp = theArrOfList[i];
5871 TDimHypList::const_iterator it = listOfdimHyp.begin();
5872 for ( ; it != listOfdimHyp.end(); it++ )
5877 //-----------------------------------------------------------------------------
5879 * \brief find common submeshes with given submesh
5880 * \param theSubMeshList list of already collected submesh to check
5881 * \param theSubMesh given submesh to intersect with other
5882 * \param theCommonSubMeshes collected common submeshes
5884 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5885 const SMESH_subMesh* theSubMesh,
5886 set<const SMESH_subMesh*>& theCommon )
5890 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5891 for ( ; it != theSubMeshList.end(); it++ )
5892 theSubMesh->FindIntersection( *it, theCommon );
5893 theSubMeshList.push_back( theSubMesh );
5894 //theCommon.insert( theSubMesh );
5897 //-----------------------------------------------------------------------------
5898 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5900 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5901 for ( ; listsIt != smLists.end(); ++listsIt )
5903 const TListOfInt& smIDs = *listsIt;
5904 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5912 //=============================================================================
5914 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5916 //=============================================================================
5918 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5920 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5921 if ( isSubMeshInList( submeshID, anOrder ))
5924 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5925 return isSubMeshInList( submeshID, allConurrent );
5928 //=============================================================================
5930 * \brief Return submesh objects list in meshing order
5932 //=============================================================================
5934 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5936 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5938 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5940 return aResult._retn();
5942 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5943 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5944 anOrder.splice( anOrder.end(), allConurrent );
5947 TListOfListOfInt::iterator listIt = anOrder.begin();
5948 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5949 unionLists( *listIt, anOrder, listIndx + 1 );
5951 // convert submesh ids into interface instances
5952 // and dump command into python
5953 convertMeshOrder( anOrder, aResult, false );
5955 return aResult._retn();
5958 //=============================================================================
5960 * \brief Finds concurrent sub-meshes
5962 //=============================================================================
5964 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5966 TListOfListOfInt anOrder;
5967 ::SMESH_Mesh& mesh = GetImpl();
5969 // collect submeshes and detect concurrent algorithms and hypothesises
5970 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5972 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5973 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5974 ::SMESH_subMesh* sm = (*i_sm).second;
5976 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5978 // list of assigned hypothesises
5979 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5980 // Find out dimensions where the submesh can be concurrent.
5981 // We define the dimensions by algo of each of hypotheses in hypList
5982 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5983 for( ; hypIt != hypList.end(); hypIt++ ) {
5984 SMESH_Algo* anAlgo = 0;
5985 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5986 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5987 // hyp it-self is algo
5988 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5990 // try to find algorithm with help of sub-shapes
5991 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5992 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5993 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5996 continue; // no algorithm assigned to a current submesh
5998 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5999 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6001 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6002 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6003 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6005 } // end iterations on submesh
6007 // iterate on created dimension-hypotheses and check for concurrents
6008 for ( int i = 0; i < 4; i++ ) {
6009 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6010 // check for concurrents in own and other dimensions (step-by-step)
6011 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6012 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6013 const SMESH_DimHyp* dimHyp = *dhIt;
6014 TDimHypList listOfConcurr;
6015 set<int> setOfConcurrIds;
6016 // looking for concurrents and collect into own list
6017 for ( int j = i; j < 4; j++ )
6018 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6019 // check if any concurrents found
6020 if ( listOfConcurr.size() > 0 ) {
6021 // add own submesh to list of concurrent
6022 addInOrderOfPriority( dimHyp, listOfConcurr );
6023 list<int> listOfConcurrIds;
6024 TDimHypList::iterator hypIt = listOfConcurr.begin();
6025 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6026 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6027 anOrder.push_back( listOfConcurrIds );
6032 removeDimHyps(dimHypListArr);
6034 // now, minimize the number of concurrent groups
6035 // Here we assume that lists of submeshes can have same submesh
6036 // in case of multi-dimension algorithms, as result
6037 // list with common submesh has to be united into one list
6039 TListOfListOfInt::iterator listIt = anOrder.begin();
6040 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6041 unionLists( *listIt, anOrder, listIndx + 1 );
6047 //=============================================================================
6049 * \brief Set submesh object order
6050 * \param theSubMeshArray submesh array order
6052 //=============================================================================
6054 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6057 _preMeshInfo->ForgetOrLoad();
6060 ::SMESH_Mesh& mesh = GetImpl();
6062 TPythonDump aPythonDump; // prevent dump of called methods
6063 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6065 TListOfListOfInt subMeshOrder;
6066 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6068 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6069 TListOfInt subMeshIds;
6071 aPythonDump << ", ";
6072 aPythonDump << "[ ";
6073 // Collect subMeshes which should be clear
6074 // do it list-by-list, because modification of submesh order
6075 // take effect between concurrent submeshes only
6076 set<const SMESH_subMesh*> subMeshToClear;
6077 list<const SMESH_subMesh*> subMeshList;
6078 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6080 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6082 aPythonDump << ", ";
6083 aPythonDump << subMesh;
6084 subMeshIds.push_back( subMesh->GetId() );
6085 // detect common parts of submeshes
6086 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6087 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6089 aPythonDump << " ]";
6090 subMeshOrder.push_back( subMeshIds );
6092 // clear collected submeshes
6093 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6094 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6095 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6096 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6098 aPythonDump << " ])";
6100 mesh.SetMeshOrder( subMeshOrder );
6106 //=============================================================================
6108 * \brief Convert submesh ids into submesh interfaces
6110 //=============================================================================
6112 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6113 SMESH::submesh_array_array& theResOrder,
6114 const bool theIsDump)
6116 int nbSet = theIdsOrder.size();
6117 TPythonDump aPythonDump; // prevent dump of called methods
6119 aPythonDump << "[ ";
6120 theResOrder.length(nbSet);
6121 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6123 for( ; it != theIdsOrder.end(); it++ ) {
6124 // translate submesh identificators into submesh objects
6125 // takeing into account real number of concurrent lists
6126 const TListOfInt& aSubOrder = (*it);
6127 if (!aSubOrder.size())
6130 aPythonDump << "[ ";
6131 // convert shape indices into interfaces
6132 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6133 aResSubSet->length(aSubOrder.size());
6134 TListOfInt::const_iterator subIt = aSubOrder.begin();
6136 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6137 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6139 SMESH::SMESH_subMesh_var subMesh =
6140 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6143 aPythonDump << ", ";
6144 aPythonDump << subMesh;
6146 aResSubSet[ j++ ] = subMesh;
6149 aPythonDump << " ]";
6151 theResOrder[ listIndx++ ] = aResSubSet;
6153 // correct number of lists
6154 theResOrder.length( listIndx );
6157 // finilise python dump
6158 aPythonDump << " ]";
6159 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6163 namespace // utils used by SMESH_MeshPartDS
6166 * \brief Class used to access to protected data of SMDS_MeshInfo
6168 struct TMeshInfo : public SMDS_MeshInfo
6170 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6173 * \brief Element holing its ID only
6175 struct TElemID : public SMDS_LinearEdge
6177 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6181 //================================================================================
6183 // Implementation of SMESH_MeshPartDS
6185 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6186 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6188 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6189 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6192 _meshDS = mesh_i->GetImpl().GetMeshDS();
6194 SetPersistentId( _meshDS->GetPersistentId() );
6196 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6198 // <meshPart> is the whole mesh
6199 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6201 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6202 myGroupSet = _meshDS->GetGroups();
6207 SMESH::long_array_var anIDs = meshPart->GetIDs();
6208 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6209 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6211 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6212 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6213 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6218 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6219 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6220 if ( _elements[ e->GetType() ].insert( e ).second )
6223 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6224 while ( nIt->more() )
6226 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6227 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6234 ShapeToMesh( _meshDS->ShapeToMesh() );
6236 _meshDS = 0; // to enforce iteration on _elements and _nodes
6239 // -------------------------------------------------------------------------------------
6240 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6241 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6244 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6245 for ( ; partIt != meshPart.end(); ++partIt )
6246 if ( const SMDS_MeshElement * e = *partIt )
6247 if ( _elements[ e->GetType() ].insert( e ).second )
6250 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6251 while ( nIt->more() )
6253 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6254 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6260 // -------------------------------------------------------------------------------------
6261 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6263 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6265 TElemID elem( IDelem );
6266 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6267 if ( !_elements[ iType ].empty() )
6269 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6270 if ( it != _elements[ iType ].end() )
6275 // -------------------------------------------------------------------------------------
6276 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6278 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6280 typedef SMDS_SetIterator
6281 <const SMDS_MeshElement*,
6282 TIDSortedElemSet::const_iterator,
6283 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6284 SMDS_MeshElement::GeomFilter
6287 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6289 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6290 _elements[type].end(),
6291 SMDS_MeshElement::GeomFilter( geomType )));
6293 // -------------------------------------------------------------------------------------
6294 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6296 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6298 typedef SMDS_SetIterator
6299 <const SMDS_MeshElement*,
6300 TIDSortedElemSet::const_iterator,
6301 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6302 SMDS_MeshElement::EntityFilter
6305 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6307 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6308 _elements[type].end(),
6309 SMDS_MeshElement::EntityFilter( entity )));
6311 // -------------------------------------------------------------------------------------
6312 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6314 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6315 if ( type == SMDSAbs_All && !_meshDS )
6317 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6319 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6320 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6322 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6324 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6325 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6327 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6328 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6330 // -------------------------------------------------------------------------------------
6331 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6332 iterType SMESH_MeshPartDS::methName() const \
6334 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6335 return _meshDS ? _meshDS->methName() : iterType \
6336 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6338 // -------------------------------------------------------------------------------------
6339 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6340 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6341 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6342 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6343 #undef _GET_ITER_DEFINE
6345 // END Implementation of SMESH_MeshPartDS
6347 //================================================================================