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_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
113 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cashed shapes if no more meshes remain; (the cash is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
243 if ( study->_is_nil() ) break;
244 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Return false if the mesh is not yet fully loaded from the study file
262 //================================================================================
264 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
267 return !_preMeshInfo;
270 //================================================================================
272 * \brief Load full mesh data from the study file
274 //================================================================================
276 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
278 Unexpect aCatch(SALOME_SalomeException);
280 _preMeshInfo->FullLoadFromFile();
283 //================================================================================
285 * \brief Remove all nodes and elements
287 //================================================================================
289 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
291 Unexpect aCatch(SALOME_SalomeException);
293 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
297 //CheckGeomGroupModif(); // issue 20145
299 catch(SALOME_Exception & S_ex) {
300 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
303 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
306 //================================================================================
308 * \brief Remove all nodes and elements for indicated shape
310 //================================================================================
312 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
313 throw (SALOME::SALOME_Exception)
315 Unexpect aCatch(SALOME_SalomeException);
317 _preMeshInfo->FullLoadFromFile();
320 _impl->ClearSubMesh( ShapeID );
322 catch(SALOME_Exception & S_ex) {
323 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
325 _impl->GetMeshDS()->Modified();
327 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
330 //=============================================================================
332 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
334 //=============================================================================
336 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
338 SMESH::DriverMED_ReadStatus res;
341 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
342 res = SMESH::DRS_OK; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
344 res = SMESH::DRS_EMPTY; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
346 res = SMESH::DRS_WARN_RENUMBER; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
348 res = SMESH::DRS_WARN_SKIP_ELEM; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
350 res = SMESH::DRS_WARN_DESCENDING; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
353 res = SMESH::DRS_FAIL; break;
358 //=============================================================================
360 * Convert ::SMESH_ComputeError to SMESH::ComputeError
362 //=============================================================================
364 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
366 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
367 errVar->subShapeID = -1;
368 errVar->hasBadMesh = false;
370 if ( !errorPtr || errorPtr->IsOK() )
372 errVar->code = SMESH::COMPERR_OK;
376 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
377 errVar->comment = errorPtr->myComment.c_str();
379 return errVar._retn();
382 //=============================================================================
386 * Imports mesh data from MED file
388 //=============================================================================
390 SMESH::DriverMED_ReadStatus
391 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
392 throw ( SALOME::SALOME_Exception )
394 Unexpect aCatch(SALOME_SalomeException);
397 status = _impl->MEDToMesh( theFileName, theMeshName );
399 catch( SALOME_Exception& S_ex ) {
400 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
403 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
406 CreateGroupServants();
408 int major, minor, release;
409 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
410 major = minor = release = -1;
411 _medFileInfo = new SMESH::MedFileInfo();
412 _medFileInfo->fileName = theFileName;
413 _medFileInfo->fileSize = 0;
414 _medFileInfo->major = major;
415 _medFileInfo->minor = minor;
416 _medFileInfo->release = release;
417 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
419 return ConvertDriverMEDReadStatus(status);
422 //================================================================================
424 * \brief Imports mesh data from the CGNS file
426 //================================================================================
428 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
429 const int theMeshIndex,
430 std::string& theMeshName )
431 throw ( SALOME::SALOME_Exception )
433 Unexpect aCatch(SALOME_SalomeException);
436 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
438 catch( SALOME_Exception& S_ex ) {
439 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
442 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
445 CreateGroupServants();
447 return ConvertDriverMEDReadStatus(status);
450 //================================================================================
452 * \brief Return string representation of a MED file version comprising nbDigits
454 //================================================================================
456 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
458 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
460 return CORBA::string_dup( ver.c_str() );
463 //=============================================================================
467 * Imports mesh data from MED file
469 //=============================================================================
471 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
472 throw ( SALOME::SALOME_Exception )
476 // Read mesh with name = <theMeshName> into SMESH_Mesh
477 _impl->UNVToMesh( theFileName );
479 CreateGroupServants();
481 SMESH_CATCH( SMESH::throwCorbaException );
486 //=============================================================================
490 * Imports mesh data from STL file
492 //=============================================================================
493 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
494 throw ( SALOME::SALOME_Exception )
498 // Read mesh with name = <theMeshName> into SMESH_Mesh
499 _impl->STLToMesh( theFileName );
501 SMESH_CATCH( SMESH::throwCorbaException );
506 //================================================================================
508 * \brief Function used in SMESH_CATCH by ImportGMFFile()
510 //================================================================================
514 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
516 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
520 //================================================================================
522 * \brief Imports data from a GMF file and returns an error description
524 //================================================================================
526 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
527 bool theMakeRequiredGroups )
528 throw (SALOME::SALOME_Exception)
530 SMESH_ComputeErrorPtr error;
533 #define SMESH_CAUGHT error =
536 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
538 SMESH_CATCH( exceptionToComputeError );
542 CreateGroupServants();
544 return ConvertComputeError( error );
547 //=============================================================================
551 //=============================================================================
553 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
555 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
556 (SMESH_Hypothesis::Hypothesis_Status theStatus)
559 RETURNCASE( HYP_OK );
560 RETURNCASE( HYP_MISSING );
561 RETURNCASE( HYP_CONCURENT );
562 RETURNCASE( HYP_BAD_PARAMETER );
563 RETURNCASE( HYP_HIDDEN_ALGO );
564 RETURNCASE( HYP_HIDING_ALGO );
565 RETURNCASE( HYP_UNKNOWN_FATAL );
566 RETURNCASE( HYP_INCOMPATIBLE );
567 RETURNCASE( HYP_NOTCONFORM );
568 RETURNCASE( HYP_ALREADY_EXIST );
569 RETURNCASE( HYP_BAD_DIM );
570 RETURNCASE( HYP_BAD_SUBSHAPE );
571 RETURNCASE( HYP_BAD_GEOMETRY );
572 RETURNCASE( HYP_NEED_SHAPE );
573 RETURNCASE( HYP_INCOMPAT_HYPS );
576 return SMESH::HYP_UNKNOWN_FATAL;
579 //=============================================================================
583 * calls internal addHypothesis() and then adds a reference to <anHyp> under
584 * the SObject actually having a reference to <aSubShape>.
585 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
587 //=============================================================================
589 SMESH::Hypothesis_Status
590 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
591 SMESH::SMESH_Hypothesis_ptr anHyp,
592 CORBA::String_out anErrorText)
593 throw(SALOME::SALOME_Exception)
595 Unexpect aCatch(SALOME_SalomeException);
597 _preMeshInfo->ForgetOrLoad();
600 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
601 anErrorText = error.c_str();
603 SMESH::SMESH_Mesh_var mesh( _this() );
604 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
606 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
607 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
609 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
611 // Update Python script
612 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
613 << aSubShape << ", " << anHyp << " )";
615 return ConvertHypothesisStatus(status);
618 //=============================================================================
622 //=============================================================================
624 SMESH_Hypothesis::Hypothesis_Status
625 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
626 SMESH::SMESH_Hypothesis_ptr anHyp,
627 std::string* anErrorText)
629 if(MYDEBUG) MESSAGE("addHypothesis");
631 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
632 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
634 if (CORBA::is_nil( anHyp ))
635 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
637 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
640 TopoDS_Shape myLocSubShape;
641 //use PseudoShape in case if mesh has no shape
643 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
645 myLocSubShape = _impl->GetShapeToMesh();
647 const int hypId = anHyp->GetId();
649 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
650 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
652 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
654 // assure there is a corresponding submesh
655 if ( !_impl->IsMainShape( myLocSubShape )) {
656 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
657 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
658 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
661 else if ( anErrorText )
663 *anErrorText = error;
666 catch(SALOME_Exception & S_ex)
668 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
673 //=============================================================================
677 //=============================================================================
679 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
680 SMESH::SMESH_Hypothesis_ptr anHyp)
681 throw(SALOME::SALOME_Exception)
683 Unexpect aCatch(SALOME_SalomeException);
685 _preMeshInfo->ForgetOrLoad();
687 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
688 SMESH::SMESH_Mesh_var mesh = _this();
690 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
692 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
693 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
695 // Update Python script
696 if(_impl->HasShapeToMesh())
697 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
698 << aSubShape << ", " << anHyp << " )";
700 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
703 return ConvertHypothesisStatus(status);
706 //=============================================================================
710 //=============================================================================
712 SMESH_Hypothesis::Hypothesis_Status
713 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
714 SMESH::SMESH_Hypothesis_ptr anHyp)
716 if(MYDEBUG) MESSAGE("removeHypothesis()");
718 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
719 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
721 if (CORBA::is_nil( anHyp ))
722 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
724 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
727 TopoDS_Shape myLocSubShape;
728 //use PseudoShape in case if mesh has no shape
729 if( _impl->HasShapeToMesh() )
730 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
732 myLocSubShape = _impl->GetShapeToMesh();
734 const int hypId = anHyp->GetId();
735 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
736 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
738 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
742 catch(SALOME_Exception & S_ex)
744 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
749 //=============================================================================
753 //=============================================================================
755 SMESH::ListOfHypothesis *
756 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
757 throw(SALOME::SALOME_Exception)
759 Unexpect aCatch(SALOME_SalomeException);
760 if (MYDEBUG) MESSAGE("GetHypothesisList");
761 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
762 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
764 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
767 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
768 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
769 myLocSubShape = _impl->GetShapeToMesh();
770 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
771 int i = 0, n = aLocalList.size();
774 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
775 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
776 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
778 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
779 if ( id_hypptr != _mapHypo.end() )
780 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
784 catch(SALOME_Exception & S_ex) {
785 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
788 return aList._retn();
791 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
793 Unexpect aCatch(SALOME_SalomeException);
794 if (MYDEBUG) MESSAGE("GetSubMeshes");
796 SMESH::submesh_array_var aList = new SMESH::submesh_array();
799 TPythonDump aPythonDump;
800 if ( !_mapSubMeshIor.empty() )
804 aList->length( _mapSubMeshIor.size() );
806 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
807 for ( ; it != _mapSubMeshIor.end(); it++ ) {
808 if ( CORBA::is_nil( it->second )) continue;
809 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
811 if (i > 1) aPythonDump << ", ";
812 aPythonDump << it->second;
816 catch(SALOME_Exception & S_ex) {
817 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
820 // Update Python script
821 if ( !_mapSubMeshIor.empty() )
822 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
824 return aList._retn();
827 //=============================================================================
831 //=============================================================================
833 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
834 const char* theName )
835 throw(SALOME::SALOME_Exception)
837 Unexpect aCatch(SALOME_SalomeException);
838 if (CORBA::is_nil(aSubShape))
839 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
841 SMESH::SMESH_subMesh_var subMesh;
842 SMESH::SMESH_Mesh_var aMesh = _this();
844 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
846 //Get or Create the SMESH_subMesh object implementation
848 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
850 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
852 TopoDS_Iterator it( myLocSubShape );
854 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
856 subMesh = getSubMesh( subMeshId );
858 // create a new subMesh object servant if there is none for the shape
859 if ( subMesh->_is_nil() )
860 subMesh = createSubMesh( aSubShape );
861 if ( _gen_i->CanPublishInStudy( subMesh ))
863 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
864 SALOMEDS::SObject_wrap aSO =
865 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
866 if ( !aSO->_is_nil()) {
867 // Update Python script
868 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
869 << aSubShape << ", '" << theName << "' )";
873 catch(SALOME_Exception & S_ex) {
874 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
876 return subMesh._retn();
879 //=============================================================================
883 //=============================================================================
885 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
886 throw (SALOME::SALOME_Exception)
890 if ( theSubMesh->_is_nil() )
893 GEOM::GEOM_Object_var aSubShape;
894 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
895 if ( !aStudy->_is_nil() ) {
896 // Remove submesh's SObject
897 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
898 if ( !anSO->_is_nil() ) {
899 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
900 SALOMEDS::SObject_wrap anObj, aRef;
901 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
902 anObj->ReferencedObject( aRef.inout() ))
904 CORBA::Object_var obj = aRef->GetObject();
905 aSubShape = GEOM::GEOM_Object::_narrow( obj );
907 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
908 // aSubShape = theSubMesh->GetSubShape();
910 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
911 builder->RemoveObjectWithChildren( anSO );
913 // Update Python script
914 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
918 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
920 _preMeshInfo->ForgetOrLoad();
922 SMESH_CATCH( SMESH::throwCorbaException );
925 //=============================================================================
929 //=============================================================================
931 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
932 const char* theName )
933 throw(SALOME::SALOME_Exception)
935 Unexpect aCatch(SALOME_SalomeException);
937 _preMeshInfo->FullLoadFromFile();
939 SMESH::SMESH_Group_var aNewGroup =
940 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
942 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
944 SMESH::SMESH_Mesh_var mesh = _this();
945 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
946 SALOMEDS::SObject_wrap aSO =
947 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
948 if ( !aSO->_is_nil())
949 // Update Python script
950 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
951 << theElemType << ", '" << theName << "' )";
953 return aNewGroup._retn();
956 //=============================================================================
960 //=============================================================================
961 SMESH::SMESH_GroupOnGeom_ptr
962 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
964 GEOM::GEOM_Object_ptr theGeomObj)
965 throw(SALOME::SALOME_Exception)
967 Unexpect aCatch(SALOME_SalomeException);
969 _preMeshInfo->FullLoadFromFile();
971 SMESH::SMESH_GroupOnGeom_var aNewGroup;
973 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
974 if ( !aShape.IsNull() )
977 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
979 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
981 SMESH::SMESH_Mesh_var mesh = _this();
982 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
983 SALOMEDS::SObject_wrap aSO =
984 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
985 if ( !aSO->_is_nil())
986 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
987 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
991 return aNewGroup._retn();
994 //================================================================================
996 * \brief Creates a group whose contents is defined by filter
997 * \param theElemType - group type
998 * \param theName - group name
999 * \param theFilter - the filter
1000 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1002 //================================================================================
1004 SMESH::SMESH_GroupOnFilter_ptr
1005 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1006 const char* theName,
1007 SMESH::Filter_ptr theFilter )
1008 throw (SALOME::SALOME_Exception)
1010 Unexpect aCatch(SALOME_SalomeException);
1012 _preMeshInfo->FullLoadFromFile();
1014 if ( CORBA::is_nil( theFilter ))
1015 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1017 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1019 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1021 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1022 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1025 if ( !aNewGroup->_is_nil() )
1026 aNewGroup->SetFilter( theFilter );
1028 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1030 SMESH::SMESH_Mesh_var mesh = _this();
1031 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1032 SALOMEDS::SObject_wrap aSO =
1033 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1035 if ( !aSO->_is_nil())
1036 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1037 << theElemType << ", '" << theName << "', " << theFilter << " )";
1039 return aNewGroup._retn();
1042 //=============================================================================
1046 //=============================================================================
1048 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1049 throw (SALOME::SALOME_Exception)
1051 if ( theGroup->_is_nil() )
1056 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1060 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1061 if ( !aStudy->_is_nil() )
1063 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1064 if ( !aGroupSO->_is_nil() )
1066 // Update Python script
1067 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1069 // Remove group's SObject
1070 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1071 builder->RemoveObjectWithChildren( aGroupSO );
1074 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1076 // Remove the group from SMESH data structures
1077 removeGroup( aGroup->GetLocalID() );
1079 SMESH_CATCH( SMESH::throwCorbaException );
1082 //=============================================================================
1084 * Remove group with its contents
1086 //=============================================================================
1088 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1089 throw (SALOME::SALOME_Exception)
1093 _preMeshInfo->FullLoadFromFile();
1095 if ( theGroup->_is_nil() )
1098 vector<int> nodeIds; // to remove nodes becoming free
1099 if ( !theGroup->IsEmpty() )
1101 CORBA::Long elemID = theGroup->GetID( 1 );
1102 int nbElemNodes = GetElemNbNodes( elemID );
1103 if ( nbElemNodes > 0 )
1104 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1108 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1109 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1110 while ( elemIt->more() )
1112 const SMDS_MeshElement* e = elemIt->next();
1114 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1115 while ( nIt->more() )
1116 nodeIds.push_back( nIt->next()->GetID() );
1118 _impl->GetMeshDS()->RemoveElement( e );
1121 // Remove free nodes
1122 if ( theGroup->GetType() != SMESH::NODE )
1123 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1124 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1125 if ( n->NbInverseElements() == 0 )
1126 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1128 TPythonDump pyDump; // Supress dump from RemoveGroup()
1130 // Update Python script (theGroup must be alive for this)
1131 pyDump << SMESH::SMESH_Mesh_var(_this())
1132 << ".RemoveGroupWithContents( " << theGroup << " )";
1135 RemoveGroup( theGroup );
1137 SMESH_CATCH( SMESH::throwCorbaException );
1140 //================================================================================
1142 * \brief Get the list of groups existing in the mesh
1143 * \retval SMESH::ListOfGroups * - list of groups
1145 //================================================================================
1147 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1149 Unexpect aCatch(SALOME_SalomeException);
1150 if (MYDEBUG) MESSAGE("GetGroups");
1152 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1155 TPythonDump aPythonDump;
1156 if ( !_mapGroups.empty() )
1158 aPythonDump << "[ ";
1160 aList->length( _mapGroups.size() );
1162 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1163 for ( ; it != _mapGroups.end(); it++ ) {
1164 if ( CORBA::is_nil( it->second )) continue;
1165 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1167 if (i > 1) aPythonDump << ", ";
1168 aPythonDump << it->second;
1172 catch(SALOME_Exception & S_ex) {
1173 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1175 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1177 return aList._retn();
1180 //=============================================================================
1182 * Get number of groups existing in the mesh
1184 //=============================================================================
1186 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1188 Unexpect aCatch(SALOME_SalomeException);
1189 return _mapGroups.size();
1192 //=============================================================================
1194 * New group including all mesh elements present in initial groups is created.
1196 //=============================================================================
1198 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1199 SMESH::SMESH_GroupBase_ptr theGroup2,
1200 const char* theName )
1201 throw (SALOME::SALOME_Exception)
1203 SMESH::SMESH_Group_var aResGrp;
1207 _preMeshInfo->FullLoadFromFile();
1209 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1210 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1212 if ( theGroup1->GetType() != theGroup2->GetType() )
1213 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1218 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1219 if ( aResGrp->_is_nil() )
1220 return SMESH::SMESH_Group::_nil();
1222 aResGrp->AddFrom( theGroup1 );
1223 aResGrp->AddFrom( theGroup2 );
1225 // Update Python script
1226 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1227 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1229 SMESH_CATCH( SMESH::throwCorbaException );
1231 return aResGrp._retn();
1234 //=============================================================================
1236 * \brief New group including all mesh elements present in initial groups is created.
1237 * \param theGroups list of groups
1238 * \param theName name of group to be created
1239 * \return pointer to the new group
1241 //=============================================================================
1243 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1244 const char* theName )
1245 throw (SALOME::SALOME_Exception)
1247 SMESH::SMESH_Group_var aResGrp;
1250 _preMeshInfo->FullLoadFromFile();
1253 return SMESH::SMESH_Group::_nil();
1258 SMESH::ElementType aType = SMESH::ALL;
1259 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1261 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1262 if ( CORBA::is_nil( aGrp ) )
1264 if ( aType == SMESH::ALL )
1265 aType = aGrp->GetType();
1266 else if ( aType != aGrp->GetType() )
1267 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1270 if ( aType == SMESH::ALL )
1271 return SMESH::SMESH_Group::_nil();
1276 aResGrp = CreateGroup( aType, theName );
1277 if ( aResGrp->_is_nil() )
1278 return SMESH::SMESH_Group::_nil();
1280 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1281 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1283 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1284 if ( !CORBA::is_nil( aGrp ) )
1286 aResGrp->AddFrom( aGrp );
1287 if ( g > 0 ) pyDump << ", ";
1291 pyDump << " ], '" << theName << "' )";
1293 SMESH_CATCH( SMESH::throwCorbaException );
1295 return aResGrp._retn();
1298 //=============================================================================
1300 * New group is created. All mesh elements that are
1301 * present in both initial groups are added to the new one.
1303 //=============================================================================
1305 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1306 SMESH::SMESH_GroupBase_ptr theGroup2,
1307 const char* theName )
1308 throw (SALOME::SALOME_Exception)
1310 SMESH::SMESH_Group_var aResGrp;
1315 _preMeshInfo->FullLoadFromFile();
1317 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1318 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1320 if ( theGroup1->GetType() != theGroup2->GetType() )
1321 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1325 // Create Intersection
1326 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1327 if ( aResGrp->_is_nil() )
1328 return aResGrp._retn();
1330 SMESHDS_GroupBase* groupDS1 = 0;
1331 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1332 groupDS1 = grp_i->GetGroupDS();
1334 SMESHDS_GroupBase* groupDS2 = 0;
1335 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1336 groupDS2 = grp_i->GetGroupDS();
1338 SMESHDS_Group* resGroupDS = 0;
1339 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1340 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1342 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1344 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1345 while ( elemIt1->more() )
1347 const SMDS_MeshElement* e = elemIt1->next();
1348 if ( groupDS2->Contains( e ))
1349 resGroupDS->SMDSGroup().Add( e );
1352 // Update Python script
1353 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1354 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1356 SMESH_CATCH( SMESH::throwCorbaException );
1358 return aResGrp._retn();
1361 //=============================================================================
1363 \brief Intersect list of groups. New group is created. All mesh elements that
1364 are present in all initial groups simultaneously are added to the new one.
1365 \param theGroups list of groups
1366 \param theName name of group to be created
1367 \return pointer on the group
1369 //=============================================================================
1370 SMESH::SMESH_Group_ptr
1371 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1372 const char* theName )
1373 throw (SALOME::SALOME_Exception)
1375 SMESH::SMESH_Group_var aResGrp;
1380 _preMeshInfo->FullLoadFromFile();
1383 return SMESH::SMESH_Group::_nil();
1385 // check types and get SMESHDS_GroupBase's
1386 SMESH::ElementType aType = SMESH::ALL;
1387 vector< SMESHDS_GroupBase* > groupVec;
1388 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1390 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1391 if ( CORBA::is_nil( aGrp ) )
1393 if ( aType == SMESH::ALL )
1394 aType = aGrp->GetType();
1395 else if ( aType != aGrp->GetType() )
1396 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1399 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1400 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1402 if ( grpDS->IsEmpty() )
1407 groupVec.push_back( grpDS );
1410 if ( aType == SMESH::ALL ) // all groups are nil
1411 return SMESH::SMESH_Group::_nil();
1416 aResGrp = CreateGroup( aType, theName );
1418 SMESHDS_Group* resGroupDS = 0;
1419 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1420 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1421 if ( !resGroupDS || groupVec.empty() )
1422 return aResGrp._retn();
1425 size_t i, nb = groupVec.size();
1426 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1427 while ( elemIt1->more() )
1429 const SMDS_MeshElement* e = elemIt1->next();
1431 for ( i = 1; ( i < nb && inAll ); ++i )
1432 inAll = groupVec[i]->Contains( e );
1435 resGroupDS->SMDSGroup().Add( e );
1438 // Update Python script
1439 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1440 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1442 SMESH_CATCH( SMESH::throwCorbaException );
1444 return aResGrp._retn();
1447 //=============================================================================
1449 * New group is created. All mesh elements that are present in
1450 * a main group but is not present in a tool group are added to the new one
1452 //=============================================================================
1454 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1455 SMESH::SMESH_GroupBase_ptr theGroup2,
1456 const char* theName )
1457 throw (SALOME::SALOME_Exception)
1459 SMESH::SMESH_Group_var aResGrp;
1464 _preMeshInfo->FullLoadFromFile();
1466 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1467 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1469 if ( theGroup1->GetType() != theGroup2->GetType() )
1470 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1474 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1475 if ( aResGrp->_is_nil() )
1476 return aResGrp._retn();
1478 SMESHDS_GroupBase* groupDS1 = 0;
1479 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1480 groupDS1 = grp_i->GetGroupDS();
1482 SMESHDS_GroupBase* groupDS2 = 0;
1483 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1484 groupDS2 = grp_i->GetGroupDS();
1486 SMESHDS_Group* resGroupDS = 0;
1487 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1488 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1490 if ( groupDS1 && groupDS2 && resGroupDS )
1492 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1493 while ( elemIt1->more() )
1495 const SMDS_MeshElement* e = elemIt1->next();
1496 if ( !groupDS2->Contains( e ))
1497 resGroupDS->SMDSGroup().Add( e );
1500 // Update Python script
1501 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1502 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1504 SMESH_CATCH( SMESH::throwCorbaException );
1506 return aResGrp._retn();
1509 //=============================================================================
1511 \brief Cut lists of groups. New group is created. All mesh elements that are
1512 present in main groups but do not present in tool groups are added to the new one
1513 \param theMainGroups list of main groups
1514 \param theToolGroups list of tool groups
1515 \param theName name of group to be created
1516 \return pointer on the group
1518 //=============================================================================
1519 SMESH::SMESH_Group_ptr
1520 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1521 const SMESH::ListOfGroups& theToolGroups,
1522 const char* theName )
1523 throw (SALOME::SALOME_Exception)
1525 SMESH::SMESH_Group_var aResGrp;
1530 _preMeshInfo->FullLoadFromFile();
1533 return SMESH::SMESH_Group::_nil();
1535 // check types and get SMESHDS_GroupBase's
1536 SMESH::ElementType aType = SMESH::ALL;
1537 vector< SMESHDS_GroupBase* > toolGroupVec;
1538 vector< SMDS_ElemIteratorPtr > mainIterVec;
1540 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1542 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1543 if ( CORBA::is_nil( aGrp ) )
1545 if ( aType == SMESH::ALL )
1546 aType = aGrp->GetType();
1547 else if ( aType != aGrp->GetType() )
1548 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1550 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1551 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1552 if ( !grpDS->IsEmpty() )
1553 mainIterVec.push_back( grpDS->GetElements() );
1555 if ( aType == SMESH::ALL ) // all main groups are nil
1556 return SMESH::SMESH_Group::_nil();
1557 if ( mainIterVec.empty() ) // all main groups are empty
1558 return aResGrp._retn();
1560 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1562 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1563 if ( CORBA::is_nil( aGrp ) )
1565 if ( aType != aGrp->GetType() )
1566 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1568 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1569 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1570 toolGroupVec.push_back( grpDS );
1576 aResGrp = CreateGroup( aType, theName );
1578 SMESHDS_Group* resGroupDS = 0;
1579 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1580 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1582 return aResGrp._retn();
1585 size_t i, nb = toolGroupVec.size();
1586 SMDS_ElemIteratorPtr mainElemIt
1587 ( new SMDS_IteratorOnIterators
1588 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1589 while ( mainElemIt->more() )
1591 const SMDS_MeshElement* e = mainElemIt->next();
1593 for ( i = 0; ( i < nb && !isIn ); ++i )
1594 isIn = toolGroupVec[i]->Contains( e );
1597 resGroupDS->SMDSGroup().Add( e );
1600 // Update Python script
1601 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1602 << ".CutListOfGroups( " << theMainGroups << ", "
1603 << theToolGroups << ", '" << theName << "' )";
1605 SMESH_CATCH( SMESH::throwCorbaException );
1607 return aResGrp._retn();
1610 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1612 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1613 bool & toStopChecking )
1615 toStopChecking = ( nbCommon < nbChecked );
1616 return nbCommon == nbNodes;
1618 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1619 bool & toStopChecking )
1621 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1622 return nbCommon == nbCorners;
1624 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1625 bool & toStopChecking )
1627 return nbCommon > 0;
1629 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1630 bool & toStopChecking )
1632 return nbCommon >= (nbNodes+1) / 2;
1636 //=============================================================================
1638 * Create a group of entities basing on nodes of other groups.
1639 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1640 * \param [in] anElemType - a type of elements to include to the new group.
1641 * \param [in] theName - a name of the new group.
1642 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1643 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1644 * new group provided that it is based on nodes of an element of \a aListOfGroups
1645 * \return SMESH_Group - the created group
1647 // IMP 19939, bug 22010, IMP 22635
1648 //=============================================================================
1650 SMESH::SMESH_Group_ptr
1651 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1652 SMESH::ElementType theElemType,
1653 const char* theName,
1654 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1655 CORBA::Boolean theUnderlyingOnly)
1656 throw (SALOME::SALOME_Exception)
1658 SMESH::SMESH_Group_var aResGrp;
1662 _preMeshInfo->FullLoadFromFile();
1664 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1666 if ( !theName || !aMeshDS )
1667 return SMESH::SMESH_Group::_nil();
1669 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1671 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1672 SMESH_Comment nbCoNoStr( "SMESH.");
1673 switch ( theNbCommonNodes ) {
1674 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1675 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1676 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1677 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1678 default: return aResGrp._retn();
1680 int nbChecked, nbCommon, nbNodes, nbCorners;
1686 aResGrp = CreateGroup( theElemType, theName );
1687 if ( aResGrp->_is_nil() )
1688 return SMESH::SMESH_Group::_nil();
1690 SMESHDS_GroupBase* groupBaseDS =
1691 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1692 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1694 vector<bool> isNodeInGroups;
1696 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1698 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1699 if ( CORBA::is_nil( aGrp ) )
1701 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1702 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1705 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1706 if ( !elIt ) continue;
1708 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1710 while ( elIt->more() ) {
1711 const SMDS_MeshElement* el = elIt->next();
1712 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1713 while ( nIt->more() )
1714 resGroupCore.Add( nIt->next() );
1717 // get elements of theElemType based on nodes of every element of group
1718 else if ( theUnderlyingOnly )
1720 while ( elIt->more() )
1722 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1723 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1724 TIDSortedElemSet checkedElems;
1725 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1726 while ( nIt->more() )
1728 const SMDS_MeshNode* n = nIt->next();
1729 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1730 // check nodes of elements of theElemType around el
1731 while ( elOfTypeIt->more() )
1733 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1734 if ( !checkedElems.insert( elOfType ).second ) continue;
1735 nbNodes = elOfType->NbNodes();
1736 nbCorners = elOfType->NbCornerNodes();
1738 bool toStopChecking = false;
1739 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1740 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1741 if ( elNodes.count( nIt2->next() ) &&
1742 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1744 resGroupCore.Add( elOfType );
1751 // get all nodes of elements of groups
1754 while ( elIt->more() )
1756 const SMDS_MeshElement* el = elIt->next(); // an element of group
1757 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1758 while ( nIt->more() )
1760 const SMDS_MeshNode* n = nIt->next();
1761 if ( n->GetID() >= (int) isNodeInGroups.size() )
1762 isNodeInGroups.resize( n->GetID() + 1, false );
1763 isNodeInGroups[ n->GetID() ] = true;
1769 // Get elements of theElemType based on a certain number of nodes of elements of groups
1770 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1772 const SMDS_MeshNode* n;
1773 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1774 const int isNodeInGroupsSize = isNodeInGroups.size();
1775 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1777 if ( !isNodeInGroups[ iN ] ||
1778 !( n = aMeshDS->FindNode( iN )))
1781 // check nodes of elements of theElemType around n
1782 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1783 while ( elOfTypeIt->more() )
1785 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1786 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1791 nbNodes = elOfType->NbNodes();
1792 nbCorners = elOfType->NbCornerNodes();
1794 bool toStopChecking = false;
1795 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1796 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1798 const int nID = nIt->next()->GetID();
1799 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1800 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1802 resGroupCore.Add( elOfType );
1810 // Update Python script
1811 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1812 << ".CreateDimGroup( "
1813 << theGroups << ", " << theElemType << ", '" << theName << "', "
1814 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1816 SMESH_CATCH( SMESH::throwCorbaException );
1818 return aResGrp._retn();
1821 //================================================================================
1823 * \brief Remember GEOM group data
1825 //================================================================================
1827 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1828 CORBA::Object_ptr theSmeshObj)
1830 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1833 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1834 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1835 if ( groupSO->_is_nil() )
1838 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1839 GEOM::GEOM_IGroupOperations_wrap groupOp =
1840 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1841 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1844 _geomGroupData.push_back( TGeomGroupData() );
1845 TGeomGroupData & groupData = _geomGroupData.back();
1847 CORBA::String_var entry = groupSO->GetID();
1848 groupData._groupEntry = entry.in();
1850 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1851 groupData._indices.insert( ids[i] );
1853 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1854 // shape index in SMESHDS
1855 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1856 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1859 //================================================================================
1861 * Remove GEOM group data relating to removed smesh object
1863 //================================================================================
1865 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1867 list<TGeomGroupData>::iterator
1868 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1869 for ( ; data != dataEnd; ++data ) {
1870 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1871 _geomGroupData.erase( data );
1877 //================================================================================
1879 * \brief Return new group contents if it has been changed and update group data
1881 //================================================================================
1883 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1885 TopoDS_Shape newShape;
1888 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1889 if ( study->_is_nil() ) return newShape; // means "not changed"
1890 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1891 if ( !groupSO->_is_nil() )
1893 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1894 if ( CORBA::is_nil( groupObj )) return newShape;
1895 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1897 // get indices of group items
1898 set<int> curIndices;
1899 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1900 GEOM::GEOM_IGroupOperations_wrap groupOp =
1901 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1902 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1903 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1904 curIndices.insert( ids[i] );
1906 if ( groupData._indices == curIndices )
1907 return newShape; // group not changed
1910 groupData._indices = curIndices;
1912 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1913 if ( !geomClient ) return newShape;
1914 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1915 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1916 newShape = _gen_i->GeomObjectToShape( geomGroup );
1919 if ( newShape.IsNull() ) {
1920 // geom group becomes empty - return empty compound
1921 TopoDS_Compound compound;
1922 BRep_Builder().MakeCompound(compound);
1923 newShape = compound;
1930 //-----------------------------------------------------------------------------
1932 * \brief Storage of shape and index used in CheckGeomGroupModif()
1934 struct TIndexedShape
1937 TopoDS_Shape _shape;
1938 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1940 //-----------------------------------------------------------------------------
1942 * \brief Data to re-create a group on geometry
1944 struct TGroupOnGeomData
1948 SMDSAbs_ElementType _type;
1950 Quantity_Color _color;
1954 //=============================================================================
1956 * \brief Update data if geometry changes
1960 //=============================================================================
1962 void SMESH_Mesh_i::CheckGeomModif()
1964 if ( !_impl->HasShapeToMesh() ) return;
1966 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1967 if ( study->_is_nil() ) return;
1969 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1970 //if ( mainGO->_is_nil() ) return;
1972 // Update after group modification
1974 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1975 called by other mesh (IPAL52735) */
1976 mainGO->GetType() == GEOM_GROUP ||
1977 mainGO->GetTick() == _mainShapeTick )
1979 CheckGeomGroupModif();
1983 // Update after shape transformation like Translate
1985 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1986 if ( !geomClient ) return;
1987 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1988 if ( geomGen->_is_nil() ) return;
1990 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1991 geomClient->RemoveShapeFromBuffer( ior.in() );
1993 // Update data taking into account that
1994 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1997 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1998 if ( newShape.IsNull() )
2001 _mainShapeTick = mainGO->GetTick();
2003 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2005 // store data of groups on geometry
2006 vector< TGroupOnGeomData > groupsData;
2007 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2008 groupsData.reserve( groups.size() );
2009 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2010 for ( ; g != groups.end(); ++g )
2011 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2013 TGroupOnGeomData data;
2014 data._oldID = group->GetID();
2015 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2016 data._type = group->GetType();
2017 data._name = group->GetStoreName();
2018 data._color = group->GetColor();
2019 groupsData.push_back( data );
2021 // store assigned hypotheses
2022 vector< pair< int, THypList > > ids2Hyps;
2023 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2024 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2026 const TopoDS_Shape& s = s2hyps.Key();
2027 const THypList& hyps = s2hyps.ChangeValue();
2028 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2031 // change shape to mesh
2032 int oldNbSubShapes = meshDS->MaxShapeIndex();
2033 _impl->ShapeToMesh( TopoDS_Shape() );
2034 _impl->ShapeToMesh( newShape );
2036 // re-add shapes of geom groups
2037 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2038 for ( ; data != _geomGroupData.end(); ++data )
2040 TopoDS_Shape newShape = newGroupShape( *data );
2041 if ( !newShape.IsNull() )
2043 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2045 TopoDS_Compound compound;
2046 BRep_Builder().MakeCompound( compound );
2047 BRep_Builder().Add( compound, newShape );
2048 newShape = compound;
2050 _impl->GetSubMesh( newShape );
2053 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2054 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2055 SALOME::INTERNAL_ERROR );
2057 // re-assign hypotheses
2058 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2060 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2061 const THypList& hyps = ids2Hyps[i].second;
2062 THypList::const_iterator h = hyps.begin();
2063 for ( ; h != hyps.end(); ++h )
2064 _impl->AddHypothesis( s, (*h)->GetID() );
2068 for ( size_t i = 0; i < groupsData.size(); ++i )
2070 const TGroupOnGeomData& data = groupsData[i];
2072 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2073 if ( i2g == _mapGroups.end() ) continue;
2075 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2076 if ( !gr_i ) continue;
2079 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2080 meshDS->IndexToShape( data._shapeID ));
2083 _mapGroups.erase( i2g );
2087 g->GetGroupDS()->SetColor( data._color );
2088 gr_i->changeLocalId( id );
2089 _mapGroups[ id ] = i2g->second;
2090 if ( data._oldID != id )
2091 _mapGroups.erase( i2g );
2095 // update _mapSubMesh
2096 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2097 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2098 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2102 //=============================================================================
2104 * \brief Update objects depending on changed geom groups
2106 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2107 * issue 0020210: Update of a smesh group after modification of the associated geom group
2109 //=============================================================================
2111 void SMESH_Mesh_i::CheckGeomGroupModif()
2113 if ( !_impl->HasShapeToMesh() ) return;
2115 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2116 if ( study->_is_nil() ) return;
2118 CORBA::Long nbEntities = NbNodes() + NbElements();
2120 // Check if group contents changed
2122 typedef map< string, TopoDS_Shape > TEntry2Geom;
2123 TEntry2Geom newGroupContents;
2125 list<TGeomGroupData>::iterator
2126 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2127 for ( ; data != dataEnd; ++data )
2129 pair< TEntry2Geom::iterator, bool > it_new =
2130 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2131 bool processedGroup = !it_new.second;
2132 TopoDS_Shape& newShape = it_new.first->second;
2133 if ( !processedGroup )
2134 newShape = newGroupShape( *data );
2135 if ( newShape.IsNull() )
2136 continue; // no changes
2139 _preMeshInfo->ForgetOrLoad();
2141 if ( processedGroup ) { // update group indices
2142 list<TGeomGroupData>::iterator data2 = data;
2143 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2144 data->_indices = data2->_indices;
2147 // Update SMESH objects according to new GEOM group contents
2149 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2150 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2152 int oldID = submesh->GetId();
2153 if ( !_mapSubMeshIor.count( oldID ))
2155 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2157 // update hypotheses
2158 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2159 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2160 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2162 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2163 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2165 // care of submeshes
2166 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2167 int newID = newSubmesh->GetId();
2168 if ( newID != oldID ) {
2169 _mapSubMesh [ newID ] = newSubmesh;
2170 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2171 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2172 _mapSubMesh. erase(oldID);
2173 _mapSubMesh_i. erase(oldID);
2174 _mapSubMeshIor.erase(oldID);
2175 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2180 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2181 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2182 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2184 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2186 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2187 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2188 ds->SetShape( newShape );
2193 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2194 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2196 // Remove groups and submeshes basing on removed sub-shapes
2198 TopTools_MapOfShape newShapeMap;
2199 TopoDS_Iterator shapeIt( newShape );
2200 for ( ; shapeIt.More(); shapeIt.Next() )
2201 newShapeMap.Add( shapeIt.Value() );
2203 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2204 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2206 if ( newShapeMap.Contains( shapeIt.Value() ))
2208 TopTools_IndexedMapOfShape oldShapeMap;
2209 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2210 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2212 const TopoDS_Shape& oldShape = oldShapeMap(i);
2213 int oldInd = meshDS->ShapeToIndex( oldShape );
2215 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2216 if ( i_smIor != _mapSubMeshIor.end() ) {
2217 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2220 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2221 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2223 // check if a group bases on oldInd shape
2224 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2225 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2226 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2227 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2229 RemoveGroup( i_grp->second ); // several groups can base on same shape
2230 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2235 // Reassign hypotheses and update groups after setting the new shape to mesh
2237 // collect anassigned hypotheses
2238 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2239 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2240 TShapeHypList assignedHyps;
2241 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2243 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2244 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2245 if ( !hyps.empty() ) {
2246 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2247 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2248 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2251 // collect shapes supporting groups
2252 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2253 TShapeTypeList groupData;
2254 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2255 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2256 for ( ; grIt != groups.end(); ++grIt )
2258 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2260 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2262 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2264 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2265 _impl->ShapeToMesh( newShape );
2267 // reassign hypotheses
2268 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2269 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2271 TIndexedShape& geom = indS_hyps->first;
2272 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2273 int oldID = geom._index;
2274 int newID = meshDS->ShapeToIndex( geom._shape );
2275 if ( oldID == 1 ) { // main shape
2277 geom._shape = newShape;
2281 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2282 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2283 // care of sub-meshes
2284 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2285 if ( newID != oldID ) {
2286 _mapSubMesh [ newID ] = newSubmesh;
2287 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2288 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2289 _mapSubMesh. erase(oldID);
2290 _mapSubMesh_i. erase(oldID);
2291 _mapSubMeshIor.erase(oldID);
2292 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2296 TShapeTypeList::iterator geomType = groupData.begin();
2297 for ( ; geomType != groupData.end(); ++geomType )
2299 const TIndexedShape& geom = geomType->first;
2300 int oldID = geom._index;
2301 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2304 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2305 CORBA::String_var name = groupSO->GetName();
2307 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2309 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2310 group_i->changeLocalId( newID );
2313 break; // everything has been updated
2316 } // loop on group data
2320 CORBA::Long newNbEntities = NbNodes() + NbElements();
2321 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2322 if ( newNbEntities != nbEntities )
2324 // Add all SObjects with icons to soToUpdateIcons
2325 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2327 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2328 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2329 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2331 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2332 i_gr != _mapGroups.end(); ++i_gr ) // groups
2333 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2336 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2337 for ( ; so != soToUpdateIcons.end(); ++so )
2338 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2341 //=============================================================================
2343 * \brief Create standalone group from a group on geometry or filter
2345 //=============================================================================
2347 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2348 throw (SALOME::SALOME_Exception)
2350 SMESH::SMESH_Group_var aGroup;
2355 _preMeshInfo->FullLoadFromFile();
2357 if ( theGroup->_is_nil() )
2358 return aGroup._retn();
2360 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2362 return aGroup._retn();
2364 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2366 const int anId = aGroupToRem->GetLocalID();
2367 if ( !_impl->ConvertToStandalone( anId ) )
2368 return aGroup._retn();
2369 removeGeomGroupData( theGroup );
2371 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2373 // remove old instance of group from own map
2374 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2375 _mapGroups.erase( anId );
2377 SALOMEDS::StudyBuilder_var builder;
2378 SALOMEDS::SObject_wrap aGroupSO;
2379 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2380 if ( !aStudy->_is_nil() ) {
2381 builder = aStudy->NewBuilder();
2382 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2383 if ( !aGroupSO->_is_nil() )
2385 // remove reference to geometry
2386 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2387 for ( ; chItr->More(); chItr->Next() )
2388 // Remove group's child SObject
2389 builder->RemoveObject( chItr->Value() );
2391 // Update Python script
2392 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2393 << ".ConvertToStandalone( " << aGroupSO << " )";
2395 // change icon of Group on Filter
2398 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2399 const int isEmpty = ( elemTypes->length() == 0 );
2402 SALOMEDS::GenericAttribute_wrap anAttr =
2403 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2404 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2405 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2411 // remember new group in own map
2412 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2413 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2415 // register CORBA object for persistence
2416 _gen_i->RegisterObject( aGroup );
2418 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2419 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2420 //aGroup->Register();
2421 aGroupToRem->UnRegister();
2423 SMESH_CATCH( SMESH::throwCorbaException );
2425 return aGroup._retn();
2428 //=============================================================================
2432 //=============================================================================
2434 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2436 if(MYDEBUG) MESSAGE( "createSubMesh" );
2437 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2438 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2439 const int subMeshId = mySubMesh->GetId();
2441 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2442 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2444 _mapSubMesh [subMeshId] = mySubMesh;
2445 _mapSubMesh_i [subMeshId] = subMeshServant;
2446 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2448 subMeshServant->Register();
2450 // register CORBA object for persistence
2451 int nextId = _gen_i->RegisterObject( subMesh );
2452 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2453 else { nextId = 0; } // avoid "unused variable" warning
2455 // to track changes of GEOM groups
2456 addGeomGroupData( theSubShapeObject, subMesh );
2458 return subMesh._retn();
2461 //=======================================================================
2462 //function : getSubMesh
2464 //=======================================================================
2466 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2468 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2469 if ( it == _mapSubMeshIor.end() )
2470 return SMESH::SMESH_subMesh::_nil();
2472 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2475 //=============================================================================
2479 //=============================================================================
2481 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2482 GEOM::GEOM_Object_ptr theSubShapeObject )
2484 bool isHypChanged = false;
2485 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2486 return isHypChanged;
2488 const int subMeshId = theSubMesh->GetId();
2490 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2492 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2494 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2497 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2498 isHypChanged = !hyps.empty();
2499 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2500 for ( ; hyp != hyps.end(); ++hyp )
2501 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2508 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2509 isHypChanged = ( aHypList->length() > 0 );
2510 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2511 removeHypothesis( theSubShapeObject, aHypList[i] );
2514 catch( const SALOME::SALOME_Exception& ) {
2515 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2517 removeGeomGroupData( theSubShapeObject );
2521 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2522 if ( id_smi != _mapSubMesh_i.end() )
2523 id_smi->second->UnRegister();
2525 // remove a CORBA object
2526 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2527 if ( id_smptr != _mapSubMeshIor.end() )
2528 SMESH::SMESH_subMesh_var( id_smptr->second );
2530 _mapSubMesh.erase(subMeshId);
2531 _mapSubMesh_i.erase(subMeshId);
2532 _mapSubMeshIor.erase(subMeshId);
2534 return isHypChanged;
2537 //=============================================================================
2541 //=============================================================================
2543 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2544 const char* theName,
2545 const TopoDS_Shape& theShape,
2546 const SMESH_PredicatePtr& thePredicate )
2548 std::string newName;
2549 if ( !theName || strlen( theName ) == 0 )
2551 std::set< std::string > presentNames;
2552 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2553 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2555 CORBA::String_var name = i_gr->second->GetName();
2556 presentNames.insert( name.in() );
2559 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2560 } while ( !presentNames.insert( newName ).second );
2561 theName = newName.c_str();
2564 SMESH::SMESH_GroupBase_var aGroup;
2565 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2567 SMESH_GroupBase_i* aGroupImpl;
2568 if ( !theShape.IsNull() )
2569 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2570 else if ( thePredicate )
2571 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2573 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2575 aGroup = aGroupImpl->_this();
2576 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2577 aGroupImpl->Register();
2579 // register CORBA object for persistence
2580 int nextId = _gen_i->RegisterObject( aGroup );
2581 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2582 else { nextId = 0; } // avoid "unused variable" warning in release mode
2584 // to track changes of GEOM groups
2585 if ( !theShape.IsNull() ) {
2586 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2587 addGeomGroupData( geom, aGroup );
2590 return aGroup._retn();
2593 //=============================================================================
2595 * SMESH_Mesh_i::removeGroup
2597 * Should be called by ~SMESH_Group_i()
2599 //=============================================================================
2601 void SMESH_Mesh_i::removeGroup( const int theId )
2603 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2604 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2605 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2606 _mapGroups.erase( theId );
2607 removeGeomGroupData( group );
2608 if ( !_impl->RemoveGroup( theId ))
2610 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2611 RemoveGroup( group );
2613 group->UnRegister();
2617 //=============================================================================
2621 //=============================================================================
2623 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2624 throw(SALOME::SALOME_Exception)
2626 SMESH::log_array_var aLog;
2630 _preMeshInfo->FullLoadFromFile();
2632 list < SMESHDS_Command * >logDS = _impl->GetLog();
2633 aLog = new SMESH::log_array;
2635 int lg = logDS.size();
2638 list < SMESHDS_Command * >::iterator its = logDS.begin();
2639 while(its != logDS.end()){
2640 SMESHDS_Command *com = *its;
2641 int comType = com->GetType();
2643 int lgcom = com->GetNumber();
2645 const list < int >&intList = com->GetIndexes();
2646 int inum = intList.size();
2648 list < int >::const_iterator ii = intList.begin();
2649 const list < double >&coordList = com->GetCoords();
2650 int rnum = coordList.size();
2652 list < double >::const_iterator ir = coordList.begin();
2653 aLog[indexLog].commandType = comType;
2654 aLog[indexLog].number = lgcom;
2655 aLog[indexLog].coords.length(rnum);
2656 aLog[indexLog].indexes.length(inum);
2657 for(int i = 0; i < rnum; i++){
2658 aLog[indexLog].coords[i] = *ir;
2659 //MESSAGE(" "<<i<<" "<<ir.Value());
2662 for(int i = 0; i < inum; i++){
2663 aLog[indexLog].indexes[i] = *ii;
2664 //MESSAGE(" "<<i<<" "<<ii.Value());
2673 SMESH_CATCH( SMESH::throwCorbaException );
2675 return aLog._retn();
2679 //=============================================================================
2683 //=============================================================================
2685 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2689 SMESH_CATCH( SMESH::throwCorbaException );
2692 //=============================================================================
2696 //=============================================================================
2698 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2703 //=============================================================================
2707 //=============================================================================
2709 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2714 //=============================================================================
2717 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2718 // issue 0020918: groups removal is caused by hyp modification
2719 // issue 0021208: to forget not loaded mesh data at hyp modification
2720 struct TCallUp_i : public SMESH_Mesh::TCallUp
2722 SMESH_Mesh_i* _mesh;
2723 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2724 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2725 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2726 virtual void Load () { _mesh->Load(); }
2730 //================================================================================
2732 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2734 //================================================================================
2736 void SMESH_Mesh_i::onHypothesisModified()
2739 _preMeshInfo->ForgetOrLoad();
2742 //=============================================================================
2746 //=============================================================================
2748 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2750 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2753 _impl->SetCallUp( new TCallUp_i(this));
2756 //=============================================================================
2760 //=============================================================================
2762 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2764 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2768 //=============================================================================
2770 * Return mesh editor
2772 //=============================================================================
2774 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2775 throw (SALOME::SALOME_Exception)
2777 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2781 _preMeshInfo->FullLoadFromFile();
2783 // Create MeshEditor
2785 _editor = new SMESH_MeshEditor_i( this, false );
2786 aMeshEdVar = _editor->_this();
2788 // Update Python script
2789 TPythonDump() << _editor << " = "
2790 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2792 SMESH_CATCH( SMESH::throwCorbaException );
2794 return aMeshEdVar._retn();
2797 //=============================================================================
2799 * Return mesh edition previewer
2801 //=============================================================================
2803 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2804 throw (SALOME::SALOME_Exception)
2806 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2810 _preMeshInfo->FullLoadFromFile();
2812 if ( !_previewEditor )
2813 _previewEditor = new SMESH_MeshEditor_i( this, true );
2814 aMeshEdVar = _previewEditor->_this();
2816 SMESH_CATCH( SMESH::throwCorbaException );
2818 return aMeshEdVar._retn();
2821 //================================================================================
2823 * \brief Return true if the mesh has been edited since a last total re-compute
2824 * and those modifications may prevent successful partial re-compute
2826 //================================================================================
2828 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2830 Unexpect aCatch(SALOME_SalomeException);
2831 return _impl->HasModificationsToDiscard();
2834 //================================================================================
2836 * \brief Returns a random unique color
2838 //================================================================================
2840 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2842 const int MAX_ATTEMPTS = 100;
2844 double tolerance = 0.5;
2845 SALOMEDS::Color col;
2849 // generate random color
2850 double red = (double)rand() / RAND_MAX;
2851 double green = (double)rand() / RAND_MAX;
2852 double blue = (double)rand() / RAND_MAX;
2853 // check existence in the list of the existing colors
2854 bool matched = false;
2855 std::list<SALOMEDS::Color>::const_iterator it;
2856 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2857 SALOMEDS::Color color = *it;
2858 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2859 matched = tol < tolerance;
2861 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2862 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2870 //=============================================================================
2872 * Sets auto-color mode. If it is on, groups get unique random colors
2874 //=============================================================================
2876 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2878 Unexpect aCatch(SALOME_SalomeException);
2879 _impl->SetAutoColor(theAutoColor);
2881 TPythonDump pyDump; // not to dump group->SetColor() from below code
2882 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2884 std::list<SALOMEDS::Color> aReservedColors;
2885 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2886 for ( ; it != _mapGroups.end(); it++ ) {
2887 if ( CORBA::is_nil( it->second )) continue;
2888 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2889 it->second->SetColor( aColor );
2890 aReservedColors.push_back( aColor );
2894 //=============================================================================
2896 * Returns true if auto-color mode is on
2898 //=============================================================================
2900 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2902 Unexpect aCatch(SALOME_SalomeException);
2903 return _impl->GetAutoColor();
2906 //=============================================================================
2908 * Checks if there are groups with equal names
2910 //=============================================================================
2912 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2914 return _impl->HasDuplicatedGroupNamesMED();
2917 //================================================================================
2919 * \brief Care of a file before exporting mesh into it
2921 //================================================================================
2923 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2925 SMESH_File aFile( file );
2927 if (aFile.exists()) {
2928 // existing filesystem node
2929 if ( !aFile.isDirectory() ) {
2930 if ( aFile.openForWriting() ) {
2931 if ( overwrite && ! aFile.remove()) {
2932 msg << "Can't replace " << aFile.getName();
2935 msg << "Can't write into " << aFile.getName();
2938 msg << "Location " << aFile.getName() << " is not a file";
2942 // nonexisting file; check if it can be created
2943 if ( !aFile.openForWriting() ) {
2944 msg << "You cannot create the file "
2946 << ". Check the directory existance and access rights";
2954 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2958 //================================================================================
2960 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2961 * \param file - file name
2962 * \param overwrite - to erase the file or not
2963 * \retval string - mesh name
2965 //================================================================================
2967 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2968 CORBA::Boolean overwrite)
2971 PrepareForWriting(file, overwrite);
2972 string aMeshName = "Mesh";
2973 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2974 if ( !aStudy->_is_nil() ) {
2975 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2976 if ( !aMeshSO->_is_nil() ) {
2977 CORBA::String_var name = aMeshSO->GetName();
2979 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2980 if ( !aStudy->GetProperties()->IsLocked() )
2982 SALOMEDS::GenericAttribute_wrap anAttr;
2983 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2984 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2985 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2986 ASSERT(!aFileName->_is_nil());
2987 aFileName->SetValue(file);
2988 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2989 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2990 ASSERT(!aFileType->_is_nil());
2991 aFileType->SetValue("FICHIERMED");
2995 // Update Python script
2996 // set name of mesh before export
2997 TPythonDump() << _gen_i << ".SetName("
2998 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3000 // check names of groups
3006 //================================================================================
3008 * \brief Export to med file
3010 //================================================================================
3012 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3013 CORBA::Boolean auto_groups,
3014 SMESH::MED_VERSION theVersion,
3015 CORBA::Boolean overwrite,
3016 CORBA::Boolean autoDimension)
3017 throw(SALOME::SALOME_Exception)
3021 _preMeshInfo->FullLoadFromFile();
3023 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3024 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3026 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3027 << file << "', " << auto_groups << ", "
3028 << theVersion << ", " << overwrite << ", "
3029 << autoDimension << " )";
3031 SMESH_CATCH( SMESH::throwCorbaException );
3034 //================================================================================
3036 * \brief Export a mesh to a med file
3038 //================================================================================
3040 void SMESH_Mesh_i::ExportToMED (const char* file,
3041 CORBA::Boolean auto_groups,
3042 SMESH::MED_VERSION theVersion)
3043 throw(SALOME::SALOME_Exception)
3045 ExportToMEDX(file,auto_groups,theVersion,true);
3048 //================================================================================
3050 * \brief Export a mesh to a med file
3052 //================================================================================
3054 void SMESH_Mesh_i::ExportMED (const char* file,
3055 CORBA::Boolean auto_groups)
3056 throw(SALOME::SALOME_Exception)
3058 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3061 //================================================================================
3063 * \brief Export a mesh to a SAUV file
3065 //================================================================================
3067 void SMESH_Mesh_i::ExportSAUV (const char* file,
3068 CORBA::Boolean auto_groups)
3069 throw(SALOME::SALOME_Exception)
3071 Unexpect aCatch(SALOME_SalomeException);
3073 _preMeshInfo->FullLoadFromFile();
3075 string aMeshName = prepareMeshNameAndGroups(file, true);
3076 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3077 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3078 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3082 //================================================================================
3084 * \brief Export a mesh to a DAT file
3086 //================================================================================
3088 void SMESH_Mesh_i::ExportDAT (const char *file)
3089 throw(SALOME::SALOME_Exception)
3091 Unexpect aCatch(SALOME_SalomeException);
3093 _preMeshInfo->FullLoadFromFile();
3095 // Update Python script
3096 // check names of groups
3098 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3101 PrepareForWriting(file);
3102 _impl->ExportDAT(file);
3105 //================================================================================
3107 * \brief Export a mesh to an UNV file
3109 //================================================================================
3111 void SMESH_Mesh_i::ExportUNV (const char *file)
3112 throw(SALOME::SALOME_Exception)
3114 Unexpect aCatch(SALOME_SalomeException);
3116 _preMeshInfo->FullLoadFromFile();
3118 // Update Python script
3119 // check names of groups
3121 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3124 PrepareForWriting(file);
3125 _impl->ExportUNV(file);
3128 //================================================================================
3130 * \brief Export a mesh to an STL file
3132 //================================================================================
3134 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3135 throw(SALOME::SALOME_Exception)
3137 Unexpect aCatch(SALOME_SalomeException);
3139 _preMeshInfo->FullLoadFromFile();
3141 // Update Python script
3142 // check names of groups
3144 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3145 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3148 PrepareForWriting(file);
3149 _impl->ExportSTL(file, isascii);
3152 //================================================================================
3154 * \brief Export a part of mesh to a med file
3156 //================================================================================
3158 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3160 CORBA::Boolean auto_groups,
3161 SMESH::MED_VERSION version,
3162 CORBA::Boolean overwrite,
3163 CORBA::Boolean autoDimension,
3164 const GEOM::ListOfFields& fields,
3165 const char* geomAssocFields)
3166 throw (SALOME::SALOME_Exception)
3170 _preMeshInfo->FullLoadFromFile();
3173 bool have0dField = false;
3174 if ( fields.length() > 0 )
3176 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3177 if ( shapeToMesh->_is_nil() )
3178 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3180 for ( size_t i = 0; i < fields.length(); ++i )
3182 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3183 THROW_SALOME_CORBA_EXCEPTION
3184 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3185 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3186 if ( fieldShape->_is_nil() )
3187 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3188 if ( !fieldShape->IsSame( shapeToMesh ) )
3189 THROW_SALOME_CORBA_EXCEPTION
3190 ( "Field defined not on shape", SALOME::BAD_PARAM);
3191 if ( fields[i]->GetDimension() == 0 )
3194 if ( geomAssocFields )
3195 for ( int i = 0; geomAssocFields[i]; ++i )
3196 switch ( geomAssocFields[i] ) {
3197 case 'v':case 'e':case 'f':case 's': break;
3198 case 'V':case 'E':case 'F':case 'S': break;
3199 default: THROW_SALOME_CORBA_EXCEPTION
3200 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3204 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3208 string aMeshName = "Mesh";
3209 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3210 if ( CORBA::is_nil( meshPart ) ||
3211 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3213 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3214 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3215 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3216 meshDS = _impl->GetMeshDS();
3221 _preMeshInfo->FullLoadFromFile();
3223 PrepareForWriting(file, overwrite);
3225 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3226 if ( !aStudy->_is_nil() ) {
3227 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3228 if ( !SO->_is_nil() ) {
3229 CORBA::String_var name = SO->GetName();
3233 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3234 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3235 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3236 meshDS = tmpDSDeleter._obj = partDS;
3241 if ( _impl->HasShapeToMesh() )
3243 DriverMED_W_Field fieldWriter;
3244 fieldWriter.SetFile( file );
3245 fieldWriter.SetMeshName( aMeshName );
3246 fieldWriter.AddODOnVertices( have0dField );
3248 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3252 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3253 goList->length( fields.length() );
3254 for ( size_t i = 0; i < fields.length(); ++i )
3256 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3259 TPythonDump() << _this() << ".ExportPartToMED( "
3260 << meshPart << ", r'" << file << "', "
3261 << auto_groups << ", " << version << ", " << overwrite << ", "
3262 << autoDimension << ", " << goList
3263 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3265 SMESH_CATCH( SMESH::throwCorbaException );
3268 //================================================================================
3270 * Write GEOM fields to MED file
3272 //================================================================================
3274 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3275 SMESHDS_Mesh* meshDS,
3276 const GEOM::ListOfFields& fields,
3277 const char* geomAssocFields)
3279 #define METH "SMESH_Mesh_i::exportMEDFields() "
3281 if (( fields.length() < 1 ) &&
3282 ( !geomAssocFields || !geomAssocFields[0] ))
3285 std::vector< std::vector< double > > dblVals;
3286 std::vector< std::vector< int > > intVals;
3287 std::vector< int > subIdsByDim[ 4 ];
3288 const double noneDblValue = 0.;
3289 const double noneIntValue = 0;
3291 for ( size_t iF = 0; iF < fields.length(); ++iF )
3295 int dim = fields[ iF ]->GetDimension();
3296 SMDSAbs_ElementType elemType;
3297 TopAbs_ShapeEnum shapeType;
3299 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3300 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3301 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3302 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3304 continue; // skip fields on whole shape
3306 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3307 if ( dataType == GEOM::FDT_String )
3309 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3310 if ( stepIDs->length() < 1 )
3312 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3313 if ( comps->length() < 1 )
3315 CORBA::String_var name = fields[ iF ]->GetName();
3317 if ( !fieldWriter.Set( meshDS,
3321 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3324 for ( size_t iC = 0; iC < comps->length(); ++iC )
3325 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3327 dblVals.resize( comps->length() );
3328 intVals.resize( comps->length() );
3330 // find sub-shape IDs
3332 std::vector< int >& subIds = subIdsByDim[ dim ];
3333 if ( subIds.empty() )
3334 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3335 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3336 subIds.push_back( id );
3340 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3344 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3346 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3347 if ( step->_is_nil() )
3350 CORBA::Long stamp = step->GetStamp();
3351 CORBA::Long id = step->GetID();
3352 fieldWriter.SetDtIt( int( stamp ), int( id ));
3354 // fill dblVals or intVals
3355 for ( size_t iC = 0; iC < comps->length(); ++iC )
3356 if ( dataType == GEOM::FDT_Double )
3358 dblVals[ iC ].clear();
3359 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3363 intVals[ iC ].clear();
3364 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3368 case GEOM::FDT_Double:
3370 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3371 if ( dblStep->_is_nil() ) continue;
3372 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3373 if ( vv->length() != subIds.size() * comps->length() )
3374 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3375 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3376 for ( size_t iC = 0; iC < comps->length(); ++iC )
3377 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3382 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3383 if ( intStep->_is_nil() ) continue;
3384 GEOM::ListOfLong_var vv = intStep->GetValues();
3385 if ( vv->length() != subIds.size() * comps->length() )
3386 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3387 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3388 for ( size_t iC = 0; iC < comps->length(); ++iC )
3389 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3392 case GEOM::FDT_Bool:
3394 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3395 if ( boolStep->_is_nil() ) continue;
3396 GEOM::short_array_var vv = boolStep->GetValues();
3397 if ( vv->length() != subIds.size() * comps->length() )
3398 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3399 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3400 for ( size_t iC = 0; iC < comps->length(); ++iC )
3401 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3407 // pass values to fieldWriter
3408 elemIt = fieldWriter.GetOrderedElems();
3409 if ( dataType == GEOM::FDT_Double )
3410 while ( elemIt->more() )
3412 const SMDS_MeshElement* e = elemIt->next();
3413 const int shapeID = e->getshapeId();
3414 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3415 for ( size_t iC = 0; iC < comps->length(); ++iC )
3416 fieldWriter.AddValue( noneDblValue );
3418 for ( size_t iC = 0; iC < comps->length(); ++iC )
3419 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3422 while ( elemIt->more() )
3424 const SMDS_MeshElement* e = elemIt->next();
3425 const int shapeID = e->getshapeId();
3426 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3427 for ( size_t iC = 0; iC < comps->length(); ++iC )
3428 fieldWriter.AddValue( (double) noneIntValue );
3430 for ( size_t iC = 0; iC < comps->length(); ++iC )
3431 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3435 fieldWriter.Perform();
3436 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3437 if ( res && res->IsKO() )
3439 if ( res->myComment.empty() )
3440 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3442 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3448 if ( !geomAssocFields || !geomAssocFields[0] )
3451 // write geomAssocFields
3453 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3454 shapeDim[ TopAbs_COMPOUND ] = 3;
3455 shapeDim[ TopAbs_COMPSOLID ] = 3;
3456 shapeDim[ TopAbs_SOLID ] = 3;
3457 shapeDim[ TopAbs_SHELL ] = 2;
3458 shapeDim[ TopAbs_FACE ] = 2;
3459 shapeDim[ TopAbs_WIRE ] = 1;
3460 shapeDim[ TopAbs_EDGE ] = 1;
3461 shapeDim[ TopAbs_VERTEX ] = 0;
3462 shapeDim[ TopAbs_SHAPE ] = 3;
3464 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3466 std::vector< std::string > compNames;
3467 switch ( geomAssocFields[ iF ]) {
3469 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3470 compNames.push_back( "dim" );
3473 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3476 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3479 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3483 compNames.push_back( "id" );
3484 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3485 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3487 fieldWriter.SetDtIt( -1, -1 );
3489 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3493 if ( compNames.size() == 2 ) // _vertices_
3494 while ( elemIt->more() )
3496 const SMDS_MeshElement* e = elemIt->next();
3497 const int shapeID = e->getshapeId();
3500 fieldWriter.AddValue( (double) -1 );
3501 fieldWriter.AddValue( (double) -1 );
3505 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3506 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3507 fieldWriter.AddValue( (double) shapeID );
3511 while ( elemIt->more() )
3513 const SMDS_MeshElement* e = elemIt->next();
3514 const int shapeID = e->getshapeId();
3516 fieldWriter.AddValue( (double) -1 );
3518 fieldWriter.AddValue( (double) shapeID );
3522 fieldWriter.Perform();
3523 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3524 if ( res && res->IsKO() )
3526 if ( res->myComment.empty() )
3527 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3529 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3532 } // loop on geomAssocFields
3537 //================================================================================
3539 * \brief Export a part of mesh to a DAT file
3541 //================================================================================
3543 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3545 throw (SALOME::SALOME_Exception)
3547 Unexpect aCatch(SALOME_SalomeException);
3549 _preMeshInfo->FullLoadFromFile();
3551 PrepareForWriting(file);
3553 SMESH_MeshPartDS partDS( meshPart );
3554 _impl->ExportDAT(file,&partDS);
3556 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3557 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3559 //================================================================================
3561 * \brief Export a part of mesh to an UNV file
3563 //================================================================================
3565 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3567 throw (SALOME::SALOME_Exception)
3569 Unexpect aCatch(SALOME_SalomeException);
3571 _preMeshInfo->FullLoadFromFile();
3573 PrepareForWriting(file);
3575 SMESH_MeshPartDS partDS( meshPart );
3576 _impl->ExportUNV(file, &partDS);
3578 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3579 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3581 //================================================================================
3583 * \brief Export a part of mesh to an STL file
3585 //================================================================================
3587 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3589 ::CORBA::Boolean isascii)
3590 throw (SALOME::SALOME_Exception)
3592 Unexpect aCatch(SALOME_SalomeException);
3594 _preMeshInfo->FullLoadFromFile();
3596 PrepareForWriting(file);
3598 SMESH_MeshPartDS partDS( meshPart );
3599 _impl->ExportSTL(file, isascii, &partDS);
3601 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3602 << meshPart<< ", r'" << file << "', " << isascii << ")";
3605 //================================================================================
3607 * \brief Export a part of mesh to an STL file
3609 //================================================================================
3611 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3613 CORBA::Boolean overwrite)
3614 throw (SALOME::SALOME_Exception)
3617 Unexpect aCatch(SALOME_SalomeException);
3619 _preMeshInfo->FullLoadFromFile();
3621 PrepareForWriting(file,overwrite);
3623 std::string meshName("");
3624 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3625 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3626 if ( !so->_is_nil() )
3628 CORBA::String_var name = so->GetName();
3629 meshName = name.in();
3631 SMESH_MeshPartDS partDS( meshPart );
3632 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3634 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3635 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3637 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3641 //================================================================================
3643 * \brief Export a part of mesh to a GMF file
3645 //================================================================================
3647 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3649 bool withRequiredGroups)
3650 throw (SALOME::SALOME_Exception)
3652 Unexpect aCatch(SALOME_SalomeException);
3654 _preMeshInfo->FullLoadFromFile();
3656 PrepareForWriting(file,/*overwrite=*/true);
3658 SMESH_MeshPartDS partDS( meshPart );
3659 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3661 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3662 << meshPart<< ", r'"
3664 << withRequiredGroups << ")";
3667 //=============================================================================
3669 * Return computation progress [0.,1]
3671 //=============================================================================
3673 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3677 return _impl->GetComputeProgress();
3679 SMESH_CATCH( SMESH::doNothing );
3683 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3685 Unexpect aCatch(SALOME_SalomeException);
3687 return _preMeshInfo->NbNodes();
3689 return _impl->NbNodes();
3692 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3694 Unexpect aCatch(SALOME_SalomeException);
3696 return _preMeshInfo->NbElements();
3698 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3701 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3703 Unexpect aCatch(SALOME_SalomeException);
3705 return _preMeshInfo->Nb0DElements();
3707 return _impl->Nb0DElements();
3710 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3712 Unexpect aCatch(SALOME_SalomeException);
3714 return _preMeshInfo->NbBalls();
3716 return _impl->NbBalls();
3719 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->NbEdges();
3725 return _impl->NbEdges();
3728 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3729 throw(SALOME::SALOME_Exception)
3731 Unexpect aCatch(SALOME_SalomeException);
3733 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3735 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3738 //=============================================================================
3740 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3742 Unexpect aCatch(SALOME_SalomeException);
3744 return _preMeshInfo->NbFaces();
3746 return _impl->NbFaces();
3749 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3751 Unexpect aCatch(SALOME_SalomeException);
3753 return _preMeshInfo->NbTriangles();
3755 return _impl->NbTriangles();
3758 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3760 Unexpect aCatch(SALOME_SalomeException);
3762 return _preMeshInfo->NbBiQuadTriangles();
3764 return _impl->NbBiQuadTriangles();
3767 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3769 Unexpect aCatch(SALOME_SalomeException);
3771 return _preMeshInfo->NbQuadrangles();
3773 return _impl->NbQuadrangles();
3776 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3778 Unexpect aCatch(SALOME_SalomeException);
3780 return _preMeshInfo->NbBiQuadQuadrangles();
3782 return _impl->NbBiQuadQuadrangles();
3785 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3787 Unexpect aCatch(SALOME_SalomeException);
3789 return _preMeshInfo->NbPolygons();
3791 return _impl->NbPolygons();
3794 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3796 Unexpect aCatch(SALOME_SalomeException);
3798 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3800 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3803 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3804 throw(SALOME::SALOME_Exception)
3806 Unexpect aCatch(SALOME_SalomeException);
3808 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3810 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3813 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3814 throw(SALOME::SALOME_Exception)
3816 Unexpect aCatch(SALOME_SalomeException);
3818 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3820 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3823 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3824 throw(SALOME::SALOME_Exception)
3826 Unexpect aCatch(SALOME_SalomeException);
3828 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3830 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3833 //=============================================================================
3835 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3837 Unexpect aCatch(SALOME_SalomeException);
3839 return _preMeshInfo->NbVolumes();
3841 return _impl->NbVolumes();
3844 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3846 Unexpect aCatch(SALOME_SalomeException);
3848 return _preMeshInfo->NbTetras();
3850 return _impl->NbTetras();
3853 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3855 Unexpect aCatch(SALOME_SalomeException);
3857 return _preMeshInfo->NbHexas();
3859 return _impl->NbHexas();
3862 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3864 Unexpect aCatch(SALOME_SalomeException);
3866 return _preMeshInfo->NbTriQuadHexas();
3868 return _impl->NbTriQuadraticHexas();
3871 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3873 Unexpect aCatch(SALOME_SalomeException);
3875 return _preMeshInfo->NbPyramids();
3877 return _impl->NbPyramids();
3880 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3882 Unexpect aCatch(SALOME_SalomeException);
3884 return _preMeshInfo->NbPrisms();
3886 return _impl->NbPrisms();
3889 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3891 Unexpect aCatch(SALOME_SalomeException);
3893 return _preMeshInfo->NbHexPrisms();
3895 return _impl->NbHexagonalPrisms();
3898 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3900 Unexpect aCatch(SALOME_SalomeException);
3902 return _preMeshInfo->NbPolyhedrons();
3904 return _impl->NbPolyhedrons();
3907 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3908 throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3914 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3917 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3918 throw(SALOME::SALOME_Exception)
3920 Unexpect aCatch(SALOME_SalomeException);
3922 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3924 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3927 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3928 throw(SALOME::SALOME_Exception)
3930 Unexpect aCatch(SALOME_SalomeException);
3932 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3934 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3937 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3938 throw(SALOME::SALOME_Exception)
3940 Unexpect aCatch(SALOME_SalomeException);
3942 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3944 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3947 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3948 throw(SALOME::SALOME_Exception)
3950 Unexpect aCatch(SALOME_SalomeException);
3952 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3954 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3957 //=============================================================================
3959 * Returns nb of published sub-meshes
3961 //=============================================================================
3963 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3965 Unexpect aCatch(SALOME_SalomeException);
3966 return _mapSubMesh_i.size();
3969 //=============================================================================
3971 * Dumps mesh into a string
3973 //=============================================================================
3975 char* SMESH_Mesh_i::Dump()
3979 return CORBA::string_dup( os.str().c_str() );
3982 //=============================================================================
3984 * Method of SMESH_IDSource interface
3986 //=============================================================================
3988 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3990 return GetElementsId();
3993 //=============================================================================
3995 * Returns ids of all elements
3997 //=============================================================================
3999 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4000 throw (SALOME::SALOME_Exception)
4002 Unexpect aCatch(SALOME_SalomeException);
4004 _preMeshInfo->FullLoadFromFile();
4006 SMESH::long_array_var aResult = new SMESH::long_array();
4007 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4009 if ( aSMESHDS_Mesh == NULL )
4010 return aResult._retn();
4012 long nbElements = NbElements();
4013 aResult->length( nbElements );
4014 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4015 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4016 aResult[i] = anIt->next()->GetID();
4018 return aResult._retn();
4022 //=============================================================================
4024 * Returns ids of all elements of given type
4026 //=============================================================================
4028 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4029 throw (SALOME::SALOME_Exception)
4031 Unexpect aCatch(SALOME_SalomeException);
4033 _preMeshInfo->FullLoadFromFile();
4035 SMESH::long_array_var aResult = new SMESH::long_array();
4036 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4038 if ( aSMESHDS_Mesh == NULL )
4039 return aResult._retn();
4041 long nbElements = NbElements();
4043 // No sense in returning ids of elements along with ids of nodes:
4044 // when theElemType == SMESH::ALL, return node ids only if
4045 // there are no elements
4046 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4047 return GetNodesId();
4049 aResult->length( nbElements );
4053 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4054 while ( i < nbElements && anIt->more() )
4055 aResult[i++] = anIt->next()->GetID();
4057 aResult->length( i );
4059 return aResult._retn();
4062 //=============================================================================
4064 * Returns ids of all nodes
4066 //=============================================================================
4068 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4069 throw (SALOME::SALOME_Exception)
4071 Unexpect aCatch(SALOME_SalomeException);
4073 _preMeshInfo->FullLoadFromFile();
4075 SMESH::long_array_var aResult = new SMESH::long_array();
4076 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4078 if ( aSMESHDS_Mesh == NULL )
4079 return aResult._retn();
4081 long nbNodes = NbNodes();
4082 aResult->length( nbNodes );
4083 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4084 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4085 aResult[i] = anIt->next()->GetID();
4087 return aResult._retn();
4090 //=============================================================================
4094 //=============================================================================
4096 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4097 throw (SALOME::SALOME_Exception)
4099 SMESH::ElementType type = SMESH::ALL;
4103 _preMeshInfo->FullLoadFromFile();
4105 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4107 SMESH_CATCH( SMESH::throwCorbaException );
4112 //=============================================================================
4116 //=============================================================================
4118 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4119 throw (SALOME::SALOME_Exception)
4122 _preMeshInfo->FullLoadFromFile();
4124 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4126 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4128 return ( SMESH::EntityType ) e->GetEntityType();
4131 //=============================================================================
4135 //=============================================================================
4137 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4138 throw (SALOME::SALOME_Exception)
4141 _preMeshInfo->FullLoadFromFile();
4143 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4145 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4147 return ( SMESH::GeometryType ) e->GetGeomType();
4150 //=============================================================================
4152 * Returns ID of elements for given submesh
4154 //=============================================================================
4155 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4156 throw (SALOME::SALOME_Exception)
4158 SMESH::long_array_var aResult = new SMESH::long_array();
4162 _preMeshInfo->FullLoadFromFile();
4164 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4165 if(!SM) return aResult._retn();
4167 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4168 if(!SDSM) return aResult._retn();
4170 aResult->length(SDSM->NbElements());
4172 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4174 while ( eIt->more() ) {
4175 aResult[i++] = eIt->next()->GetID();
4178 SMESH_CATCH( SMESH::throwCorbaException );
4180 return aResult._retn();
4183 //=============================================================================
4185 * Returns ID of nodes for given submesh
4186 * If param all==true - returns all nodes, else -
4187 * returns only nodes on shapes.
4189 //=============================================================================
4191 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4193 throw (SALOME::SALOME_Exception)
4195 SMESH::long_array_var aResult = new SMESH::long_array();
4199 _preMeshInfo->FullLoadFromFile();
4201 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4202 if(!SM) return aResult._retn();
4204 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4205 if(!SDSM) return aResult._retn();
4208 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4209 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4210 while ( nIt->more() ) {
4211 const SMDS_MeshNode* elem = nIt->next();
4212 theElems.insert( elem->GetID() );
4215 else { // all nodes of submesh elements
4216 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4217 while ( eIt->more() ) {
4218 const SMDS_MeshElement* anElem = eIt->next();
4219 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4220 while ( nIt->more() ) {
4221 const SMDS_MeshElement* elem = nIt->next();
4222 theElems.insert( elem->GetID() );
4227 aResult->length(theElems.size());
4228 set<int>::iterator itElem;
4230 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4231 aResult[i++] = *itElem;
4233 SMESH_CATCH( SMESH::throwCorbaException );
4235 return aResult._retn();
4238 //=============================================================================
4240 * Returns type of elements for given submesh
4242 //=============================================================================
4244 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4245 throw (SALOME::SALOME_Exception)
4247 SMESH::ElementType type = SMESH::ALL;
4251 _preMeshInfo->FullLoadFromFile();
4253 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4254 if(!SM) return SMESH::ALL;
4256 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4257 if(!SDSM) return SMESH::ALL;
4259 if(SDSM->NbElements()==0)
4260 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4262 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4263 const SMDS_MeshElement* anElem = eIt->next();
4265 type = ( SMESH::ElementType ) anElem->GetType();
4267 SMESH_CATCH( SMESH::throwCorbaException );
4273 //=============================================================================
4275 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4277 //=============================================================================
4279 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4282 _preMeshInfo->FullLoadFromFile();
4284 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4285 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4290 //=============================================================================
4292 * Get XYZ coordinates of node as list of double
4293 * If there is not node for given ID - returns empty list
4295 //=============================================================================
4297 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4300 _preMeshInfo->FullLoadFromFile();
4302 SMESH::double_array_var aResult = new SMESH::double_array();
4303 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4304 if ( aSMESHDS_Mesh == NULL )
4305 return aResult._retn();
4308 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4310 return aResult._retn();
4314 aResult[0] = aNode->X();
4315 aResult[1] = aNode->Y();
4316 aResult[2] = aNode->Z();
4317 return aResult._retn();
4321 //=============================================================================
4323 * For given node returns list of IDs of inverse elements
4324 * If there is not node for given ID - returns empty list
4326 //=============================================================================
4328 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4331 _preMeshInfo->FullLoadFromFile();
4333 SMESH::long_array_var aResult = new SMESH::long_array();
4334 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4335 if ( aSMESHDS_Mesh == NULL )
4336 return aResult._retn();
4339 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4341 return aResult._retn();
4343 // find inverse elements
4344 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4345 aResult->length( aNode->NbInverseElements() );
4346 for( int i = 0; eIt->more(); ++i )
4348 const SMDS_MeshElement* elem = eIt->next();
4349 aResult[ i ] = elem->GetID();
4351 return aResult._retn();
4354 //=============================================================================
4356 * \brief Return position of a node on shape
4358 //=============================================================================
4360 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4363 _preMeshInfo->FullLoadFromFile();
4365 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4366 aNodePosition->shapeID = 0;
4367 aNodePosition->shapeType = GEOM::SHAPE;
4369 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4370 if ( !mesh ) return aNodePosition;
4372 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4374 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4376 aNodePosition->shapeID = aNode->getshapeId();
4377 switch ( pos->GetTypeOfPosition() ) {
4379 aNodePosition->shapeType = GEOM::EDGE;
4380 aNodePosition->params.length(1);
4381 aNodePosition->params[0] =
4382 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4385 aNodePosition->shapeType = GEOM::FACE;
4386 aNodePosition->params.length(2);
4387 aNodePosition->params[0] =
4388 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4389 aNodePosition->params[1] =
4390 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4392 case SMDS_TOP_VERTEX:
4393 aNodePosition->shapeType = GEOM::VERTEX;
4395 case SMDS_TOP_3DSPACE:
4396 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4397 aNodePosition->shapeType = GEOM::SOLID;
4398 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4399 aNodePosition->shapeType = GEOM::SHELL;
4405 return aNodePosition;
4408 //=============================================================================
4410 * \brief Return position of an element on shape
4412 //=============================================================================
4414 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4417 _preMeshInfo->FullLoadFromFile();
4419 SMESH::ElementPosition anElementPosition;
4420 anElementPosition.shapeID = 0;
4421 anElementPosition.shapeType = GEOM::SHAPE;
4423 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4424 if ( !mesh ) return anElementPosition;
4426 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4428 anElementPosition.shapeID = anElem->getshapeId();
4429 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4430 if ( !aSp.IsNull() ) {
4431 switch ( aSp.ShapeType() ) {
4433 anElementPosition.shapeType = GEOM::EDGE;
4436 anElementPosition.shapeType = GEOM::FACE;
4439 anElementPosition.shapeType = GEOM::VERTEX;
4442 anElementPosition.shapeType = GEOM::SOLID;
4445 anElementPosition.shapeType = GEOM::SHELL;
4451 return anElementPosition;
4454 //=============================================================================
4456 * If given element is node returns IDs of shape from position
4457 * If there is not node for given ID - returns -1
4459 //=============================================================================
4461 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4464 _preMeshInfo->FullLoadFromFile();
4466 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4467 if ( aSMESHDS_Mesh == NULL )
4471 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4473 return aNode->getshapeId();
4480 //=============================================================================
4482 * For given element returns ID of result shape after
4483 * ::FindShape() from SMESH_MeshEditor
4484 * If there is not element for given ID - returns -1
4486 //=============================================================================
4488 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4491 _preMeshInfo->FullLoadFromFile();
4493 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4494 if ( aSMESHDS_Mesh == NULL )
4497 // try to find element
4498 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4502 ::SMESH_MeshEditor aMeshEditor(_impl);
4503 int index = aMeshEditor.FindShape( elem );
4511 //=============================================================================
4513 * Returns number of nodes for given element
4514 * If there is not element for given ID - returns -1
4516 //=============================================================================
4518 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4521 _preMeshInfo->FullLoadFromFile();
4523 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4524 if ( aSMESHDS_Mesh == NULL ) return -1;
4525 // try to find element
4526 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4527 if(!elem) return -1;
4528 return elem->NbNodes();
4532 //=============================================================================
4534 * Returns ID of node by given index for given element
4535 * If there is not element for given ID - returns -1
4536 * If there is not node for given index - returns -2
4538 //=============================================================================
4540 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4543 _preMeshInfo->FullLoadFromFile();
4545 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4546 if ( aSMESHDS_Mesh == NULL ) return -1;
4547 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4548 if(!elem) return -1;
4549 if( index>=elem->NbNodes() || index<0 ) return -1;
4550 return elem->GetNode(index)->GetID();
4553 //=============================================================================
4555 * Returns IDs of nodes of given element
4557 //=============================================================================
4559 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4562 _preMeshInfo->FullLoadFromFile();
4564 SMESH::long_array_var aResult = new SMESH::long_array();
4565 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4567 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4569 aResult->length( elem->NbNodes() );
4570 for ( int i = 0; i < elem->NbNodes(); ++i )
4571 aResult[ i ] = elem->GetNode( i )->GetID();
4574 return aResult._retn();
4577 //=============================================================================
4579 * Returns true if given node is medium node
4580 * in given quadratic element
4582 //=============================================================================
4584 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4587 _preMeshInfo->FullLoadFromFile();
4589 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4590 if ( aSMESHDS_Mesh == NULL ) return false;
4592 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4593 if(!aNode) return false;
4594 // try to find element
4595 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4596 if(!elem) return false;
4598 return elem->IsMediumNode(aNode);
4602 //=============================================================================
4604 * Returns true if given node is medium node
4605 * in one of quadratic elements
4607 //=============================================================================
4609 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4610 SMESH::ElementType theElemType)
4613 _preMeshInfo->FullLoadFromFile();
4615 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4616 if ( aSMESHDS_Mesh == NULL ) return false;
4619 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4620 if(!aNode) return false;
4622 SMESH_MesherHelper aHelper( *(_impl) );
4624 SMDSAbs_ElementType aType;
4625 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4626 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4627 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4628 else aType = SMDSAbs_All;
4630 return aHelper.IsMedium(aNode,aType);
4634 //=============================================================================
4636 * Returns number of edges for given element
4638 //=============================================================================
4640 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4643 _preMeshInfo->FullLoadFromFile();
4645 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4646 if ( aSMESHDS_Mesh == NULL ) return -1;
4647 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4648 if(!elem) return -1;
4649 return elem->NbEdges();
4653 //=============================================================================
4655 * Returns number of faces for given element
4657 //=============================================================================
4659 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4662 _preMeshInfo->FullLoadFromFile();
4664 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4665 if ( aSMESHDS_Mesh == NULL ) return -1;
4666 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4667 if(!elem) return -1;
4668 return elem->NbFaces();
4671 //=======================================================================
4672 //function : GetElemFaceNodes
4673 //purpose : Returns nodes of given face (counted from zero) for given element.
4674 //=======================================================================
4676 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4677 CORBA::Short faceIndex)
4680 _preMeshInfo->FullLoadFromFile();
4682 SMESH::long_array_var aResult = new SMESH::long_array();
4683 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4685 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4687 SMDS_VolumeTool vtool( elem );
4688 if ( faceIndex < vtool.NbFaces() )
4690 aResult->length( vtool.NbFaceNodes( faceIndex ));
4691 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4692 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4693 aResult[ i ] = nn[ i ]->GetID();
4697 return aResult._retn();
4700 //=======================================================================
4701 //function : GetElemFaceNodes
4702 //purpose : Returns three components of normal of given mesh face.
4703 //=======================================================================
4705 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4706 CORBA::Boolean normalized)
4709 _preMeshInfo->FullLoadFromFile();
4711 SMESH::double_array_var aResult = new SMESH::double_array();
4713 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4716 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4718 aResult->length( 3 );
4719 aResult[ 0 ] = normal.X();
4720 aResult[ 1 ] = normal.Y();
4721 aResult[ 2 ] = normal.Z();
4724 return aResult._retn();
4727 //=======================================================================
4728 //function : FindElementByNodes
4729 //purpose : Returns an element based on all given nodes.
4730 //=======================================================================
4732 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4735 _preMeshInfo->FullLoadFromFile();
4737 CORBA::Long elemID(0);
4738 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4740 vector< const SMDS_MeshNode * > nn( nodes.length() );
4741 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4742 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4745 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4746 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4747 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4748 _impl->NbVolumes( ORDER_QUADRATIC )))
4749 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4751 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4756 //=============================================================================
4758 * Returns true if given element is polygon
4760 //=============================================================================
4762 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4765 _preMeshInfo->FullLoadFromFile();
4767 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4768 if ( aSMESHDS_Mesh == NULL ) return false;
4769 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4770 if(!elem) return false;
4771 return elem->IsPoly();
4775 //=============================================================================
4777 * Returns true if given element is quadratic
4779 //=============================================================================
4781 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4784 _preMeshInfo->FullLoadFromFile();
4786 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4787 if ( aSMESHDS_Mesh == NULL ) return false;
4788 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4789 if(!elem) return false;
4790 return elem->IsQuadratic();
4793 //=============================================================================
4795 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4797 //=============================================================================
4799 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4802 _preMeshInfo->FullLoadFromFile();
4804 if ( const SMDS_BallElement* ball =
4805 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4806 return ball->GetDiameter();
4811 //=============================================================================
4813 * Returns bary center for given element
4815 //=============================================================================
4817 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4820 _preMeshInfo->FullLoadFromFile();
4822 SMESH::double_array_var aResult = new SMESH::double_array();
4823 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4824 if ( aSMESHDS_Mesh == NULL )
4825 return aResult._retn();
4827 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4829 return aResult._retn();
4831 if(elem->GetType()==SMDSAbs_Volume) {
4832 SMDS_VolumeTool aTool;
4833 if(aTool.Set(elem)) {
4835 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4840 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4842 double x=0., y=0., z=0.;
4843 for(; anIt->more(); ) {
4845 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4859 return aResult._retn();
4862 //================================================================================
4864 * \brief Create a group of elements preventing computation of a sub-shape
4866 //================================================================================
4868 SMESH::ListOfGroups*
4869 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4870 const char* theGroupName )
4871 throw ( SALOME::SALOME_Exception )
4873 Unexpect aCatch(SALOME_SalomeException);
4875 if ( !theGroupName || strlen( theGroupName) == 0 )
4876 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4878 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4879 ::SMESH_MeshEditor::ElemFeatures elemType;
4881 // submesh by subshape id
4882 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4883 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4886 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4887 if ( error && !error->myBadElements.empty())
4889 // sort bad elements by type
4890 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4891 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4892 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4893 for ( ; elemIt != elemEnd; ++elemIt )
4895 const SMDS_MeshElement* elem = *elemIt;
4896 if ( !elem ) continue;
4898 if ( elem->GetID() < 1 )
4900 // elem is a temporary element, make a real element
4901 vector< const SMDS_MeshNode* > nodes;
4902 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4903 while ( nIt->more() && elem )
4905 nodes.push_back( nIt->next() );
4906 if ( nodes.back()->GetID() < 1 )
4907 elem = 0; // a temporary element on temporary nodes
4911 ::SMESH_MeshEditor editor( _impl );
4912 elem = editor.AddElement( nodes, elemType.Init( elem ));
4916 elemsByType[ elem->GetType() ].push_back( elem );
4919 // how many groups to create?
4921 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4922 nbTypes += int( !elemsByType[ i ].empty() );
4923 groups->length( nbTypes );
4926 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4928 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4929 if ( elems.empty() ) continue;
4931 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4932 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4934 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4935 SMESH::SMESH_Mesh_var mesh = _this();
4936 SALOMEDS::SObject_wrap aSO =
4937 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4938 GEOM::GEOM_Object::_nil(), theGroupName);
4940 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4941 if ( !grp_i ) continue;
4943 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4944 for ( size_t iE = 0; iE < elems.size(); ++iE )
4945 grpDS->SMDSGroup().Add( elems[ iE ]);
4950 return groups._retn();
4953 //=============================================================================
4955 * Create and publish group servants if any groups were imported or created anyhow
4957 //=============================================================================
4959 void SMESH_Mesh_i::CreateGroupServants()
4961 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4962 SMESH::SMESH_Mesh_var aMesh = _this();
4965 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4966 while ( groupIt->more() )
4968 ::SMESH_Group* group = groupIt->next();
4969 int anId = group->GetGroupDS()->GetID();
4971 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4972 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4974 addedIDs.insert( anId );
4976 SMESH_GroupBase_i* aGroupImpl;
4978 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4979 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4981 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4982 shape = groupOnGeom->GetShape();
4985 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4988 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4989 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4990 aGroupImpl->Register();
4992 // register CORBA object for persistence
4993 int nextId = _gen_i->RegisterObject( groupVar );
4994 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4995 else { nextId = 0; } // avoid "unused variable" warning in release mode
4997 // publishing the groups in the study
4998 if ( !aStudy->_is_nil() ) {
4999 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5000 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5003 if ( !addedIDs.empty() )
5006 set<int>::iterator id = addedIDs.begin();
5007 for ( ; id != addedIDs.end(); ++id )
5009 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5010 int i = std::distance( _mapGroups.begin(), it );
5011 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5016 //=============================================================================
5018 * \brief Return groups cantained in _mapGroups by their IDs
5020 //=============================================================================
5022 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5024 int nbGroups = groupIDs.size();
5025 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5026 aList->length( nbGroups );
5028 list<int>::const_iterator ids = groupIDs.begin();
5029 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5031 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5032 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5033 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5035 aList->length( nbGroups );
5036 return aList._retn();
5039 //=============================================================================
5041 * \brief Return information about imported file
5043 //=============================================================================
5045 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5047 SMESH::MedFileInfo_var res( _medFileInfo );
5048 if ( !res.operator->() ) {
5049 res = new SMESH::MedFileInfo;
5051 res->fileSize = res->major = res->minor = res->release = -1;
5056 //=============================================================================
5058 * \brief Pass names of mesh groups from study to mesh DS
5060 //=============================================================================
5062 void SMESH_Mesh_i::checkGroupNames()
5064 int nbGrp = NbGroups();
5068 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5069 if ( aStudy->_is_nil() )
5070 return; // nothing to do
5072 SMESH::ListOfGroups* grpList = 0;
5073 // avoid dump of "GetGroups"
5075 // store python dump into a local variable inside local scope
5076 SMESH::TPythonDump pDump; // do not delete this line of code
5077 grpList = GetGroups();
5080 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5081 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5084 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5085 if ( aGrpSO->_is_nil() )
5087 // correct name of the mesh group if necessary
5088 const char* guiName = aGrpSO->GetName();
5089 if ( strcmp(guiName, aGrp->GetName()) )
5090 aGrp->SetName( guiName );
5094 //=============================================================================
5096 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5098 //=============================================================================
5099 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5101 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5105 //=============================================================================
5107 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5109 //=============================================================================
5111 char* SMESH_Mesh_i::GetParameters()
5113 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5116 //=============================================================================
5118 * \brief Returns list of notebook variables used for last Mesh operation
5120 //=============================================================================
5121 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5123 SMESH::string_array_var aResult = new SMESH::string_array();
5124 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5126 CORBA::String_var aParameters = GetParameters();
5127 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5128 if ( !aStudy->_is_nil()) {
5129 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5130 if ( aSections->length() > 0 ) {
5131 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5132 aResult->length( aVars.length() );
5133 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5134 aResult[i] = CORBA::string_dup( aVars[i] );
5138 return aResult._retn();
5141 //=======================================================================
5142 //function : GetTypes
5143 //purpose : Returns types of elements it contains
5144 //=======================================================================
5146 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5149 return _preMeshInfo->GetTypes();
5151 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5155 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5156 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5157 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5158 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5159 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5160 if (_impl->NbNodes() &&
5161 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5162 types->length( nbTypes );
5164 return types._retn();
5167 //=======================================================================
5168 //function : GetMesh
5169 //purpose : Returns self
5170 //=======================================================================
5172 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5174 return SMESH::SMESH_Mesh::_duplicate( _this() );
5177 //=======================================================================
5178 //function : IsMeshInfoCorrect
5179 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5180 // * happen if mesh data is not yet fully loaded from the file of study.
5181 //=======================================================================
5183 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5185 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5188 //=============================================================================
5190 * \brief Returns number of mesh elements per each \a EntityType
5192 //=============================================================================
5194 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5197 return _preMeshInfo->GetMeshInfo();
5199 SMESH::long_array_var aRes = new SMESH::long_array();
5200 aRes->length(SMESH::Entity_Last);
5201 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5203 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5205 return aRes._retn();
5206 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5207 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5208 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5209 return aRes._retn();
5212 //=============================================================================
5214 * \brief Returns number of mesh elements per each \a ElementType
5216 //=============================================================================
5218 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5220 SMESH::long_array_var aRes = new SMESH::long_array();
5221 aRes->length(SMESH::NB_ELEMENT_TYPES);
5222 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5225 const SMDS_MeshInfo* meshInfo = 0;
5227 meshInfo = _preMeshInfo;
5228 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5229 meshInfo = & meshDS->GetMeshInfo();
5232 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5233 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5235 return aRes._retn();
5238 //=============================================================================
5240 * Collect statistic of mesh elements given by iterator
5242 //=============================================================================
5244 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5245 SMESH::long_array& theInfo)
5247 if (!theItr) return;
5248 while (theItr->more())
5249 theInfo[ theItr->next()->GetEntityType() ]++;
5251 //=============================================================================
5253 * Returns mesh unstructed grid information.
5255 //=============================================================================
5257 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5259 SALOMEDS::TMPFile_var SeqFile;
5260 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5261 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5263 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5264 aWriter->WriteToOutputStringOn();
5265 aWriter->SetInputData(aGrid);
5266 aWriter->SetFileTypeToBinary();
5268 char* str = aWriter->GetOutputString();
5269 int size = aWriter->GetOutputStringLength();
5271 //Allocate octect buffer of required size
5272 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5273 //Copy ostrstream content to the octect buffer
5274 memcpy(OctetBuf, str, size);
5275 //Create and return TMPFile
5276 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5280 return SeqFile._retn();
5283 //=============================================================================
5284 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5285 * SMESH::ElementType type) */
5287 using namespace SMESH::Controls;
5288 //-----------------------------------------------------------------------------
5289 struct PredicateIterator : public SMDS_ElemIterator
5291 SMDS_ElemIteratorPtr _elemIter;
5292 PredicatePtr _predicate;
5293 const SMDS_MeshElement* _elem;
5295 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5296 PredicatePtr predicate):
5297 _elemIter(iterator), _predicate(predicate)
5305 virtual const SMDS_MeshElement* next()
5307 const SMDS_MeshElement* res = _elem;
5309 while ( _elemIter->more() && !_elem )
5311 _elem = _elemIter->next();
5312 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5319 //-----------------------------------------------------------------------------
5320 struct IDSourceIterator : public SMDS_ElemIterator
5322 const CORBA::Long* _idPtr;
5323 const CORBA::Long* _idEndPtr;
5324 SMESH::long_array_var _idArray;
5325 const SMDS_Mesh* _mesh;
5326 const SMDSAbs_ElementType _type;
5327 const SMDS_MeshElement* _elem;
5329 IDSourceIterator( const SMDS_Mesh* mesh,
5330 const CORBA::Long* ids,
5332 SMDSAbs_ElementType type):
5333 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5335 if ( _idPtr && nbIds && _mesh )
5338 IDSourceIterator( const SMDS_Mesh* mesh,
5339 SMESH::long_array* idArray,
5340 SMDSAbs_ElementType type):
5341 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5343 if ( idArray && _mesh )
5345 _idPtr = &_idArray[0];
5346 _idEndPtr = _idPtr + _idArray->length();
5354 virtual const SMDS_MeshElement* next()
5356 const SMDS_MeshElement* res = _elem;
5358 while ( _idPtr < _idEndPtr && !_elem )
5360 if ( _type == SMDSAbs_Node )
5362 _elem = _mesh->FindNode( *_idPtr++ );
5364 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5365 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5373 //-----------------------------------------------------------------------------
5375 struct NodeOfElemIterator : public SMDS_ElemIterator
5377 TColStd_MapOfInteger _checkedNodeIDs;
5378 SMDS_ElemIteratorPtr _elemIter;
5379 SMDS_ElemIteratorPtr _nodeIter;
5380 const SMDS_MeshElement* _node;
5382 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5384 if ( _elemIter && _elemIter->more() )
5386 _nodeIter = _elemIter->next()->nodesIterator();
5394 virtual const SMDS_MeshElement* next()
5396 const SMDS_MeshElement* res = _node;
5398 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5400 if ( _nodeIter->more() )
5402 _node = _nodeIter->next();
5403 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5408 _nodeIter = _elemIter->next()->nodesIterator();
5416 //=============================================================================
5418 * Return iterator on elements of given type in given object
5420 //=============================================================================
5422 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5423 SMESH::ElementType theType)
5425 SMDS_ElemIteratorPtr elemIt;
5426 bool typeOK = ( theType == SMESH::ALL );
5427 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5429 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5430 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5431 if ( !mesh_i ) return elemIt;
5432 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5434 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5436 elemIt = meshDS->elementsIterator( elemType );
5439 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5441 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5444 elemIt = sm->GetElements();
5445 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5447 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5448 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5452 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5454 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5455 if ( groupDS && ( elemType == groupDS->GetType() ||
5456 elemType == SMDSAbs_Node ||
5457 elemType == SMDSAbs_All ))
5459 elemIt = groupDS->GetElements();
5460 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5463 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5465 if ( filter_i->GetElementType() == theType ||
5466 elemType == SMDSAbs_Node ||
5467 elemType == SMDSAbs_All)
5469 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5470 if ( pred_i && pred_i->GetPredicate() )
5472 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5473 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5474 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5475 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5481 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5482 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5483 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5485 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5488 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5489 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5493 SMESH::long_array_var ids = theObject->GetIDs();
5494 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5496 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5499 if ( elemIt && elemIt->more() && !typeOK )
5501 if ( elemType == SMDSAbs_Node )
5503 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5507 elemIt = SMDS_ElemIteratorPtr();
5513 //=============================================================================
5514 namespace // Finding concurrent hypotheses
5515 //=============================================================================
5519 * \brief mapping of mesh dimension into shape type
5521 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5523 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5525 case 0: aType = TopAbs_VERTEX; break;
5526 case 1: aType = TopAbs_EDGE; break;
5527 case 2: aType = TopAbs_FACE; break;
5529 default:aType = TopAbs_SOLID; break;
5534 //-----------------------------------------------------------------------------
5536 * \brief Internal structure used to find concurent submeshes
5538 * It represents a pair < submesh, concurent dimension >, where
5539 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5540 * with another submesh. In other words, it is dimension of a hypothesis assigned
5547 int _dim; //!< a dimension the algo can build (concurrent dimension)
5548 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5549 TopTools_MapOfShape _shapeMap;
5550 SMESH_subMesh* _subMesh;
5551 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5553 //-----------------------------------------------------------------------------
5554 // Return the algorithm
5555 const SMESH_Algo* GetAlgo() const
5556 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5558 //-----------------------------------------------------------------------------
5560 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5562 const TopoDS_Shape& theShape)
5564 _subMesh = (SMESH_subMesh*)theSubMesh;
5565 SetShape( theDim, theShape );
5568 //-----------------------------------------------------------------------------
5570 void SetShape(const int theDim,
5571 const TopoDS_Shape& theShape)
5574 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5575 if (_dim >= _ownDim)
5576 _shapeMap.Add( theShape );
5578 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5579 for( ; anExp.More(); anExp.Next() )
5580 _shapeMap.Add( anExp.Current() );
5584 //-----------------------------------------------------------------------------
5585 //! Check sharing of sub-shapes
5586 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5587 const TopTools_MapOfShape& theToFind,
5588 const TopAbs_ShapeEnum theType)
5590 bool isShared = false;
5591 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5592 for (; !isShared && anItr.More(); anItr.Next() )
5594 const TopoDS_Shape aSubSh = anItr.Key();
5595 // check for case when concurrent dimensions are same
5596 isShared = theToFind.Contains( aSubSh );
5597 // check for sub-shape with concurrent dimension
5598 TopExp_Explorer anExp( aSubSh, theType );
5599 for ( ; !isShared && anExp.More(); anExp.Next() )
5600 isShared = theToFind.Contains( anExp.Current() );
5605 //-----------------------------------------------------------------------------
5606 //! check algorithms
5607 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5608 const SMESHDS_Hypothesis* theA2)
5610 if ( !theA1 || !theA2 ||
5611 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5612 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5613 return false; // one of the hypothesis is not algorithm
5614 // check algorithm names (should be equal)
5615 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5619 //-----------------------------------------------------------------------------
5620 //! Check if sub-shape hypotheses are concurrent
5621 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5623 if ( _subMesh == theOther->_subMesh )
5624 return false; // same sub-shape - should not be
5626 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5627 // any of the two submeshes is not on COMPOUND shape )
5628 // -> no concurrency
5629 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5630 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5631 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5632 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5633 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5636 // bool checkSubShape = ( _dim >= theOther->_dim )
5637 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5638 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5639 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5640 if ( !checkSubShape )
5643 // check algorithms to be same
5644 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5645 return true; // different algorithms -> concurrency !
5647 // check hypothesises for concurrence (skip first as algorithm)
5649 // pointers should be same, because it is referened from mesh hypothesis partition
5650 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5651 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5652 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5653 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5655 // the submeshes are concurrent if their algorithms has different parameters
5656 return nbSame != (int)theOther->_hypotheses.size() - 1;
5659 // Return true if algorithm of this SMESH_DimHyp is used if no
5660 // sub-mesh order is imposed by the user
5661 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5663 // NeedDiscreteBoundary() algo has a higher priority
5664 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5665 theOther->GetAlgo()->NeedDiscreteBoundary() )
5666 return !this->GetAlgo()->NeedDiscreteBoundary();
5668 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5671 }; // end of SMESH_DimHyp
5672 //-----------------------------------------------------------------------------
5674 typedef list<const SMESH_DimHyp*> TDimHypList;
5676 //-----------------------------------------------------------------------------
5678 void addDimHypInstance(const int theDim,
5679 const TopoDS_Shape& theShape,
5680 const SMESH_Algo* theAlgo,
5681 const SMESH_subMesh* theSubMesh,
5682 const list <const SMESHDS_Hypothesis*>& theHypList,
5683 TDimHypList* theDimHypListArr )
5685 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5686 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5687 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5688 dimHyp->_hypotheses.push_front(theAlgo);
5689 listOfdimHyp.push_back( dimHyp );
5692 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5693 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5694 theHypList.begin(), theHypList.end() );
5697 //-----------------------------------------------------------------------------
5698 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5699 TDimHypList& theListOfConcurr)
5701 if ( theListOfConcurr.empty() )
5703 theListOfConcurr.push_back( theDimHyp );
5707 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5708 while ( hypIt != theListOfConcurr.end() &&
5709 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5711 theListOfConcurr.insert( hypIt, theDimHyp );
5715 //-----------------------------------------------------------------------------
5716 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5717 const TDimHypList& theListOfDimHyp,
5718 TDimHypList& theListOfConcurrHyp,
5719 set<int>& theSetOfConcurrId )
5721 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5722 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5724 const SMESH_DimHyp* curDimHyp = *rIt;
5725 if ( curDimHyp == theDimHyp )
5726 break; // meet own dimHyp pointer in same dimension
5728 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5729 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5731 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5736 //-----------------------------------------------------------------------------
5737 void unionLists(TListOfInt& theListOfId,
5738 TListOfListOfInt& theListOfListOfId,
5741 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5742 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5744 continue; //skip already treated lists
5745 // check if other list has any same submesh object
5746 TListOfInt& otherListOfId = *it;
5747 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5748 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5751 // union two lists (from source into target)
5752 TListOfInt::iterator it2 = otherListOfId.begin();
5753 for ( ; it2 != otherListOfId.end(); it2++ ) {
5754 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5755 theListOfId.push_back(*it2);
5757 // clear source list
5758 otherListOfId.clear();
5761 //-----------------------------------------------------------------------------
5763 //! free memory allocated for dimension-hypothesis objects
5764 void removeDimHyps( TDimHypList* theArrOfList )
5766 for (int i = 0; i < 4; i++ ) {
5767 TDimHypList& listOfdimHyp = theArrOfList[i];
5768 TDimHypList::const_iterator it = listOfdimHyp.begin();
5769 for ( ; it != listOfdimHyp.end(); it++ )
5774 //-----------------------------------------------------------------------------
5776 * \brief find common submeshes with given submesh
5777 * \param theSubMeshList list of already collected submesh to check
5778 * \param theSubMesh given submesh to intersect with other
5779 * \param theCommonSubMeshes collected common submeshes
5781 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5782 const SMESH_subMesh* theSubMesh,
5783 set<const SMESH_subMesh*>& theCommon )
5787 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5788 for ( ; it != theSubMeshList.end(); it++ )
5789 theSubMesh->FindIntersection( *it, theCommon );
5790 theSubMeshList.push_back( theSubMesh );
5791 //theCommon.insert( theSubMesh );
5794 //-----------------------------------------------------------------------------
5795 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5797 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5798 for ( ; listsIt != smLists.end(); ++listsIt )
5800 const TListOfInt& smIDs = *listsIt;
5801 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5809 //=============================================================================
5811 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5813 //=============================================================================
5815 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5817 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5818 if ( isSubMeshInList( submeshID, anOrder ))
5821 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5822 return isSubMeshInList( submeshID, allConurrent );
5825 //=============================================================================
5827 * \brief Return submesh objects list in meshing order
5829 //=============================================================================
5831 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5833 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5835 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5837 return aResult._retn();
5839 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5840 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5841 anOrder.splice( anOrder.end(), allConurrent );
5844 TListOfListOfInt::iterator listIt = anOrder.begin();
5845 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5846 unionLists( *listIt, anOrder, listIndx + 1 );
5848 // convert submesh ids into interface instances
5849 // and dump command into python
5850 convertMeshOrder( anOrder, aResult, false );
5852 return aResult._retn();
5855 //=============================================================================
5857 * \brief Finds concurrent sub-meshes
5859 //=============================================================================
5861 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5863 TListOfListOfInt anOrder;
5864 ::SMESH_Mesh& mesh = GetImpl();
5866 // collect submeshes and detect concurrent algorithms and hypothesises
5867 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5869 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5870 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5871 ::SMESH_subMesh* sm = (*i_sm).second;
5873 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5875 // list of assigned hypothesises
5876 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5877 // Find out dimensions where the submesh can be concurrent.
5878 // We define the dimensions by algo of each of hypotheses in hypList
5879 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5880 for( ; hypIt != hypList.end(); hypIt++ ) {
5881 SMESH_Algo* anAlgo = 0;
5882 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5883 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5884 // hyp it-self is algo
5885 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5887 // try to find algorithm with help of sub-shapes
5888 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5889 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5890 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5893 continue; // no algorithm assigned to a current submesh
5895 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5896 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5898 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5899 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5900 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5902 } // end iterations on submesh
5904 // iterate on created dimension-hypotheses and check for concurrents
5905 for ( int i = 0; i < 4; i++ ) {
5906 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5907 // check for concurrents in own and other dimensions (step-by-step)
5908 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5909 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5910 const SMESH_DimHyp* dimHyp = *dhIt;
5911 TDimHypList listOfConcurr;
5912 set<int> setOfConcurrIds;
5913 // looking for concurrents and collect into own list
5914 for ( int j = i; j < 4; j++ )
5915 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5916 // check if any concurrents found
5917 if ( listOfConcurr.size() > 0 ) {
5918 // add own submesh to list of concurrent
5919 addInOrderOfPriority( dimHyp, listOfConcurr );
5920 list<int> listOfConcurrIds;
5921 TDimHypList::iterator hypIt = listOfConcurr.begin();
5922 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5923 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5924 anOrder.push_back( listOfConcurrIds );
5929 removeDimHyps(dimHypListArr);
5931 // now, minimise the number of concurrent groups
5932 // Here we assume that lists of submeshes can have same submesh
5933 // in case of multi-dimension algorithms, as result
5934 // list with common submesh has to be united into one list
5936 TListOfListOfInt::iterator listIt = anOrder.begin();
5937 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5938 unionLists( *listIt, anOrder, listIndx + 1 );
5944 //=============================================================================
5946 * \brief Set submesh object order
5947 * \param theSubMeshArray submesh array order
5949 //=============================================================================
5951 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5954 _preMeshInfo->ForgetOrLoad();
5957 ::SMESH_Mesh& mesh = GetImpl();
5959 TPythonDump aPythonDump; // prevent dump of called methods
5960 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5962 TListOfListOfInt subMeshOrder;
5963 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5965 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5966 TListOfInt subMeshIds;
5968 aPythonDump << ", ";
5969 aPythonDump << "[ ";
5970 // Collect subMeshes which should be clear
5971 // do it list-by-list, because modification of submesh order
5972 // take effect between concurrent submeshes only
5973 set<const SMESH_subMesh*> subMeshToClear;
5974 list<const SMESH_subMesh*> subMeshList;
5975 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5977 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5979 aPythonDump << ", ";
5980 aPythonDump << subMesh;
5981 subMeshIds.push_back( subMesh->GetId() );
5982 // detect common parts of submeshes
5983 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5984 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5986 aPythonDump << " ]";
5987 subMeshOrder.push_back( subMeshIds );
5989 // clear collected submeshes
5990 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5991 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5992 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5993 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5995 aPythonDump << " ])";
5997 mesh.SetMeshOrder( subMeshOrder );
6003 //=============================================================================
6005 * \brief Convert submesh ids into submesh interfaces
6007 //=============================================================================
6009 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6010 SMESH::submesh_array_array& theResOrder,
6011 const bool theIsDump)
6013 int nbSet = theIdsOrder.size();
6014 TPythonDump aPythonDump; // prevent dump of called methods
6016 aPythonDump << "[ ";
6017 theResOrder.length(nbSet);
6018 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6020 for( ; it != theIdsOrder.end(); it++ ) {
6021 // translate submesh identificators into submesh objects
6022 // takeing into account real number of concurrent lists
6023 const TListOfInt& aSubOrder = (*it);
6024 if (!aSubOrder.size())
6027 aPythonDump << "[ ";
6028 // convert shape indeces into interfaces
6029 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6030 aResSubSet->length(aSubOrder.size());
6031 TListOfInt::const_iterator subIt = aSubOrder.begin();
6033 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6034 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6036 SMESH::SMESH_subMesh_var subMesh =
6037 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6040 aPythonDump << ", ";
6041 aPythonDump << subMesh;
6043 aResSubSet[ j++ ] = subMesh;
6046 aPythonDump << " ]";
6048 theResOrder[ listIndx++ ] = aResSubSet;
6050 // correct number of lists
6051 theResOrder.length( listIndx );
6054 // finilise python dump
6055 aPythonDump << " ]";
6056 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6060 //================================================================================
6062 // Implementation of SMESH_MeshPartDS
6064 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6065 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6067 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6068 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6071 _meshDS = mesh_i->GetImpl().GetMeshDS();
6073 SetPersistentId( _meshDS->GetPersistentId() );
6075 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6077 // <meshPart> is the whole mesh
6078 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6080 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6081 myGroupSet = _meshDS->GetGroups();
6086 SMESH::long_array_var anIDs = meshPart->GetIDs();
6087 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6088 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6090 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6091 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6092 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6097 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6098 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6099 if ( _elements[ e->GetType() ].insert( e ).second )
6102 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6103 while ( nIt->more() )
6105 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6106 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6113 ShapeToMesh( _meshDS->ShapeToMesh() );
6115 _meshDS = 0; // to enforce iteration on _elements and _nodes
6118 // -------------------------------------------------------------------------------------
6119 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6120 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6123 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6124 for ( ; partIt != meshPart.end(); ++partIt )
6125 if ( const SMDS_MeshElement * e = *partIt )
6126 if ( _elements[ e->GetType() ].insert( e ).second )
6129 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6130 while ( nIt->more() )
6132 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6133 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6139 // -------------------------------------------------------------------------------------
6140 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6142 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6144 TElemID elem( IDelem );
6145 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6146 if ( !_elements[ iType ].empty() )
6148 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6149 if ( it != _elements[ iType ].end() )
6154 // -------------------------------------------------------------------------------------
6155 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6157 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6159 typedef SMDS_SetIterator
6160 <const SMDS_MeshElement*,
6161 TIDSortedElemSet::const_iterator,
6162 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6163 SMDS_MeshElement::GeomFilter
6166 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6168 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6169 _elements[type].end(),
6170 SMDS_MeshElement::GeomFilter( geomType )));
6172 // -------------------------------------------------------------------------------------
6173 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6175 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6177 typedef SMDS_SetIterator
6178 <const SMDS_MeshElement*,
6179 TIDSortedElemSet::const_iterator,
6180 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6181 SMDS_MeshElement::EntityFilter
6184 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6186 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6187 _elements[type].end(),
6188 SMDS_MeshElement::EntityFilter( entity )));
6190 // -------------------------------------------------------------------------------------
6191 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6193 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6194 if ( type == SMDSAbs_All && !_meshDS )
6196 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6198 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6199 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6201 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6203 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6204 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6206 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6207 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6209 // -------------------------------------------------------------------------------------
6210 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6211 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6213 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6214 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6215 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6217 // -------------------------------------------------------------------------------------
6218 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6219 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6220 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6221 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6222 #undef _GET_ITER_DEFINE
6224 // END Implementation of SMESH_MeshPartDS
6226 //================================================================================