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);
302 _impl->GetMeshDS()->Modified();
304 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
307 //================================================================================
309 * \brief Remove all nodes and elements for indicated shape
311 //================================================================================
313 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
314 throw (SALOME::SALOME_Exception)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Imports mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
393 throw ( SALOME::SALOME_Exception )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
411 major = minor = release = -1;
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Imports mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
432 throw ( SALOME::SALOME_Exception )
434 Unexpect aCatch(SALOME_SalomeException);
437 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
439 catch( SALOME_Exception& S_ex ) {
440 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
446 CreateGroupServants();
448 return ConvertDriverMEDReadStatus(status);
451 //================================================================================
453 * \brief Return string representation of a MED file version comprising nbDigits
455 //================================================================================
457 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
459 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
461 return CORBA::string_dup( ver.c_str() );
464 //=============================================================================
468 * Imports mesh data from MED file
470 //=============================================================================
472 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
473 throw ( SALOME::SALOME_Exception )
477 // Read mesh with name = <theMeshName> into SMESH_Mesh
478 _impl->UNVToMesh( theFileName );
480 CreateGroupServants();
482 SMESH_CATCH( SMESH::throwCorbaException );
487 //=============================================================================
491 * Imports mesh data from STL file
493 //=============================================================================
494 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
495 throw ( SALOME::SALOME_Exception )
499 // Read mesh with name = <theMeshName> into SMESH_Mesh
500 _impl->STLToMesh( theFileName );
502 SMESH_CATCH( SMESH::throwCorbaException );
507 //================================================================================
509 * \brief Function used in SMESH_CATCH by ImportGMFFile()
511 //================================================================================
515 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
517 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
521 //================================================================================
523 * \brief Imports data from a GMF file and returns an error description
525 //================================================================================
527 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
528 bool theMakeRequiredGroups )
529 throw (SALOME::SALOME_Exception)
531 SMESH_ComputeErrorPtr error;
534 #define SMESH_CAUGHT error =
537 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
539 SMESH_CATCH( exceptionToComputeError );
543 CreateGroupServants();
545 return ConvertComputeError( error );
548 //=============================================================================
552 //=============================================================================
554 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
556 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
557 (SMESH_Hypothesis::Hypothesis_Status theStatus)
560 RETURNCASE( HYP_OK );
561 RETURNCASE( HYP_MISSING );
562 RETURNCASE( HYP_CONCURENT );
563 RETURNCASE( HYP_BAD_PARAMETER );
564 RETURNCASE( HYP_HIDDEN_ALGO );
565 RETURNCASE( HYP_HIDING_ALGO );
566 RETURNCASE( HYP_UNKNOWN_FATAL );
567 RETURNCASE( HYP_INCOMPATIBLE );
568 RETURNCASE( HYP_NOTCONFORM );
569 RETURNCASE( HYP_ALREADY_EXIST );
570 RETURNCASE( HYP_BAD_DIM );
571 RETURNCASE( HYP_BAD_SUBSHAPE );
572 RETURNCASE( HYP_BAD_GEOMETRY );
573 RETURNCASE( HYP_NEED_SHAPE );
574 RETURNCASE( HYP_INCOMPAT_HYPS );
577 return SMESH::HYP_UNKNOWN_FATAL;
580 //=============================================================================
584 * calls internal addHypothesis() and then adds a reference to <anHyp> under
585 * the SObject actually having a reference to <aSubShape>.
586 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
588 //=============================================================================
590 SMESH::Hypothesis_Status
591 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
592 SMESH::SMESH_Hypothesis_ptr anHyp,
593 CORBA::String_out anErrorText)
594 throw(SALOME::SALOME_Exception)
596 Unexpect aCatch(SALOME_SalomeException);
598 _preMeshInfo->ForgetOrLoad();
601 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
602 anErrorText = error.c_str();
604 SMESH::SMESH_Mesh_var mesh( _this() );
605 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
607 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
608 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
610 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
612 // Update Python script
613 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
614 << aSubShape << ", " << anHyp << " )";
616 return ConvertHypothesisStatus(status);
619 //=============================================================================
623 //=============================================================================
625 SMESH_Hypothesis::Hypothesis_Status
626 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
627 SMESH::SMESH_Hypothesis_ptr anHyp,
628 std::string* anErrorText)
630 if(MYDEBUG) MESSAGE("addHypothesis");
632 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
633 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
635 if (CORBA::is_nil( anHyp ))
636 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
638 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
641 TopoDS_Shape myLocSubShape;
642 //use PseudoShape in case if mesh has no shape
644 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
646 myLocSubShape = _impl->GetShapeToMesh();
648 const int hypId = anHyp->GetId();
650 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
651 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
653 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
655 // assure there is a corresponding submesh
656 if ( !_impl->IsMainShape( myLocSubShape )) {
657 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
658 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
659 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
662 else if ( anErrorText )
664 *anErrorText = error;
667 catch(SALOME_Exception & S_ex)
669 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
674 //=============================================================================
678 //=============================================================================
680 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
681 SMESH::SMESH_Hypothesis_ptr anHyp)
682 throw(SALOME::SALOME_Exception)
684 Unexpect aCatch(SALOME_SalomeException);
686 _preMeshInfo->ForgetOrLoad();
688 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
689 SMESH::SMESH_Mesh_var mesh = _this();
691 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
693 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
694 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
696 // Update Python script
697 if(_impl->HasShapeToMesh())
698 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
699 << aSubShape << ", " << anHyp << " )";
701 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
704 return ConvertHypothesisStatus(status);
707 //=============================================================================
711 //=============================================================================
713 SMESH_Hypothesis::Hypothesis_Status
714 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
715 SMESH::SMESH_Hypothesis_ptr anHyp)
717 if(MYDEBUG) MESSAGE("removeHypothesis()");
719 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
720 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
722 if (CORBA::is_nil( anHyp ))
723 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
725 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
728 TopoDS_Shape myLocSubShape;
729 //use PseudoShape in case if mesh has no shape
730 if( _impl->HasShapeToMesh() )
731 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
733 myLocSubShape = _impl->GetShapeToMesh();
735 const int hypId = anHyp->GetId();
736 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
737 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
739 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
743 catch(SALOME_Exception & S_ex)
745 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
750 //=============================================================================
754 //=============================================================================
756 SMESH::ListOfHypothesis *
757 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
758 throw(SALOME::SALOME_Exception)
760 Unexpect aCatch(SALOME_SalomeException);
761 if (MYDEBUG) MESSAGE("GetHypothesisList");
762 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
763 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
765 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
768 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
769 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
770 myLocSubShape = _impl->GetShapeToMesh();
771 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
772 int i = 0, n = aLocalList.size();
775 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
776 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
777 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
779 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
780 if ( id_hypptr != _mapHypo.end() )
781 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
785 catch(SALOME_Exception & S_ex) {
786 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
789 return aList._retn();
792 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
794 Unexpect aCatch(SALOME_SalomeException);
795 if (MYDEBUG) MESSAGE("GetSubMeshes");
797 SMESH::submesh_array_var aList = new SMESH::submesh_array();
800 TPythonDump aPythonDump;
801 if ( !_mapSubMeshIor.empty() )
805 aList->length( _mapSubMeshIor.size() );
807 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
808 for ( ; it != _mapSubMeshIor.end(); it++ ) {
809 if ( CORBA::is_nil( it->second )) continue;
810 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
812 if (i > 1) aPythonDump << ", ";
813 aPythonDump << it->second;
817 catch(SALOME_Exception & S_ex) {
818 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
821 // Update Python script
822 if ( !_mapSubMeshIor.empty() )
823 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
825 return aList._retn();
828 //=============================================================================
832 //=============================================================================
834 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
835 const char* theName )
836 throw(SALOME::SALOME_Exception)
838 Unexpect aCatch(SALOME_SalomeException);
839 if (CORBA::is_nil(aSubShape))
840 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
842 SMESH::SMESH_subMesh_var subMesh;
843 SMESH::SMESH_Mesh_var aMesh = _this();
845 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
847 //Get or Create the SMESH_subMesh object implementation
849 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
851 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
853 TopoDS_Iterator it( myLocSubShape );
855 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
857 subMesh = getSubMesh( subMeshId );
859 // create a new subMesh object servant if there is none for the shape
860 if ( subMesh->_is_nil() )
861 subMesh = createSubMesh( aSubShape );
862 if ( _gen_i->CanPublishInStudy( subMesh ))
864 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
865 SALOMEDS::SObject_wrap aSO =
866 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
867 if ( !aSO->_is_nil()) {
868 // Update Python script
869 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
870 << aSubShape << ", '" << theName << "' )";
874 catch(SALOME_Exception & S_ex) {
875 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
877 return subMesh._retn();
880 //=============================================================================
884 //=============================================================================
886 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
887 throw (SALOME::SALOME_Exception)
891 if ( theSubMesh->_is_nil() )
894 GEOM::GEOM_Object_var aSubShape;
895 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
896 if ( !aStudy->_is_nil() ) {
897 // Remove submesh's SObject
898 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
899 if ( !anSO->_is_nil() ) {
900 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
901 SALOMEDS::SObject_wrap anObj, aRef;
902 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
903 anObj->ReferencedObject( aRef.inout() ))
905 CORBA::Object_var obj = aRef->GetObject();
906 aSubShape = GEOM::GEOM_Object::_narrow( obj );
908 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
909 // aSubShape = theSubMesh->GetSubShape();
911 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
912 builder->RemoveObjectWithChildren( anSO );
914 // Update Python script
915 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
919 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
921 _preMeshInfo->ForgetOrLoad();
923 SMESH_CATCH( SMESH::throwCorbaException );
926 //=============================================================================
930 //=============================================================================
932 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
933 const char* theName )
934 throw(SALOME::SALOME_Exception)
936 Unexpect aCatch(SALOME_SalomeException);
938 _preMeshInfo->FullLoadFromFile();
940 SMESH::SMESH_Group_var aNewGroup =
941 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
943 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
945 SMESH::SMESH_Mesh_var mesh = _this();
946 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
947 SALOMEDS::SObject_wrap aSO =
948 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
949 if ( !aSO->_is_nil())
950 // Update Python script
951 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
952 << theElemType << ", '" << theName << "' )";
954 return aNewGroup._retn();
957 //=============================================================================
961 //=============================================================================
962 SMESH::SMESH_GroupOnGeom_ptr
963 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
965 GEOM::GEOM_Object_ptr theGeomObj)
966 throw(SALOME::SALOME_Exception)
968 Unexpect aCatch(SALOME_SalomeException);
970 _preMeshInfo->FullLoadFromFile();
972 SMESH::SMESH_GroupOnGeom_var aNewGroup;
974 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
975 if ( !aShape.IsNull() )
978 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
980 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
982 SMESH::SMESH_Mesh_var mesh = _this();
983 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
984 SALOMEDS::SObject_wrap aSO =
985 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
986 if ( !aSO->_is_nil())
987 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
988 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
992 return aNewGroup._retn();
995 //================================================================================
997 * \brief Creates a group whose contents is defined by filter
998 * \param theElemType - group type
999 * \param theName - group name
1000 * \param theFilter - the filter
1001 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1003 //================================================================================
1005 SMESH::SMESH_GroupOnFilter_ptr
1006 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1007 const char* theName,
1008 SMESH::Filter_ptr theFilter )
1009 throw (SALOME::SALOME_Exception)
1011 Unexpect aCatch(SALOME_SalomeException);
1013 _preMeshInfo->FullLoadFromFile();
1015 if ( CORBA::is_nil( theFilter ))
1016 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1018 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1020 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1022 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1023 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1026 if ( !aNewGroup->_is_nil() )
1027 aNewGroup->SetFilter( theFilter );
1029 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1031 SMESH::SMESH_Mesh_var mesh = _this();
1032 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1033 SALOMEDS::SObject_wrap aSO =
1034 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1036 if ( !aSO->_is_nil())
1037 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1038 << theElemType << ", '" << theName << "', " << theFilter << " )";
1040 return aNewGroup._retn();
1043 //=============================================================================
1047 //=============================================================================
1049 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1050 throw (SALOME::SALOME_Exception)
1052 if ( theGroup->_is_nil() )
1057 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1061 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1062 if ( !aStudy->_is_nil() )
1064 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1065 if ( !aGroupSO->_is_nil() )
1067 // Update Python script
1068 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1070 // Remove group's SObject
1071 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1072 builder->RemoveObjectWithChildren( aGroupSO );
1075 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1077 // Remove the group from SMESH data structures
1078 removeGroup( aGroup->GetLocalID() );
1080 SMESH_CATCH( SMESH::throwCorbaException );
1083 //=============================================================================
1085 * Remove group with its contents
1087 //=============================================================================
1089 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1090 throw (SALOME::SALOME_Exception)
1094 _preMeshInfo->FullLoadFromFile();
1096 if ( theGroup->_is_nil() )
1099 vector<int> nodeIds; // to remove nodes becoming free
1100 if ( !theGroup->IsEmpty() )
1102 CORBA::Long elemID = theGroup->GetID( 1 );
1103 int nbElemNodes = GetElemNbNodes( elemID );
1104 if ( nbElemNodes > 0 )
1105 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1109 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1110 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1111 while ( elemIt->more() )
1113 const SMDS_MeshElement* e = elemIt->next();
1115 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1116 while ( nIt->more() )
1117 nodeIds.push_back( nIt->next()->GetID() );
1119 _impl->GetMeshDS()->RemoveElement( e );
1122 // Remove free nodes
1123 if ( theGroup->GetType() != SMESH::NODE )
1124 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1125 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1126 if ( n->NbInverseElements() == 0 )
1127 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1129 TPythonDump pyDump; // Supress dump from RemoveGroup()
1131 // Update Python script (theGroup must be alive for this)
1132 pyDump << SMESH::SMESH_Mesh_var(_this())
1133 << ".RemoveGroupWithContents( " << theGroup << " )";
1136 RemoveGroup( theGroup );
1138 SMESH_CATCH( SMESH::throwCorbaException );
1141 //================================================================================
1143 * \brief Get the list of groups existing in the mesh
1144 * \retval SMESH::ListOfGroups * - list of groups
1146 //================================================================================
1148 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1150 Unexpect aCatch(SALOME_SalomeException);
1151 if (MYDEBUG) MESSAGE("GetGroups");
1153 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1156 TPythonDump aPythonDump;
1157 if ( !_mapGroups.empty() )
1159 aPythonDump << "[ ";
1161 aList->length( _mapGroups.size() );
1163 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1164 for ( ; it != _mapGroups.end(); it++ ) {
1165 if ( CORBA::is_nil( it->second )) continue;
1166 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1168 if (i > 1) aPythonDump << ", ";
1169 aPythonDump << it->second;
1173 catch(SALOME_Exception & S_ex) {
1174 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1176 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1178 return aList._retn();
1181 //=============================================================================
1183 * Get number of groups existing in the mesh
1185 //=============================================================================
1187 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1189 Unexpect aCatch(SALOME_SalomeException);
1190 return _mapGroups.size();
1193 //=============================================================================
1195 * New group including all mesh elements present in initial groups is created.
1197 //=============================================================================
1199 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1200 SMESH::SMESH_GroupBase_ptr theGroup2,
1201 const char* theName )
1202 throw (SALOME::SALOME_Exception)
1204 SMESH::SMESH_Group_var aResGrp;
1208 _preMeshInfo->FullLoadFromFile();
1210 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1211 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1213 if ( theGroup1->GetType() != theGroup2->GetType() )
1214 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1219 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1220 if ( aResGrp->_is_nil() )
1221 return SMESH::SMESH_Group::_nil();
1223 aResGrp->AddFrom( theGroup1 );
1224 aResGrp->AddFrom( theGroup2 );
1226 // Update Python script
1227 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1228 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1230 SMESH_CATCH( SMESH::throwCorbaException );
1232 return aResGrp._retn();
1235 //=============================================================================
1237 * \brief New group including all mesh elements present in initial groups is created.
1238 * \param theGroups list of groups
1239 * \param theName name of group to be created
1240 * \return pointer to the new group
1242 //=============================================================================
1244 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1245 const char* theName )
1246 throw (SALOME::SALOME_Exception)
1248 SMESH::SMESH_Group_var aResGrp;
1251 _preMeshInfo->FullLoadFromFile();
1254 return SMESH::SMESH_Group::_nil();
1259 SMESH::ElementType aType = SMESH::ALL;
1260 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1262 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1263 if ( CORBA::is_nil( aGrp ) )
1265 if ( aType == SMESH::ALL )
1266 aType = aGrp->GetType();
1267 else if ( aType != aGrp->GetType() )
1268 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1271 if ( aType == SMESH::ALL )
1272 return SMESH::SMESH_Group::_nil();
1277 aResGrp = CreateGroup( aType, theName );
1278 if ( aResGrp->_is_nil() )
1279 return SMESH::SMESH_Group::_nil();
1281 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1282 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1284 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1285 if ( !CORBA::is_nil( aGrp ) )
1287 aResGrp->AddFrom( aGrp );
1288 if ( g > 0 ) pyDump << ", ";
1292 pyDump << " ], '" << theName << "' )";
1294 SMESH_CATCH( SMESH::throwCorbaException );
1296 return aResGrp._retn();
1299 //=============================================================================
1301 * New group is created. All mesh elements that are
1302 * present in both initial groups are added to the new one.
1304 //=============================================================================
1306 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1307 SMESH::SMESH_GroupBase_ptr theGroup2,
1308 const char* theName )
1309 throw (SALOME::SALOME_Exception)
1311 SMESH::SMESH_Group_var aResGrp;
1316 _preMeshInfo->FullLoadFromFile();
1318 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1319 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1321 if ( theGroup1->GetType() != theGroup2->GetType() )
1322 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1326 // Create Intersection
1327 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1328 if ( aResGrp->_is_nil() )
1329 return aResGrp._retn();
1331 SMESHDS_GroupBase* groupDS1 = 0;
1332 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1333 groupDS1 = grp_i->GetGroupDS();
1335 SMESHDS_GroupBase* groupDS2 = 0;
1336 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1337 groupDS2 = grp_i->GetGroupDS();
1339 SMESHDS_Group* resGroupDS = 0;
1340 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1341 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1343 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1345 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1346 while ( elemIt1->more() )
1348 const SMDS_MeshElement* e = elemIt1->next();
1349 if ( groupDS2->Contains( e ))
1350 resGroupDS->SMDSGroup().Add( e );
1353 // Update Python script
1354 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1355 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1357 SMESH_CATCH( SMESH::throwCorbaException );
1359 return aResGrp._retn();
1362 //=============================================================================
1364 \brief Intersect list of groups. New group is created. All mesh elements that
1365 are present in all initial groups simultaneously are added to the new one.
1366 \param theGroups list of groups
1367 \param theName name of group to be created
1368 \return pointer on the group
1370 //=============================================================================
1371 SMESH::SMESH_Group_ptr
1372 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1373 const char* theName )
1374 throw (SALOME::SALOME_Exception)
1376 SMESH::SMESH_Group_var aResGrp;
1381 _preMeshInfo->FullLoadFromFile();
1384 return SMESH::SMESH_Group::_nil();
1386 // check types and get SMESHDS_GroupBase's
1387 SMESH::ElementType aType = SMESH::ALL;
1388 vector< SMESHDS_GroupBase* > groupVec;
1389 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1391 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1392 if ( CORBA::is_nil( aGrp ) )
1394 if ( aType == SMESH::ALL )
1395 aType = aGrp->GetType();
1396 else if ( aType != aGrp->GetType() )
1397 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1400 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1401 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1403 if ( grpDS->IsEmpty() )
1408 groupVec.push_back( grpDS );
1411 if ( aType == SMESH::ALL ) // all groups are nil
1412 return SMESH::SMESH_Group::_nil();
1417 aResGrp = CreateGroup( aType, theName );
1419 SMESHDS_Group* resGroupDS = 0;
1420 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1421 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1422 if ( !resGroupDS || groupVec.empty() )
1423 return aResGrp._retn();
1426 size_t i, nb = groupVec.size();
1427 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1428 while ( elemIt1->more() )
1430 const SMDS_MeshElement* e = elemIt1->next();
1432 for ( i = 1; ( i < nb && inAll ); ++i )
1433 inAll = groupVec[i]->Contains( e );
1436 resGroupDS->SMDSGroup().Add( e );
1439 // Update Python script
1440 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1441 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1443 SMESH_CATCH( SMESH::throwCorbaException );
1445 return aResGrp._retn();
1448 //=============================================================================
1450 * New group is created. All mesh elements that are present in
1451 * a main group but is not present in a tool group are added to the new one
1453 //=============================================================================
1455 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1456 SMESH::SMESH_GroupBase_ptr theGroup2,
1457 const char* theName )
1458 throw (SALOME::SALOME_Exception)
1460 SMESH::SMESH_Group_var aResGrp;
1465 _preMeshInfo->FullLoadFromFile();
1467 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1468 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1470 if ( theGroup1->GetType() != theGroup2->GetType() )
1471 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1475 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1476 if ( aResGrp->_is_nil() )
1477 return aResGrp._retn();
1479 SMESHDS_GroupBase* groupDS1 = 0;
1480 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1481 groupDS1 = grp_i->GetGroupDS();
1483 SMESHDS_GroupBase* groupDS2 = 0;
1484 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1485 groupDS2 = grp_i->GetGroupDS();
1487 SMESHDS_Group* resGroupDS = 0;
1488 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1489 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1491 if ( groupDS1 && groupDS2 && resGroupDS )
1493 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1494 while ( elemIt1->more() )
1496 const SMDS_MeshElement* e = elemIt1->next();
1497 if ( !groupDS2->Contains( e ))
1498 resGroupDS->SMDSGroup().Add( e );
1501 // Update Python script
1502 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1503 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1505 SMESH_CATCH( SMESH::throwCorbaException );
1507 return aResGrp._retn();
1510 //=============================================================================
1512 \brief Cut lists of groups. New group is created. All mesh elements that are
1513 present in main groups but do not present in tool groups are added to the new one
1514 \param theMainGroups list of main groups
1515 \param theToolGroups list of tool groups
1516 \param theName name of group to be created
1517 \return pointer on the group
1519 //=============================================================================
1520 SMESH::SMESH_Group_ptr
1521 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1522 const SMESH::ListOfGroups& theToolGroups,
1523 const char* theName )
1524 throw (SALOME::SALOME_Exception)
1526 SMESH::SMESH_Group_var aResGrp;
1531 _preMeshInfo->FullLoadFromFile();
1534 return SMESH::SMESH_Group::_nil();
1536 // check types and get SMESHDS_GroupBase's
1537 SMESH::ElementType aType = SMESH::ALL;
1538 vector< SMESHDS_GroupBase* > toolGroupVec;
1539 vector< SMDS_ElemIteratorPtr > mainIterVec;
1541 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1543 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1544 if ( CORBA::is_nil( aGrp ) )
1546 if ( aType == SMESH::ALL )
1547 aType = aGrp->GetType();
1548 else if ( aType != aGrp->GetType() )
1549 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1551 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1552 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1553 if ( !grpDS->IsEmpty() )
1554 mainIterVec.push_back( grpDS->GetElements() );
1556 if ( aType == SMESH::ALL ) // all main groups are nil
1557 return SMESH::SMESH_Group::_nil();
1558 if ( mainIterVec.empty() ) // all main groups are empty
1559 return aResGrp._retn();
1561 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1563 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1564 if ( CORBA::is_nil( aGrp ) )
1566 if ( aType != aGrp->GetType() )
1567 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1569 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1570 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1571 toolGroupVec.push_back( grpDS );
1577 aResGrp = CreateGroup( aType, theName );
1579 SMESHDS_Group* resGroupDS = 0;
1580 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1581 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1583 return aResGrp._retn();
1586 size_t i, nb = toolGroupVec.size();
1587 SMDS_ElemIteratorPtr mainElemIt
1588 ( new SMDS_IteratorOnIterators
1589 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1590 while ( mainElemIt->more() )
1592 const SMDS_MeshElement* e = mainElemIt->next();
1594 for ( i = 0; ( i < nb && !isIn ); ++i )
1595 isIn = toolGroupVec[i]->Contains( e );
1598 resGroupDS->SMDSGroup().Add( e );
1601 // Update Python script
1602 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1603 << ".CutListOfGroups( " << theMainGroups << ", "
1604 << theToolGroups << ", '" << theName << "' )";
1606 SMESH_CATCH( SMESH::throwCorbaException );
1608 return aResGrp._retn();
1611 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1613 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1614 bool & toStopChecking )
1616 toStopChecking = ( nbCommon < nbChecked );
1617 return nbCommon == nbNodes;
1619 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1620 bool & toStopChecking )
1622 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1623 return nbCommon == nbCorners;
1625 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1626 bool & toStopChecking )
1628 return nbCommon > 0;
1630 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1631 bool & toStopChecking )
1633 return nbCommon >= (nbNodes+1) / 2;
1637 //=============================================================================
1639 * Create a group of entities basing on nodes of other groups.
1640 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1641 * \param [in] anElemType - a type of elements to include to the new group.
1642 * \param [in] theName - a name of the new group.
1643 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1644 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1645 * new group provided that it is based on nodes of an element of \a aListOfGroups
1646 * \return SMESH_Group - the created group
1648 // IMP 19939, bug 22010, IMP 22635
1649 //=============================================================================
1651 SMESH::SMESH_Group_ptr
1652 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1653 SMESH::ElementType theElemType,
1654 const char* theName,
1655 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1656 CORBA::Boolean theUnderlyingOnly)
1657 throw (SALOME::SALOME_Exception)
1659 SMESH::SMESH_Group_var aResGrp;
1663 _preMeshInfo->FullLoadFromFile();
1665 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1667 if ( !theName || !aMeshDS )
1668 return SMESH::SMESH_Group::_nil();
1670 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1672 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1673 SMESH_Comment nbCoNoStr( "SMESH.");
1674 switch ( theNbCommonNodes ) {
1675 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1676 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1677 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1678 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1679 default: return aResGrp._retn();
1681 int nbChecked, nbCommon, nbNodes, nbCorners;
1687 aResGrp = CreateGroup( theElemType, theName );
1688 if ( aResGrp->_is_nil() )
1689 return SMESH::SMESH_Group::_nil();
1691 SMESHDS_GroupBase* groupBaseDS =
1692 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1693 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1695 vector<bool> isNodeInGroups;
1697 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1699 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1700 if ( CORBA::is_nil( aGrp ) )
1702 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1703 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1706 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1707 if ( !elIt ) continue;
1709 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1711 while ( elIt->more() ) {
1712 const SMDS_MeshElement* el = elIt->next();
1713 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1714 while ( nIt->more() )
1715 resGroupCore.Add( nIt->next() );
1718 // get elements of theElemType based on nodes of every element of group
1719 else if ( theUnderlyingOnly )
1721 while ( elIt->more() )
1723 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1724 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1725 TIDSortedElemSet checkedElems;
1726 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1727 while ( nIt->more() )
1729 const SMDS_MeshNode* n = nIt->next();
1730 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1731 // check nodes of elements of theElemType around el
1732 while ( elOfTypeIt->more() )
1734 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1735 if ( !checkedElems.insert( elOfType ).second ) continue;
1736 nbNodes = elOfType->NbNodes();
1737 nbCorners = elOfType->NbCornerNodes();
1739 bool toStopChecking = false;
1740 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1741 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1742 if ( elNodes.count( nIt2->next() ) &&
1743 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1745 resGroupCore.Add( elOfType );
1752 // get all nodes of elements of groups
1755 while ( elIt->more() )
1757 const SMDS_MeshElement* el = elIt->next(); // an element of group
1758 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1759 while ( nIt->more() )
1761 const SMDS_MeshNode* n = nIt->next();
1762 if ( n->GetID() >= (int) isNodeInGroups.size() )
1763 isNodeInGroups.resize( n->GetID() + 1, false );
1764 isNodeInGroups[ n->GetID() ] = true;
1770 // Get elements of theElemType based on a certain number of nodes of elements of groups
1771 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1773 const SMDS_MeshNode* n;
1774 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1775 const int isNodeInGroupsSize = isNodeInGroups.size();
1776 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1778 if ( !isNodeInGroups[ iN ] ||
1779 !( n = aMeshDS->FindNode( iN )))
1782 // check nodes of elements of theElemType around n
1783 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1784 while ( elOfTypeIt->more() )
1786 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1787 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1792 nbNodes = elOfType->NbNodes();
1793 nbCorners = elOfType->NbCornerNodes();
1795 bool toStopChecking = false;
1796 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1797 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1799 const int nID = nIt->next()->GetID();
1800 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1801 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1803 resGroupCore.Add( elOfType );
1811 // Update Python script
1812 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1813 << ".CreateDimGroup( "
1814 << theGroups << ", " << theElemType << ", '" << theName << "', "
1815 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1817 SMESH_CATCH( SMESH::throwCorbaException );
1819 return aResGrp._retn();
1822 //================================================================================
1824 * \brief Remember GEOM group data
1826 //================================================================================
1828 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1829 CORBA::Object_ptr theSmeshObj)
1831 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1834 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1835 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1836 if ( groupSO->_is_nil() )
1839 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1840 GEOM::GEOM_IGroupOperations_wrap groupOp =
1841 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1842 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1845 _geomGroupData.push_back( TGeomGroupData() );
1846 TGeomGroupData & groupData = _geomGroupData.back();
1848 CORBA::String_var entry = groupSO->GetID();
1849 groupData._groupEntry = entry.in();
1851 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1852 groupData._indices.insert( ids[i] );
1854 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1855 // shape index in SMESHDS
1856 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1857 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1860 //================================================================================
1862 * Remove GEOM group data relating to removed smesh object
1864 //================================================================================
1866 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1868 list<TGeomGroupData>::iterator
1869 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1870 for ( ; data != dataEnd; ++data ) {
1871 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1872 _geomGroupData.erase( data );
1878 //================================================================================
1880 * \brief Return new group contents if it has been changed and update group data
1882 //================================================================================
1884 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1886 TopoDS_Shape newShape;
1889 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1890 if ( study->_is_nil() ) return newShape; // means "not changed"
1891 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1892 if ( !groupSO->_is_nil() )
1894 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1895 if ( CORBA::is_nil( groupObj )) return newShape;
1896 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1898 // get indices of group items
1899 set<int> curIndices;
1900 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1901 GEOM::GEOM_IGroupOperations_wrap groupOp =
1902 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1903 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1904 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1905 curIndices.insert( ids[i] );
1907 if ( groupData._indices == curIndices )
1908 return newShape; // group not changed
1911 groupData._indices = curIndices;
1913 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1914 if ( !geomClient ) return newShape;
1915 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1916 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1917 newShape = _gen_i->GeomObjectToShape( geomGroup );
1920 if ( newShape.IsNull() ) {
1921 // geom group becomes empty - return empty compound
1922 TopoDS_Compound compound;
1923 BRep_Builder().MakeCompound(compound);
1924 newShape = compound;
1931 //-----------------------------------------------------------------------------
1933 * \brief Storage of shape and index used in CheckGeomGroupModif()
1935 struct TIndexedShape
1938 TopoDS_Shape _shape;
1939 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1941 //-----------------------------------------------------------------------------
1943 * \brief Data to re-create a group on geometry
1945 struct TGroupOnGeomData
1949 SMDSAbs_ElementType _type;
1951 Quantity_Color _color;
1955 //=============================================================================
1957 * \brief Update data if geometry changes
1961 //=============================================================================
1963 void SMESH_Mesh_i::CheckGeomModif()
1965 if ( !_impl->HasShapeToMesh() ) return;
1967 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1968 if ( study->_is_nil() ) return;
1970 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1971 //if ( mainGO->_is_nil() ) return;
1973 // Update after group modification
1975 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1976 called by other mesh (IPAL52735) */
1977 mainGO->GetType() == GEOM_GROUP ||
1978 mainGO->GetTick() == _mainShapeTick )
1980 CheckGeomGroupModif();
1984 // Update after shape transformation like Translate
1986 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1987 if ( !geomClient ) return;
1988 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1989 if ( geomGen->_is_nil() ) return;
1991 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1992 geomClient->RemoveShapeFromBuffer( ior.in() );
1994 // Update data taking into account that
1995 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1998 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1999 if ( newShape.IsNull() )
2002 _mainShapeTick = mainGO->GetTick();
2004 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2006 // store data of groups on geometry
2007 vector< TGroupOnGeomData > groupsData;
2008 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2009 groupsData.reserve( groups.size() );
2010 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2011 for ( ; g != groups.end(); ++g )
2012 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2014 TGroupOnGeomData data;
2015 data._oldID = group->GetID();
2016 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2017 data._type = group->GetType();
2018 data._name = group->GetStoreName();
2019 data._color = group->GetColor();
2020 groupsData.push_back( data );
2022 // store assigned hypotheses
2023 vector< pair< int, THypList > > ids2Hyps;
2024 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2025 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2027 const TopoDS_Shape& s = s2hyps.Key();
2028 const THypList& hyps = s2hyps.ChangeValue();
2029 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2032 // change shape to mesh
2033 int oldNbSubShapes = meshDS->MaxShapeIndex();
2034 _impl->ShapeToMesh( TopoDS_Shape() );
2035 _impl->ShapeToMesh( newShape );
2037 // re-add shapes of geom groups
2038 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2039 for ( ; data != _geomGroupData.end(); ++data )
2041 TopoDS_Shape newShape = newGroupShape( *data );
2042 if ( !newShape.IsNull() )
2044 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2046 TopoDS_Compound compound;
2047 BRep_Builder().MakeCompound( compound );
2048 BRep_Builder().Add( compound, newShape );
2049 newShape = compound;
2051 _impl->GetSubMesh( newShape );
2054 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2055 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2056 SALOME::INTERNAL_ERROR );
2058 // re-assign hypotheses
2059 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2061 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2062 const THypList& hyps = ids2Hyps[i].second;
2063 THypList::const_iterator h = hyps.begin();
2064 for ( ; h != hyps.end(); ++h )
2065 _impl->AddHypothesis( s, (*h)->GetID() );
2069 for ( size_t i = 0; i < groupsData.size(); ++i )
2071 const TGroupOnGeomData& data = groupsData[i];
2073 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2074 if ( i2g == _mapGroups.end() ) continue;
2076 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2077 if ( !gr_i ) continue;
2080 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2081 meshDS->IndexToShape( data._shapeID ));
2084 _mapGroups.erase( i2g );
2088 g->GetGroupDS()->SetColor( data._color );
2089 gr_i->changeLocalId( id );
2090 _mapGroups[ id ] = i2g->second;
2091 if ( data._oldID != id )
2092 _mapGroups.erase( i2g );
2096 // update _mapSubMesh
2097 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2098 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2099 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2103 //=============================================================================
2105 * \brief Update objects depending on changed geom groups
2107 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2108 * issue 0020210: Update of a smesh group after modification of the associated geom group
2110 //=============================================================================
2112 void SMESH_Mesh_i::CheckGeomGroupModif()
2114 if ( !_impl->HasShapeToMesh() ) return;
2116 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2117 if ( study->_is_nil() ) return;
2119 CORBA::Long nbEntities = NbNodes() + NbElements();
2121 // Check if group contents changed
2123 typedef map< string, TopoDS_Shape > TEntry2Geom;
2124 TEntry2Geom newGroupContents;
2126 list<TGeomGroupData>::iterator
2127 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2128 for ( ; data != dataEnd; ++data )
2130 pair< TEntry2Geom::iterator, bool > it_new =
2131 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2132 bool processedGroup = !it_new.second;
2133 TopoDS_Shape& newShape = it_new.first->second;
2134 if ( !processedGroup )
2135 newShape = newGroupShape( *data );
2136 if ( newShape.IsNull() )
2137 continue; // no changes
2140 _preMeshInfo->ForgetOrLoad();
2142 if ( processedGroup ) { // update group indices
2143 list<TGeomGroupData>::iterator data2 = data;
2144 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2145 data->_indices = data2->_indices;
2148 // Update SMESH objects according to new GEOM group contents
2150 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2151 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2153 int oldID = submesh->GetId();
2154 if ( !_mapSubMeshIor.count( oldID ))
2156 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2158 // update hypotheses
2159 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2160 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2161 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2163 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2164 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2166 // care of submeshes
2167 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2168 int newID = newSubmesh->GetId();
2169 if ( newID != oldID ) {
2170 _mapSubMesh [ newID ] = newSubmesh;
2171 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2172 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2173 _mapSubMesh. erase(oldID);
2174 _mapSubMesh_i. erase(oldID);
2175 _mapSubMeshIor.erase(oldID);
2176 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2181 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2182 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2183 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2185 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2187 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2188 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2189 ds->SetShape( newShape );
2194 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2195 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2197 // Remove groups and submeshes basing on removed sub-shapes
2199 TopTools_MapOfShape newShapeMap;
2200 TopoDS_Iterator shapeIt( newShape );
2201 for ( ; shapeIt.More(); shapeIt.Next() )
2202 newShapeMap.Add( shapeIt.Value() );
2204 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2205 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2207 if ( newShapeMap.Contains( shapeIt.Value() ))
2209 TopTools_IndexedMapOfShape oldShapeMap;
2210 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2211 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2213 const TopoDS_Shape& oldShape = oldShapeMap(i);
2214 int oldInd = meshDS->ShapeToIndex( oldShape );
2216 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2217 if ( i_smIor != _mapSubMeshIor.end() ) {
2218 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2221 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2222 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2224 // check if a group bases on oldInd shape
2225 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2226 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2227 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2228 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2230 RemoveGroup( i_grp->second ); // several groups can base on same shape
2231 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2236 // Reassign hypotheses and update groups after setting the new shape to mesh
2238 // collect anassigned hypotheses
2239 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2240 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2241 TShapeHypList assignedHyps;
2242 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2244 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2245 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2246 if ( !hyps.empty() ) {
2247 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2248 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2249 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2252 // collect shapes supporting groups
2253 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2254 TShapeTypeList groupData;
2255 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2256 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2257 for ( ; grIt != groups.end(); ++grIt )
2259 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2261 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2263 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2265 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2266 _impl->ShapeToMesh( newShape );
2268 // reassign hypotheses
2269 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2270 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2272 TIndexedShape& geom = indS_hyps->first;
2273 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2274 int oldID = geom._index;
2275 int newID = meshDS->ShapeToIndex( geom._shape );
2276 if ( oldID == 1 ) { // main shape
2278 geom._shape = newShape;
2282 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2283 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2284 // care of sub-meshes
2285 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2286 if ( newID != oldID ) {
2287 _mapSubMesh [ newID ] = newSubmesh;
2288 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2289 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2290 _mapSubMesh. erase(oldID);
2291 _mapSubMesh_i. erase(oldID);
2292 _mapSubMeshIor.erase(oldID);
2293 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2297 TShapeTypeList::iterator geomType = groupData.begin();
2298 for ( ; geomType != groupData.end(); ++geomType )
2300 const TIndexedShape& geom = geomType->first;
2301 int oldID = geom._index;
2302 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2305 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2306 CORBA::String_var name = groupSO->GetName();
2308 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2310 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2311 group_i->changeLocalId( newID );
2314 break; // everything has been updated
2317 } // loop on group data
2321 CORBA::Long newNbEntities = NbNodes() + NbElements();
2322 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2323 if ( newNbEntities != nbEntities )
2325 // Add all SObjects with icons to soToUpdateIcons
2326 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2328 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2329 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2330 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2332 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2333 i_gr != _mapGroups.end(); ++i_gr ) // groups
2334 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2337 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2338 for ( ; so != soToUpdateIcons.end(); ++so )
2339 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2342 //=============================================================================
2344 * \brief Create standalone group from a group on geometry or filter
2346 //=============================================================================
2348 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2349 throw (SALOME::SALOME_Exception)
2351 SMESH::SMESH_Group_var aGroup;
2356 _preMeshInfo->FullLoadFromFile();
2358 if ( theGroup->_is_nil() )
2359 return aGroup._retn();
2361 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2363 return aGroup._retn();
2365 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2367 const int anId = aGroupToRem->GetLocalID();
2368 if ( !_impl->ConvertToStandalone( anId ) )
2369 return aGroup._retn();
2370 removeGeomGroupData( theGroup );
2372 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2374 // remove old instance of group from own map
2375 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2376 _mapGroups.erase( anId );
2378 SALOMEDS::StudyBuilder_var builder;
2379 SALOMEDS::SObject_wrap aGroupSO;
2380 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2381 if ( !aStudy->_is_nil() ) {
2382 builder = aStudy->NewBuilder();
2383 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2384 if ( !aGroupSO->_is_nil() )
2386 // remove reference to geometry
2387 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2388 for ( ; chItr->More(); chItr->Next() )
2389 // Remove group's child SObject
2390 builder->RemoveObject( chItr->Value() );
2392 // Update Python script
2393 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2394 << ".ConvertToStandalone( " << aGroupSO << " )";
2396 // change icon of Group on Filter
2399 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2400 const int isEmpty = ( elemTypes->length() == 0 );
2403 SALOMEDS::GenericAttribute_wrap anAttr =
2404 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2405 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2406 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2412 // remember new group in own map
2413 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2414 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2416 // register CORBA object for persistence
2417 _gen_i->RegisterObject( aGroup );
2419 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2420 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2421 //aGroup->Register();
2422 aGroupToRem->UnRegister();
2424 SMESH_CATCH( SMESH::throwCorbaException );
2426 return aGroup._retn();
2429 //=============================================================================
2433 //=============================================================================
2435 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2437 if(MYDEBUG) MESSAGE( "createSubMesh" );
2438 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2439 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2440 const int subMeshId = mySubMesh->GetId();
2442 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2443 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2445 _mapSubMesh [subMeshId] = mySubMesh;
2446 _mapSubMesh_i [subMeshId] = subMeshServant;
2447 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2449 subMeshServant->Register();
2451 // register CORBA object for persistence
2452 int nextId = _gen_i->RegisterObject( subMesh );
2453 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2454 else { nextId = 0; } // avoid "unused variable" warning
2456 // to track changes of GEOM groups
2457 addGeomGroupData( theSubShapeObject, subMesh );
2459 return subMesh._retn();
2462 //=======================================================================
2463 //function : getSubMesh
2465 //=======================================================================
2467 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2469 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2470 if ( it == _mapSubMeshIor.end() )
2471 return SMESH::SMESH_subMesh::_nil();
2473 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2476 //=============================================================================
2480 //=============================================================================
2482 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2483 GEOM::GEOM_Object_ptr theSubShapeObject )
2485 bool isHypChanged = false;
2486 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2487 return isHypChanged;
2489 const int subMeshId = theSubMesh->GetId();
2491 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2493 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2495 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2498 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2499 isHypChanged = !hyps.empty();
2500 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2501 for ( ; hyp != hyps.end(); ++hyp )
2502 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2509 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2510 isHypChanged = ( aHypList->length() > 0 );
2511 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2512 removeHypothesis( theSubShapeObject, aHypList[i] );
2515 catch( const SALOME::SALOME_Exception& ) {
2516 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2518 removeGeomGroupData( theSubShapeObject );
2522 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2523 if ( id_smi != _mapSubMesh_i.end() )
2524 id_smi->second->UnRegister();
2526 // remove a CORBA object
2527 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2528 if ( id_smptr != _mapSubMeshIor.end() )
2529 SMESH::SMESH_subMesh_var( id_smptr->second );
2531 _mapSubMesh.erase(subMeshId);
2532 _mapSubMesh_i.erase(subMeshId);
2533 _mapSubMeshIor.erase(subMeshId);
2535 return isHypChanged;
2538 //=============================================================================
2542 //=============================================================================
2544 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2545 const char* theName,
2546 const TopoDS_Shape& theShape,
2547 const SMESH_PredicatePtr& thePredicate )
2549 std::string newName;
2550 if ( !theName || strlen( theName ) == 0 )
2552 std::set< std::string > presentNames;
2553 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2554 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2556 CORBA::String_var name = i_gr->second->GetName();
2557 presentNames.insert( name.in() );
2560 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2561 } while ( !presentNames.insert( newName ).second );
2562 theName = newName.c_str();
2565 SMESH::SMESH_GroupBase_var aGroup;
2566 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2568 SMESH_GroupBase_i* aGroupImpl;
2569 if ( !theShape.IsNull() )
2570 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2571 else if ( thePredicate )
2572 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2574 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2576 aGroup = aGroupImpl->_this();
2577 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2578 aGroupImpl->Register();
2580 // register CORBA object for persistence
2581 int nextId = _gen_i->RegisterObject( aGroup );
2582 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2583 else { nextId = 0; } // avoid "unused variable" warning in release mode
2585 // to track changes of GEOM groups
2586 if ( !theShape.IsNull() ) {
2587 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2588 addGeomGroupData( geom, aGroup );
2591 return aGroup._retn();
2594 //=============================================================================
2596 * SMESH_Mesh_i::removeGroup
2598 * Should be called by ~SMESH_Group_i()
2600 //=============================================================================
2602 void SMESH_Mesh_i::removeGroup( const int theId )
2604 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2605 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2606 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2607 _mapGroups.erase( theId );
2608 removeGeomGroupData( group );
2609 if ( !_impl->RemoveGroup( theId ))
2611 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2612 RemoveGroup( group );
2614 group->UnRegister();
2618 //=============================================================================
2622 //=============================================================================
2624 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2625 throw(SALOME::SALOME_Exception)
2627 SMESH::log_array_var aLog;
2631 _preMeshInfo->FullLoadFromFile();
2633 list < SMESHDS_Command * >logDS = _impl->GetLog();
2634 aLog = new SMESH::log_array;
2636 int lg = logDS.size();
2639 list < SMESHDS_Command * >::iterator its = logDS.begin();
2640 while(its != logDS.end()){
2641 SMESHDS_Command *com = *its;
2642 int comType = com->GetType();
2644 int lgcom = com->GetNumber();
2646 const list < int >&intList = com->GetIndexes();
2647 int inum = intList.size();
2649 list < int >::const_iterator ii = intList.begin();
2650 const list < double >&coordList = com->GetCoords();
2651 int rnum = coordList.size();
2653 list < double >::const_iterator ir = coordList.begin();
2654 aLog[indexLog].commandType = comType;
2655 aLog[indexLog].number = lgcom;
2656 aLog[indexLog].coords.length(rnum);
2657 aLog[indexLog].indexes.length(inum);
2658 for(int i = 0; i < rnum; i++){
2659 aLog[indexLog].coords[i] = *ir;
2660 //MESSAGE(" "<<i<<" "<<ir.Value());
2663 for(int i = 0; i < inum; i++){
2664 aLog[indexLog].indexes[i] = *ii;
2665 //MESSAGE(" "<<i<<" "<<ii.Value());
2674 SMESH_CATCH( SMESH::throwCorbaException );
2676 return aLog._retn();
2680 //=============================================================================
2684 //=============================================================================
2686 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2690 SMESH_CATCH( SMESH::throwCorbaException );
2693 //=============================================================================
2697 //=============================================================================
2699 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2704 //=============================================================================
2708 //=============================================================================
2710 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2715 //=============================================================================
2718 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2719 // issue 0020918: groups removal is caused by hyp modification
2720 // issue 0021208: to forget not loaded mesh data at hyp modification
2721 struct TCallUp_i : public SMESH_Mesh::TCallUp
2723 SMESH_Mesh_i* _mesh;
2724 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2725 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2726 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2727 virtual void Load () { _mesh->Load(); }
2731 //================================================================================
2733 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2735 //================================================================================
2737 void SMESH_Mesh_i::onHypothesisModified()
2740 _preMeshInfo->ForgetOrLoad();
2743 //=============================================================================
2747 //=============================================================================
2749 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2751 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2754 _impl->SetCallUp( new TCallUp_i(this));
2757 //=============================================================================
2761 //=============================================================================
2763 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2765 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2769 //=============================================================================
2771 * Return mesh editor
2773 //=============================================================================
2775 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2776 throw (SALOME::SALOME_Exception)
2778 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2782 _preMeshInfo->FullLoadFromFile();
2784 // Create MeshEditor
2786 _editor = new SMESH_MeshEditor_i( this, false );
2787 aMeshEdVar = _editor->_this();
2789 // Update Python script
2790 TPythonDump() << _editor << " = "
2791 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2793 SMESH_CATCH( SMESH::throwCorbaException );
2795 return aMeshEdVar._retn();
2798 //=============================================================================
2800 * Return mesh edition previewer
2802 //=============================================================================
2804 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2805 throw (SALOME::SALOME_Exception)
2807 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2811 _preMeshInfo->FullLoadFromFile();
2813 if ( !_previewEditor )
2814 _previewEditor = new SMESH_MeshEditor_i( this, true );
2815 aMeshEdVar = _previewEditor->_this();
2817 SMESH_CATCH( SMESH::throwCorbaException );
2819 return aMeshEdVar._retn();
2822 //================================================================================
2824 * \brief Return true if the mesh has been edited since a last total re-compute
2825 * and those modifications may prevent successful partial re-compute
2827 //================================================================================
2829 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2831 Unexpect aCatch(SALOME_SalomeException);
2832 return _impl->HasModificationsToDiscard();
2835 //================================================================================
2837 * \brief Returns a random unique color
2839 //================================================================================
2841 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2843 const int MAX_ATTEMPTS = 100;
2845 double tolerance = 0.5;
2846 SALOMEDS::Color col;
2850 // generate random color
2851 double red = (double)rand() / RAND_MAX;
2852 double green = (double)rand() / RAND_MAX;
2853 double blue = (double)rand() / RAND_MAX;
2854 // check existence in the list of the existing colors
2855 bool matched = false;
2856 std::list<SALOMEDS::Color>::const_iterator it;
2857 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2858 SALOMEDS::Color color = *it;
2859 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2860 matched = tol < tolerance;
2862 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2863 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2871 //=============================================================================
2873 * Sets auto-color mode. If it is on, groups get unique random colors
2875 //=============================================================================
2877 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2879 Unexpect aCatch(SALOME_SalomeException);
2880 _impl->SetAutoColor(theAutoColor);
2882 TPythonDump pyDump; // not to dump group->SetColor() from below code
2883 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2885 std::list<SALOMEDS::Color> aReservedColors;
2886 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2887 for ( ; it != _mapGroups.end(); it++ ) {
2888 if ( CORBA::is_nil( it->second )) continue;
2889 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2890 it->second->SetColor( aColor );
2891 aReservedColors.push_back( aColor );
2895 //=============================================================================
2897 * Returns true if auto-color mode is on
2899 //=============================================================================
2901 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2903 Unexpect aCatch(SALOME_SalomeException);
2904 return _impl->GetAutoColor();
2907 //=============================================================================
2909 * Checks if there are groups with equal names
2911 //=============================================================================
2913 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2915 return _impl->HasDuplicatedGroupNamesMED();
2918 //================================================================================
2920 * \brief Care of a file before exporting mesh into it
2922 //================================================================================
2924 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2926 SMESH_File aFile( file );
2928 if (aFile.exists()) {
2929 // existing filesystem node
2930 if ( !aFile.isDirectory() ) {
2931 if ( aFile.openForWriting() ) {
2932 if ( overwrite && ! aFile.remove()) {
2933 msg << "Can't replace " << aFile.getName();
2936 msg << "Can't write into " << aFile.getName();
2939 msg << "Location " << aFile.getName() << " is not a file";
2943 // nonexisting file; check if it can be created
2944 if ( !aFile.openForWriting() ) {
2945 msg << "You cannot create the file "
2947 << ". Check the directory existance and access rights";
2955 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2959 //================================================================================
2961 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2962 * \param file - file name
2963 * \param overwrite - to erase the file or not
2964 * \retval string - mesh name
2966 //================================================================================
2968 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2969 CORBA::Boolean overwrite)
2972 PrepareForWriting(file, overwrite);
2973 string aMeshName = "Mesh";
2974 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2975 if ( !aStudy->_is_nil() ) {
2976 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2977 if ( !aMeshSO->_is_nil() ) {
2978 CORBA::String_var name = aMeshSO->GetName();
2980 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2981 if ( !aStudy->GetProperties()->IsLocked() )
2983 SALOMEDS::GenericAttribute_wrap anAttr;
2984 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2985 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2986 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2987 ASSERT(!aFileName->_is_nil());
2988 aFileName->SetValue(file);
2989 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2990 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2991 ASSERT(!aFileType->_is_nil());
2992 aFileType->SetValue("FICHIERMED");
2996 // Update Python script
2997 // set name of mesh before export
2998 TPythonDump() << _gen_i << ".SetName("
2999 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3001 // check names of groups
3007 //================================================================================
3009 * \brief Export to med file
3011 //================================================================================
3013 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3014 CORBA::Boolean auto_groups,
3015 SMESH::MED_VERSION theVersion,
3016 CORBA::Boolean overwrite,
3017 CORBA::Boolean autoDimension)
3018 throw(SALOME::SALOME_Exception)
3022 _preMeshInfo->FullLoadFromFile();
3024 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3025 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3027 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3028 << file << "', " << auto_groups << ", "
3029 << theVersion << ", " << overwrite << ", "
3030 << autoDimension << " )";
3032 SMESH_CATCH( SMESH::throwCorbaException );
3035 //================================================================================
3037 * \brief Export a mesh to a med file
3039 //================================================================================
3041 void SMESH_Mesh_i::ExportToMED (const char* file,
3042 CORBA::Boolean auto_groups,
3043 SMESH::MED_VERSION theVersion)
3044 throw(SALOME::SALOME_Exception)
3046 ExportToMEDX(file,auto_groups,theVersion,true);
3049 //================================================================================
3051 * \brief Export a mesh to a med file
3053 //================================================================================
3055 void SMESH_Mesh_i::ExportMED (const char* file,
3056 CORBA::Boolean auto_groups)
3057 throw(SALOME::SALOME_Exception)
3059 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3062 //================================================================================
3064 * \brief Export a mesh to a SAUV file
3066 //================================================================================
3068 void SMESH_Mesh_i::ExportSAUV (const char* file,
3069 CORBA::Boolean auto_groups)
3070 throw(SALOME::SALOME_Exception)
3072 Unexpect aCatch(SALOME_SalomeException);
3074 _preMeshInfo->FullLoadFromFile();
3076 string aMeshName = prepareMeshNameAndGroups(file, true);
3077 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3078 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3079 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3083 //================================================================================
3085 * \brief Export a mesh to a DAT file
3087 //================================================================================
3089 void SMESH_Mesh_i::ExportDAT (const char *file)
3090 throw(SALOME::SALOME_Exception)
3092 Unexpect aCatch(SALOME_SalomeException);
3094 _preMeshInfo->FullLoadFromFile();
3096 // Update Python script
3097 // check names of groups
3099 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3102 PrepareForWriting(file);
3103 _impl->ExportDAT(file);
3106 //================================================================================
3108 * \brief Export a mesh to an UNV file
3110 //================================================================================
3112 void SMESH_Mesh_i::ExportUNV (const char *file)
3113 throw(SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3117 _preMeshInfo->FullLoadFromFile();
3119 // Update Python script
3120 // check names of groups
3122 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3125 PrepareForWriting(file);
3126 _impl->ExportUNV(file);
3129 //================================================================================
3131 * \brief Export a mesh to an STL file
3133 //================================================================================
3135 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3136 throw(SALOME::SALOME_Exception)
3138 Unexpect aCatch(SALOME_SalomeException);
3140 _preMeshInfo->FullLoadFromFile();
3142 // Update Python script
3143 // check names of groups
3145 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3146 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3149 PrepareForWriting(file);
3150 _impl->ExportSTL(file, isascii);
3153 //================================================================================
3155 * \brief Export a part of mesh to a med file
3157 //================================================================================
3159 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3161 CORBA::Boolean auto_groups,
3162 SMESH::MED_VERSION version,
3163 CORBA::Boolean overwrite,
3164 CORBA::Boolean autoDimension,
3165 const GEOM::ListOfFields& fields,
3166 const char* geomAssocFields)
3167 throw (SALOME::SALOME_Exception)
3171 _preMeshInfo->FullLoadFromFile();
3174 bool have0dField = false;
3175 if ( fields.length() > 0 )
3177 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3178 if ( shapeToMesh->_is_nil() )
3179 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3181 for ( size_t i = 0; i < fields.length(); ++i )
3183 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3184 THROW_SALOME_CORBA_EXCEPTION
3185 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3186 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3187 if ( fieldShape->_is_nil() )
3188 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3189 if ( !fieldShape->IsSame( shapeToMesh ) )
3190 THROW_SALOME_CORBA_EXCEPTION
3191 ( "Field defined not on shape", SALOME::BAD_PARAM);
3192 if ( fields[i]->GetDimension() == 0 )
3195 if ( geomAssocFields )
3196 for ( int i = 0; geomAssocFields[i]; ++i )
3197 switch ( geomAssocFields[i] ) {
3198 case 'v':case 'e':case 'f':case 's': break;
3199 case 'V':case 'E':case 'F':case 'S': break;
3200 default: THROW_SALOME_CORBA_EXCEPTION
3201 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3205 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3209 string aMeshName = "Mesh";
3210 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3211 if ( CORBA::is_nil( meshPart ) ||
3212 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3214 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3215 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3216 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3217 meshDS = _impl->GetMeshDS();
3222 _preMeshInfo->FullLoadFromFile();
3224 PrepareForWriting(file, overwrite);
3226 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3227 if ( !aStudy->_is_nil() ) {
3228 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3229 if ( !SO->_is_nil() ) {
3230 CORBA::String_var name = SO->GetName();
3234 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3235 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3236 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3237 meshDS = tmpDSDeleter._obj = partDS;
3242 if ( _impl->HasShapeToMesh() )
3244 DriverMED_W_Field fieldWriter;
3245 fieldWriter.SetFile( file );
3246 fieldWriter.SetMeshName( aMeshName );
3247 fieldWriter.AddODOnVertices( have0dField );
3249 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3253 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3254 goList->length( fields.length() );
3255 for ( size_t i = 0; i < fields.length(); ++i )
3257 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3260 TPythonDump() << _this() << ".ExportPartToMED( "
3261 << meshPart << ", r'" << file << "', "
3262 << auto_groups << ", " << version << ", " << overwrite << ", "
3263 << autoDimension << ", " << goList
3264 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3266 SMESH_CATCH( SMESH::throwCorbaException );
3269 //================================================================================
3271 * Write GEOM fields to MED file
3273 //================================================================================
3275 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3276 SMESHDS_Mesh* meshDS,
3277 const GEOM::ListOfFields& fields,
3278 const char* geomAssocFields)
3280 #define METH "SMESH_Mesh_i::exportMEDFields() "
3282 if (( fields.length() < 1 ) &&
3283 ( !geomAssocFields || !geomAssocFields[0] ))
3286 std::vector< std::vector< double > > dblVals;
3287 std::vector< std::vector< int > > intVals;
3288 std::vector< int > subIdsByDim[ 4 ];
3289 const double noneDblValue = 0.;
3290 const double noneIntValue = 0;
3292 for ( size_t iF = 0; iF < fields.length(); ++iF )
3296 int dim = fields[ iF ]->GetDimension();
3297 SMDSAbs_ElementType elemType;
3298 TopAbs_ShapeEnum shapeType;
3300 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3301 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3302 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3303 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3305 continue; // skip fields on whole shape
3307 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3308 if ( dataType == GEOM::FDT_String )
3310 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3311 if ( stepIDs->length() < 1 )
3313 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3314 if ( comps->length() < 1 )
3316 CORBA::String_var name = fields[ iF ]->GetName();
3318 if ( !fieldWriter.Set( meshDS,
3322 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3325 for ( size_t iC = 0; iC < comps->length(); ++iC )
3326 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3328 dblVals.resize( comps->length() );
3329 intVals.resize( comps->length() );
3331 // find sub-shape IDs
3333 std::vector< int >& subIds = subIdsByDim[ dim ];
3334 if ( subIds.empty() )
3335 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3336 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3337 subIds.push_back( id );
3341 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3345 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3347 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3348 if ( step->_is_nil() )
3351 CORBA::Long stamp = step->GetStamp();
3352 CORBA::Long id = step->GetID();
3353 fieldWriter.SetDtIt( int( stamp ), int( id ));
3355 // fill dblVals or intVals
3356 for ( size_t iC = 0; iC < comps->length(); ++iC )
3357 if ( dataType == GEOM::FDT_Double )
3359 dblVals[ iC ].clear();
3360 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3364 intVals[ iC ].clear();
3365 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3369 case GEOM::FDT_Double:
3371 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3372 if ( dblStep->_is_nil() ) continue;
3373 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3374 if ( vv->length() != subIds.size() * comps->length() )
3375 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3376 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3377 for ( size_t iC = 0; iC < comps->length(); ++iC )
3378 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3383 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3384 if ( intStep->_is_nil() ) continue;
3385 GEOM::ListOfLong_var vv = intStep->GetValues();
3386 if ( vv->length() != subIds.size() * comps->length() )
3387 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3388 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3389 for ( size_t iC = 0; iC < comps->length(); ++iC )
3390 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3393 case GEOM::FDT_Bool:
3395 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3396 if ( boolStep->_is_nil() ) continue;
3397 GEOM::short_array_var vv = boolStep->GetValues();
3398 if ( vv->length() != subIds.size() * comps->length() )
3399 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3400 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3401 for ( size_t iC = 0; iC < comps->length(); ++iC )
3402 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3408 // pass values to fieldWriter
3409 elemIt = fieldWriter.GetOrderedElems();
3410 if ( dataType == GEOM::FDT_Double )
3411 while ( elemIt->more() )
3413 const SMDS_MeshElement* e = elemIt->next();
3414 const int shapeID = e->getshapeId();
3415 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3416 for ( size_t iC = 0; iC < comps->length(); ++iC )
3417 fieldWriter.AddValue( noneDblValue );
3419 for ( size_t iC = 0; iC < comps->length(); ++iC )
3420 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3423 while ( elemIt->more() )
3425 const SMDS_MeshElement* e = elemIt->next();
3426 const int shapeID = e->getshapeId();
3427 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3428 for ( size_t iC = 0; iC < comps->length(); ++iC )
3429 fieldWriter.AddValue( (double) noneIntValue );
3431 for ( size_t iC = 0; iC < comps->length(); ++iC )
3432 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3436 fieldWriter.Perform();
3437 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3438 if ( res && res->IsKO() )
3440 if ( res->myComment.empty() )
3441 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3443 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3449 if ( !geomAssocFields || !geomAssocFields[0] )
3452 // write geomAssocFields
3454 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3455 shapeDim[ TopAbs_COMPOUND ] = 3;
3456 shapeDim[ TopAbs_COMPSOLID ] = 3;
3457 shapeDim[ TopAbs_SOLID ] = 3;
3458 shapeDim[ TopAbs_SHELL ] = 2;
3459 shapeDim[ TopAbs_FACE ] = 2;
3460 shapeDim[ TopAbs_WIRE ] = 1;
3461 shapeDim[ TopAbs_EDGE ] = 1;
3462 shapeDim[ TopAbs_VERTEX ] = 0;
3463 shapeDim[ TopAbs_SHAPE ] = 3;
3465 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3467 std::vector< std::string > compNames;
3468 switch ( geomAssocFields[ iF ]) {
3470 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3471 compNames.push_back( "dim" );
3474 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3477 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3480 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3484 compNames.push_back( "id" );
3485 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3486 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3488 fieldWriter.SetDtIt( -1, -1 );
3490 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3494 if ( compNames.size() == 2 ) // _vertices_
3495 while ( elemIt->more() )
3497 const SMDS_MeshElement* e = elemIt->next();
3498 const int shapeID = e->getshapeId();
3501 fieldWriter.AddValue( (double) -1 );
3502 fieldWriter.AddValue( (double) -1 );
3506 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3507 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3508 fieldWriter.AddValue( (double) shapeID );
3512 while ( elemIt->more() )
3514 const SMDS_MeshElement* e = elemIt->next();
3515 const int shapeID = e->getshapeId();
3517 fieldWriter.AddValue( (double) -1 );
3519 fieldWriter.AddValue( (double) shapeID );
3523 fieldWriter.Perform();
3524 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3525 if ( res && res->IsKO() )
3527 if ( res->myComment.empty() )
3528 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3530 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3533 } // loop on geomAssocFields
3538 //================================================================================
3540 * \brief Export a part of mesh to a DAT file
3542 //================================================================================
3544 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3546 throw (SALOME::SALOME_Exception)
3548 Unexpect aCatch(SALOME_SalomeException);
3550 _preMeshInfo->FullLoadFromFile();
3552 PrepareForWriting(file);
3554 SMESH_MeshPartDS partDS( meshPart );
3555 _impl->ExportDAT(file,&partDS);
3557 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3558 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3560 //================================================================================
3562 * \brief Export a part of mesh to an UNV file
3564 //================================================================================
3566 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3568 throw (SALOME::SALOME_Exception)
3570 Unexpect aCatch(SALOME_SalomeException);
3572 _preMeshInfo->FullLoadFromFile();
3574 PrepareForWriting(file);
3576 SMESH_MeshPartDS partDS( meshPart );
3577 _impl->ExportUNV(file, &partDS);
3579 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3580 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3582 //================================================================================
3584 * \brief Export a part of mesh to an STL file
3586 //================================================================================
3588 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3590 ::CORBA::Boolean isascii)
3591 throw (SALOME::SALOME_Exception)
3593 Unexpect aCatch(SALOME_SalomeException);
3595 _preMeshInfo->FullLoadFromFile();
3597 PrepareForWriting(file);
3599 SMESH_MeshPartDS partDS( meshPart );
3600 _impl->ExportSTL(file, isascii, &partDS);
3602 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3603 << meshPart<< ", r'" << file << "', " << isascii << ")";
3606 //================================================================================
3608 * \brief Export a part of mesh to an STL file
3610 //================================================================================
3612 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3614 CORBA::Boolean overwrite)
3615 throw (SALOME::SALOME_Exception)
3618 Unexpect aCatch(SALOME_SalomeException);
3620 _preMeshInfo->FullLoadFromFile();
3622 PrepareForWriting(file,overwrite);
3624 std::string meshName("");
3625 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3626 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3627 if ( !so->_is_nil() )
3629 CORBA::String_var name = so->GetName();
3630 meshName = name.in();
3632 SMESH_MeshPartDS partDS( meshPart );
3633 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3635 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3636 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3638 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3642 //================================================================================
3644 * \brief Export a part of mesh to a GMF file
3646 //================================================================================
3648 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3650 bool withRequiredGroups)
3651 throw (SALOME::SALOME_Exception)
3653 Unexpect aCatch(SALOME_SalomeException);
3655 _preMeshInfo->FullLoadFromFile();
3657 PrepareForWriting(file,/*overwrite=*/true);
3659 SMESH_MeshPartDS partDS( meshPart );
3660 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3662 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3663 << meshPart<< ", r'"
3665 << withRequiredGroups << ")";
3668 //=============================================================================
3670 * Return computation progress [0.,1]
3672 //=============================================================================
3674 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3678 return _impl->GetComputeProgress();
3680 SMESH_CATCH( SMESH::doNothing );
3684 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3686 Unexpect aCatch(SALOME_SalomeException);
3688 return _preMeshInfo->NbNodes();
3690 return _impl->NbNodes();
3693 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3695 Unexpect aCatch(SALOME_SalomeException);
3697 return _preMeshInfo->NbElements();
3699 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3702 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3704 Unexpect aCatch(SALOME_SalomeException);
3706 return _preMeshInfo->Nb0DElements();
3708 return _impl->Nb0DElements();
3711 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3713 Unexpect aCatch(SALOME_SalomeException);
3715 return _preMeshInfo->NbBalls();
3717 return _impl->NbBalls();
3720 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3722 Unexpect aCatch(SALOME_SalomeException);
3724 return _preMeshInfo->NbEdges();
3726 return _impl->NbEdges();
3729 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3730 throw(SALOME::SALOME_Exception)
3732 Unexpect aCatch(SALOME_SalomeException);
3734 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3736 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3739 //=============================================================================
3741 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3743 Unexpect aCatch(SALOME_SalomeException);
3745 return _preMeshInfo->NbFaces();
3747 return _impl->NbFaces();
3750 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 return _preMeshInfo->NbTriangles();
3756 return _impl->NbTriangles();
3759 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3763 return _preMeshInfo->NbBiQuadTriangles();
3765 return _impl->NbBiQuadTriangles();
3768 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbQuadrangles();
3774 return _impl->NbQuadrangles();
3777 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbBiQuadQuadrangles();
3783 return _impl->NbBiQuadQuadrangles();
3786 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3788 Unexpect aCatch(SALOME_SalomeException);
3790 return _preMeshInfo->NbPolygons();
3792 return _impl->NbPolygons();
3795 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3801 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3804 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3805 throw(SALOME::SALOME_Exception)
3807 Unexpect aCatch(SALOME_SalomeException);
3809 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3811 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3814 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3815 throw(SALOME::SALOME_Exception)
3817 Unexpect aCatch(SALOME_SalomeException);
3819 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3821 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3824 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3825 throw(SALOME::SALOME_Exception)
3827 Unexpect aCatch(SALOME_SalomeException);
3829 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3831 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3834 //=============================================================================
3836 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3838 Unexpect aCatch(SALOME_SalomeException);
3840 return _preMeshInfo->NbVolumes();
3842 return _impl->NbVolumes();
3845 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3847 Unexpect aCatch(SALOME_SalomeException);
3849 return _preMeshInfo->NbTetras();
3851 return _impl->NbTetras();
3854 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3856 Unexpect aCatch(SALOME_SalomeException);
3858 return _preMeshInfo->NbHexas();
3860 return _impl->NbHexas();
3863 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbTriQuadHexas();
3869 return _impl->NbTriQuadraticHexas();
3872 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 return _preMeshInfo->NbPyramids();
3878 return _impl->NbPyramids();
3881 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbPrisms();
3887 return _impl->NbPrisms();
3890 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 return _preMeshInfo->NbHexPrisms();
3896 return _impl->NbHexagonalPrisms();
3899 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3901 Unexpect aCatch(SALOME_SalomeException);
3903 return _preMeshInfo->NbPolyhedrons();
3905 return _impl->NbPolyhedrons();
3908 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3909 throw(SALOME::SALOME_Exception)
3911 Unexpect aCatch(SALOME_SalomeException);
3913 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3915 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3918 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3919 throw(SALOME::SALOME_Exception)
3921 Unexpect aCatch(SALOME_SalomeException);
3923 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3925 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3928 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3929 throw(SALOME::SALOME_Exception)
3931 Unexpect aCatch(SALOME_SalomeException);
3933 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3935 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3938 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3939 throw(SALOME::SALOME_Exception)
3941 Unexpect aCatch(SALOME_SalomeException);
3943 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3945 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3948 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3949 throw(SALOME::SALOME_Exception)
3951 Unexpect aCatch(SALOME_SalomeException);
3953 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3955 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3958 //=============================================================================
3960 * Returns nb of published sub-meshes
3962 //=============================================================================
3964 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3966 Unexpect aCatch(SALOME_SalomeException);
3967 return _mapSubMesh_i.size();
3970 //=============================================================================
3972 * Dumps mesh into a string
3974 //=============================================================================
3976 char* SMESH_Mesh_i::Dump()
3980 return CORBA::string_dup( os.str().c_str() );
3983 //=============================================================================
3985 * Method of SMESH_IDSource interface
3987 //=============================================================================
3989 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3991 return GetElementsId();
3994 //=============================================================================
3996 * Returns ids of all elements
3998 //=============================================================================
4000 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4001 throw (SALOME::SALOME_Exception)
4003 Unexpect aCatch(SALOME_SalomeException);
4005 _preMeshInfo->FullLoadFromFile();
4007 SMESH::long_array_var aResult = new SMESH::long_array();
4008 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4010 if ( aSMESHDS_Mesh == NULL )
4011 return aResult._retn();
4013 long nbElements = NbElements();
4014 aResult->length( nbElements );
4015 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4016 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4017 aResult[i] = anIt->next()->GetID();
4019 return aResult._retn();
4023 //=============================================================================
4025 * Returns ids of all elements of given type
4027 //=============================================================================
4029 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4030 throw (SALOME::SALOME_Exception)
4032 Unexpect aCatch(SALOME_SalomeException);
4034 _preMeshInfo->FullLoadFromFile();
4036 SMESH::long_array_var aResult = new SMESH::long_array();
4037 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4039 if ( aSMESHDS_Mesh == NULL )
4040 return aResult._retn();
4042 long nbElements = NbElements();
4044 // No sense in returning ids of elements along with ids of nodes:
4045 // when theElemType == SMESH::ALL, return node ids only if
4046 // there are no elements
4047 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4048 return GetNodesId();
4050 aResult->length( nbElements );
4054 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4055 while ( i < nbElements && anIt->more() )
4056 aResult[i++] = anIt->next()->GetID();
4058 aResult->length( i );
4060 return aResult._retn();
4063 //=============================================================================
4065 * Returns ids of all nodes
4067 //=============================================================================
4069 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4070 throw (SALOME::SALOME_Exception)
4072 Unexpect aCatch(SALOME_SalomeException);
4074 _preMeshInfo->FullLoadFromFile();
4076 SMESH::long_array_var aResult = new SMESH::long_array();
4077 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4079 if ( aSMESHDS_Mesh == NULL )
4080 return aResult._retn();
4082 long nbNodes = NbNodes();
4083 aResult->length( nbNodes );
4084 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4085 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4086 aResult[i] = anIt->next()->GetID();
4088 return aResult._retn();
4091 //=============================================================================
4095 //=============================================================================
4097 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4098 throw (SALOME::SALOME_Exception)
4100 SMESH::ElementType type = SMESH::ALL;
4104 _preMeshInfo->FullLoadFromFile();
4106 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4108 SMESH_CATCH( SMESH::throwCorbaException );
4113 //=============================================================================
4117 //=============================================================================
4119 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4120 throw (SALOME::SALOME_Exception)
4123 _preMeshInfo->FullLoadFromFile();
4125 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4127 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4129 return ( SMESH::EntityType ) e->GetEntityType();
4132 //=============================================================================
4136 //=============================================================================
4138 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4139 throw (SALOME::SALOME_Exception)
4142 _preMeshInfo->FullLoadFromFile();
4144 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4146 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4148 return ( SMESH::GeometryType ) e->GetGeomType();
4151 //=============================================================================
4153 * Returns ID of elements for given submesh
4155 //=============================================================================
4156 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4157 throw (SALOME::SALOME_Exception)
4159 SMESH::long_array_var aResult = new SMESH::long_array();
4163 _preMeshInfo->FullLoadFromFile();
4165 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4166 if(!SM) return aResult._retn();
4168 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4169 if(!SDSM) return aResult._retn();
4171 aResult->length(SDSM->NbElements());
4173 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4175 while ( eIt->more() ) {
4176 aResult[i++] = eIt->next()->GetID();
4179 SMESH_CATCH( SMESH::throwCorbaException );
4181 return aResult._retn();
4184 //=============================================================================
4186 * Returns ID of nodes for given submesh
4187 * If param all==true - returns all nodes, else -
4188 * returns only nodes on shapes.
4190 //=============================================================================
4192 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4194 throw (SALOME::SALOME_Exception)
4196 SMESH::long_array_var aResult = new SMESH::long_array();
4200 _preMeshInfo->FullLoadFromFile();
4202 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4203 if(!SM) return aResult._retn();
4205 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4206 if(!SDSM) return aResult._retn();
4209 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4210 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4211 while ( nIt->more() ) {
4212 const SMDS_MeshNode* elem = nIt->next();
4213 theElems.insert( elem->GetID() );
4216 else { // all nodes of submesh elements
4217 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4218 while ( eIt->more() ) {
4219 const SMDS_MeshElement* anElem = eIt->next();
4220 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4221 while ( nIt->more() ) {
4222 const SMDS_MeshElement* elem = nIt->next();
4223 theElems.insert( elem->GetID() );
4228 aResult->length(theElems.size());
4229 set<int>::iterator itElem;
4231 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4232 aResult[i++] = *itElem;
4234 SMESH_CATCH( SMESH::throwCorbaException );
4236 return aResult._retn();
4239 //=============================================================================
4241 * Returns type of elements for given submesh
4243 //=============================================================================
4245 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4246 throw (SALOME::SALOME_Exception)
4248 SMESH::ElementType type = SMESH::ALL;
4252 _preMeshInfo->FullLoadFromFile();
4254 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4255 if(!SM) return SMESH::ALL;
4257 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4258 if(!SDSM) return SMESH::ALL;
4260 if(SDSM->NbElements()==0)
4261 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4263 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4264 const SMDS_MeshElement* anElem = eIt->next();
4266 type = ( SMESH::ElementType ) anElem->GetType();
4268 SMESH_CATCH( SMESH::throwCorbaException );
4274 //=============================================================================
4276 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4278 //=============================================================================
4280 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4283 _preMeshInfo->FullLoadFromFile();
4285 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4286 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4291 //=============================================================================
4293 * Get XYZ coordinates of node as list of double
4294 * If there is not node for given ID - returns empty list
4296 //=============================================================================
4298 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4301 _preMeshInfo->FullLoadFromFile();
4303 SMESH::double_array_var aResult = new SMESH::double_array();
4304 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4305 if ( aSMESHDS_Mesh == NULL )
4306 return aResult._retn();
4309 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4311 return aResult._retn();
4315 aResult[0] = aNode->X();
4316 aResult[1] = aNode->Y();
4317 aResult[2] = aNode->Z();
4318 return aResult._retn();
4322 //=============================================================================
4324 * For given node returns list of IDs of inverse elements
4325 * If there is not node for given ID - returns empty list
4327 //=============================================================================
4329 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4332 _preMeshInfo->FullLoadFromFile();
4334 SMESH::long_array_var aResult = new SMESH::long_array();
4335 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4336 if ( aSMESHDS_Mesh == NULL )
4337 return aResult._retn();
4340 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4342 return aResult._retn();
4344 // find inverse elements
4345 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4346 aResult->length( aNode->NbInverseElements() );
4347 for( int i = 0; eIt->more(); ++i )
4349 const SMDS_MeshElement* elem = eIt->next();
4350 aResult[ i ] = elem->GetID();
4352 return aResult._retn();
4355 //=============================================================================
4357 * \brief Return position of a node on shape
4359 //=============================================================================
4361 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4364 _preMeshInfo->FullLoadFromFile();
4366 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4367 aNodePosition->shapeID = 0;
4368 aNodePosition->shapeType = GEOM::SHAPE;
4370 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4371 if ( !mesh ) return aNodePosition;
4373 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4375 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4377 aNodePosition->shapeID = aNode->getshapeId();
4378 switch ( pos->GetTypeOfPosition() ) {
4380 aNodePosition->shapeType = GEOM::EDGE;
4381 aNodePosition->params.length(1);
4382 aNodePosition->params[0] =
4383 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4386 aNodePosition->shapeType = GEOM::FACE;
4387 aNodePosition->params.length(2);
4388 aNodePosition->params[0] =
4389 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4390 aNodePosition->params[1] =
4391 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4393 case SMDS_TOP_VERTEX:
4394 aNodePosition->shapeType = GEOM::VERTEX;
4396 case SMDS_TOP_3DSPACE:
4397 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4398 aNodePosition->shapeType = GEOM::SOLID;
4399 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4400 aNodePosition->shapeType = GEOM::SHELL;
4406 return aNodePosition;
4409 //=============================================================================
4411 * \brief Return position of an element on shape
4413 //=============================================================================
4415 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4418 _preMeshInfo->FullLoadFromFile();
4420 SMESH::ElementPosition anElementPosition;
4421 anElementPosition.shapeID = 0;
4422 anElementPosition.shapeType = GEOM::SHAPE;
4424 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4425 if ( !mesh ) return anElementPosition;
4427 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4429 anElementPosition.shapeID = anElem->getshapeId();
4430 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4431 if ( !aSp.IsNull() ) {
4432 switch ( aSp.ShapeType() ) {
4434 anElementPosition.shapeType = GEOM::EDGE;
4437 anElementPosition.shapeType = GEOM::FACE;
4440 anElementPosition.shapeType = GEOM::VERTEX;
4443 anElementPosition.shapeType = GEOM::SOLID;
4446 anElementPosition.shapeType = GEOM::SHELL;
4452 return anElementPosition;
4455 //=============================================================================
4457 * If given element is node returns IDs of shape from position
4458 * If there is not node for given ID - returns -1
4460 //=============================================================================
4462 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4465 _preMeshInfo->FullLoadFromFile();
4467 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4468 if ( aSMESHDS_Mesh == NULL )
4472 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4474 return aNode->getshapeId();
4481 //=============================================================================
4483 * For given element returns ID of result shape after
4484 * ::FindShape() from SMESH_MeshEditor
4485 * If there is not element for given ID - returns -1
4487 //=============================================================================
4489 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4492 _preMeshInfo->FullLoadFromFile();
4494 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4495 if ( aSMESHDS_Mesh == NULL )
4498 // try to find element
4499 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4503 ::SMESH_MeshEditor aMeshEditor(_impl);
4504 int index = aMeshEditor.FindShape( elem );
4512 //=============================================================================
4514 * Returns number of nodes for given element
4515 * If there is not element for given ID - returns -1
4517 //=============================================================================
4519 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4522 _preMeshInfo->FullLoadFromFile();
4524 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4525 if ( aSMESHDS_Mesh == NULL ) return -1;
4526 // try to find element
4527 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4528 if(!elem) return -1;
4529 return elem->NbNodes();
4533 //=============================================================================
4535 * Returns ID of node by given index for given element
4536 * If there is not element for given ID - returns -1
4537 * If there is not node for given index - returns -2
4539 //=============================================================================
4541 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4544 _preMeshInfo->FullLoadFromFile();
4546 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4547 if ( aSMESHDS_Mesh == NULL ) return -1;
4548 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4549 if(!elem) return -1;
4550 if( index>=elem->NbNodes() || index<0 ) return -1;
4551 return elem->GetNode(index)->GetID();
4554 //=============================================================================
4556 * Returns IDs of nodes of given element
4558 //=============================================================================
4560 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4563 _preMeshInfo->FullLoadFromFile();
4565 SMESH::long_array_var aResult = new SMESH::long_array();
4566 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4568 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4570 aResult->length( elem->NbNodes() );
4571 for ( int i = 0; i < elem->NbNodes(); ++i )
4572 aResult[ i ] = elem->GetNode( i )->GetID();
4575 return aResult._retn();
4578 //=============================================================================
4580 * Returns true if given node is medium node
4581 * in given quadratic element
4583 //=============================================================================
4585 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4588 _preMeshInfo->FullLoadFromFile();
4590 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4591 if ( aSMESHDS_Mesh == NULL ) return false;
4593 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4594 if(!aNode) return false;
4595 // try to find element
4596 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4597 if(!elem) return false;
4599 return elem->IsMediumNode(aNode);
4603 //=============================================================================
4605 * Returns true if given node is medium node
4606 * in one of quadratic elements
4608 //=============================================================================
4610 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4611 SMESH::ElementType theElemType)
4614 _preMeshInfo->FullLoadFromFile();
4616 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4617 if ( aSMESHDS_Mesh == NULL ) return false;
4620 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4621 if(!aNode) return false;
4623 SMESH_MesherHelper aHelper( *(_impl) );
4625 SMDSAbs_ElementType aType;
4626 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4627 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4628 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4629 else aType = SMDSAbs_All;
4631 return aHelper.IsMedium(aNode,aType);
4635 //=============================================================================
4637 * Returns number of edges for given element
4639 //=============================================================================
4641 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4644 _preMeshInfo->FullLoadFromFile();
4646 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4647 if ( aSMESHDS_Mesh == NULL ) return -1;
4648 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4649 if(!elem) return -1;
4650 return elem->NbEdges();
4654 //=============================================================================
4656 * Returns number of faces for given element
4658 //=============================================================================
4660 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4663 _preMeshInfo->FullLoadFromFile();
4665 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4666 if ( aSMESHDS_Mesh == NULL ) return -1;
4667 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4668 if(!elem) return -1;
4669 return elem->NbFaces();
4672 //=======================================================================
4673 //function : GetElemFaceNodes
4674 //purpose : Returns nodes of given face (counted from zero) for given element.
4675 //=======================================================================
4677 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4678 CORBA::Short faceIndex)
4681 _preMeshInfo->FullLoadFromFile();
4683 SMESH::long_array_var aResult = new SMESH::long_array();
4684 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4686 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4688 SMDS_VolumeTool vtool( elem );
4689 if ( faceIndex < vtool.NbFaces() )
4691 aResult->length( vtool.NbFaceNodes( faceIndex ));
4692 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4693 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4694 aResult[ i ] = nn[ i ]->GetID();
4698 return aResult._retn();
4701 //=======================================================================
4702 //function : GetElemFaceNodes
4703 //purpose : Returns three components of normal of given mesh face.
4704 //=======================================================================
4706 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4707 CORBA::Boolean normalized)
4710 _preMeshInfo->FullLoadFromFile();
4712 SMESH::double_array_var aResult = new SMESH::double_array();
4714 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4717 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4719 aResult->length( 3 );
4720 aResult[ 0 ] = normal.X();
4721 aResult[ 1 ] = normal.Y();
4722 aResult[ 2 ] = normal.Z();
4725 return aResult._retn();
4728 //=======================================================================
4729 //function : FindElementByNodes
4730 //purpose : Returns an element based on all given nodes.
4731 //=======================================================================
4733 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4736 _preMeshInfo->FullLoadFromFile();
4738 CORBA::Long elemID(0);
4739 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4741 vector< const SMDS_MeshNode * > nn( nodes.length() );
4742 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4743 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4746 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4747 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4748 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4749 _impl->NbVolumes( ORDER_QUADRATIC )))
4750 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4752 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4757 //=============================================================================
4759 * Returns true if given element is polygon
4761 //=============================================================================
4763 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4766 _preMeshInfo->FullLoadFromFile();
4768 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4769 if ( aSMESHDS_Mesh == NULL ) return false;
4770 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4771 if(!elem) return false;
4772 return elem->IsPoly();
4776 //=============================================================================
4778 * Returns true if given element is quadratic
4780 //=============================================================================
4782 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4785 _preMeshInfo->FullLoadFromFile();
4787 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4788 if ( aSMESHDS_Mesh == NULL ) return false;
4789 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4790 if(!elem) return false;
4791 return elem->IsQuadratic();
4794 //=============================================================================
4796 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4798 //=============================================================================
4800 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4803 _preMeshInfo->FullLoadFromFile();
4805 if ( const SMDS_BallElement* ball =
4806 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4807 return ball->GetDiameter();
4812 //=============================================================================
4814 * Returns bary center for given element
4816 //=============================================================================
4818 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4821 _preMeshInfo->FullLoadFromFile();
4823 SMESH::double_array_var aResult = new SMESH::double_array();
4824 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4825 if ( aSMESHDS_Mesh == NULL )
4826 return aResult._retn();
4828 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4830 return aResult._retn();
4832 if(elem->GetType()==SMDSAbs_Volume) {
4833 SMDS_VolumeTool aTool;
4834 if(aTool.Set(elem)) {
4836 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4841 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4843 double x=0., y=0., z=0.;
4844 for(; anIt->more(); ) {
4846 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4860 return aResult._retn();
4863 //================================================================================
4865 * \brief Create a group of elements preventing computation of a sub-shape
4867 //================================================================================
4869 SMESH::ListOfGroups*
4870 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4871 const char* theGroupName )
4872 throw ( SALOME::SALOME_Exception )
4874 Unexpect aCatch(SALOME_SalomeException);
4876 if ( !theGroupName || strlen( theGroupName) == 0 )
4877 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4879 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4880 ::SMESH_MeshEditor::ElemFeatures elemType;
4882 // submesh by subshape id
4883 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4884 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4887 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4888 if ( error && !error->myBadElements.empty())
4890 // sort bad elements by type
4891 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4892 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4893 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4894 for ( ; elemIt != elemEnd; ++elemIt )
4896 const SMDS_MeshElement* elem = *elemIt;
4897 if ( !elem ) continue;
4899 if ( elem->GetID() < 1 )
4901 // elem is a temporary element, make a real element
4902 vector< const SMDS_MeshNode* > nodes;
4903 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4904 while ( nIt->more() && elem )
4906 nodes.push_back( nIt->next() );
4907 if ( nodes.back()->GetID() < 1 )
4908 elem = 0; // a temporary element on temporary nodes
4912 ::SMESH_MeshEditor editor( _impl );
4913 elem = editor.AddElement( nodes, elemType.Init( elem ));
4917 elemsByType[ elem->GetType() ].push_back( elem );
4920 // how many groups to create?
4922 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4923 nbTypes += int( !elemsByType[ i ].empty() );
4924 groups->length( nbTypes );
4927 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4929 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4930 if ( elems.empty() ) continue;
4932 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4933 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4935 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4936 SMESH::SMESH_Mesh_var mesh = _this();
4937 SALOMEDS::SObject_wrap aSO =
4938 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4939 GEOM::GEOM_Object::_nil(), theGroupName);
4941 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4942 if ( !grp_i ) continue;
4944 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4945 for ( size_t iE = 0; iE < elems.size(); ++iE )
4946 grpDS->SMDSGroup().Add( elems[ iE ]);
4951 return groups._retn();
4954 //=============================================================================
4956 * Create and publish group servants if any groups were imported or created anyhow
4958 //=============================================================================
4960 void SMESH_Mesh_i::CreateGroupServants()
4962 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4963 SMESH::SMESH_Mesh_var aMesh = _this();
4966 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4967 while ( groupIt->more() )
4969 ::SMESH_Group* group = groupIt->next();
4970 int anId = group->GetGroupDS()->GetID();
4972 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4973 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4975 addedIDs.insert( anId );
4977 SMESH_GroupBase_i* aGroupImpl;
4979 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4980 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4982 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4983 shape = groupOnGeom->GetShape();
4986 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4989 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4990 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4991 aGroupImpl->Register();
4993 // register CORBA object for persistence
4994 int nextId = _gen_i->RegisterObject( groupVar );
4995 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4996 else { nextId = 0; } // avoid "unused variable" warning in release mode
4998 // publishing the groups in the study
4999 if ( !aStudy->_is_nil() ) {
5000 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5001 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5004 if ( !addedIDs.empty() )
5007 set<int>::iterator id = addedIDs.begin();
5008 for ( ; id != addedIDs.end(); ++id )
5010 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5011 int i = std::distance( _mapGroups.begin(), it );
5012 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5017 //=============================================================================
5019 * \brief Return groups cantained in _mapGroups by their IDs
5021 //=============================================================================
5023 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5025 int nbGroups = groupIDs.size();
5026 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5027 aList->length( nbGroups );
5029 list<int>::const_iterator ids = groupIDs.begin();
5030 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5032 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5033 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5034 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5036 aList->length( nbGroups );
5037 return aList._retn();
5040 //=============================================================================
5042 * \brief Return information about imported file
5044 //=============================================================================
5046 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5048 SMESH::MedFileInfo_var res( _medFileInfo );
5049 if ( !res.operator->() ) {
5050 res = new SMESH::MedFileInfo;
5052 res->fileSize = res->major = res->minor = res->release = -1;
5057 //=============================================================================
5059 * \brief Pass names of mesh groups from study to mesh DS
5061 //=============================================================================
5063 void SMESH_Mesh_i::checkGroupNames()
5065 int nbGrp = NbGroups();
5069 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5070 if ( aStudy->_is_nil() )
5071 return; // nothing to do
5073 SMESH::ListOfGroups* grpList = 0;
5074 // avoid dump of "GetGroups"
5076 // store python dump into a local variable inside local scope
5077 SMESH::TPythonDump pDump; // do not delete this line of code
5078 grpList = GetGroups();
5081 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5082 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5085 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5086 if ( aGrpSO->_is_nil() )
5088 // correct name of the mesh group if necessary
5089 const char* guiName = aGrpSO->GetName();
5090 if ( strcmp(guiName, aGrp->GetName()) )
5091 aGrp->SetName( guiName );
5095 //=============================================================================
5097 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5099 //=============================================================================
5100 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5102 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5106 //=============================================================================
5108 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5110 //=============================================================================
5112 char* SMESH_Mesh_i::GetParameters()
5114 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5117 //=============================================================================
5119 * \brief Returns list of notebook variables used for last Mesh operation
5121 //=============================================================================
5122 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5124 SMESH::string_array_var aResult = new SMESH::string_array();
5125 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5127 CORBA::String_var aParameters = GetParameters();
5128 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5129 if ( !aStudy->_is_nil()) {
5130 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5131 if ( aSections->length() > 0 ) {
5132 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5133 aResult->length( aVars.length() );
5134 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5135 aResult[i] = CORBA::string_dup( aVars[i] );
5139 return aResult._retn();
5142 //=======================================================================
5143 //function : GetTypes
5144 //purpose : Returns types of elements it contains
5145 //=======================================================================
5147 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5150 return _preMeshInfo->GetTypes();
5152 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5156 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5157 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5158 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5159 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5160 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5161 if (_impl->NbNodes() &&
5162 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5163 types->length( nbTypes );
5165 return types._retn();
5168 //=======================================================================
5169 //function : GetMesh
5170 //purpose : Returns self
5171 //=======================================================================
5173 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5175 return SMESH::SMESH_Mesh::_duplicate( _this() );
5178 //=======================================================================
5179 //function : IsMeshInfoCorrect
5180 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5181 // * happen if mesh data is not yet fully loaded from the file of study.
5182 //=======================================================================
5184 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5186 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5189 //=============================================================================
5191 * \brief Returns number of mesh elements per each \a EntityType
5193 //=============================================================================
5195 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5198 return _preMeshInfo->GetMeshInfo();
5200 SMESH::long_array_var aRes = new SMESH::long_array();
5201 aRes->length(SMESH::Entity_Last);
5202 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5204 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5206 return aRes._retn();
5207 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5208 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5209 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5210 return aRes._retn();
5213 //=============================================================================
5215 * \brief Returns number of mesh elements per each \a ElementType
5217 //=============================================================================
5219 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5221 SMESH::long_array_var aRes = new SMESH::long_array();
5222 aRes->length(SMESH::NB_ELEMENT_TYPES);
5223 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5226 const SMDS_MeshInfo* meshInfo = 0;
5228 meshInfo = _preMeshInfo;
5229 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5230 meshInfo = & meshDS->GetMeshInfo();
5233 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5234 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5236 return aRes._retn();
5239 //=============================================================================
5241 * Collect statistic of mesh elements given by iterator
5243 //=============================================================================
5245 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5246 SMESH::long_array& theInfo)
5248 if (!theItr) return;
5249 while (theItr->more())
5250 theInfo[ theItr->next()->GetEntityType() ]++;
5252 //=============================================================================
5254 * Returns mesh unstructed grid information.
5256 //=============================================================================
5258 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5260 SALOMEDS::TMPFile_var SeqFile;
5261 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5262 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5264 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5265 aWriter->WriteToOutputStringOn();
5266 aWriter->SetInputData(aGrid);
5267 aWriter->SetFileTypeToBinary();
5269 char* str = aWriter->GetOutputString();
5270 int size = aWriter->GetOutputStringLength();
5272 //Allocate octect buffer of required size
5273 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5274 //Copy ostrstream content to the octect buffer
5275 memcpy(OctetBuf, str, size);
5276 //Create and return TMPFile
5277 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5281 return SeqFile._retn();
5284 //=============================================================================
5285 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5286 * SMESH::ElementType type) */
5288 using namespace SMESH::Controls;
5289 //-----------------------------------------------------------------------------
5290 struct PredicateIterator : public SMDS_ElemIterator
5292 SMDS_ElemIteratorPtr _elemIter;
5293 PredicatePtr _predicate;
5294 const SMDS_MeshElement* _elem;
5296 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5297 PredicatePtr predicate):
5298 _elemIter(iterator), _predicate(predicate)
5306 virtual const SMDS_MeshElement* next()
5308 const SMDS_MeshElement* res = _elem;
5310 while ( _elemIter->more() && !_elem )
5312 _elem = _elemIter->next();
5313 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5320 //-----------------------------------------------------------------------------
5321 struct IDSourceIterator : public SMDS_ElemIterator
5323 const CORBA::Long* _idPtr;
5324 const CORBA::Long* _idEndPtr;
5325 SMESH::long_array_var _idArray;
5326 const SMDS_Mesh* _mesh;
5327 const SMDSAbs_ElementType _type;
5328 const SMDS_MeshElement* _elem;
5330 IDSourceIterator( const SMDS_Mesh* mesh,
5331 const CORBA::Long* ids,
5333 SMDSAbs_ElementType type):
5334 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5336 if ( _idPtr && nbIds && _mesh )
5339 IDSourceIterator( const SMDS_Mesh* mesh,
5340 SMESH::long_array* idArray,
5341 SMDSAbs_ElementType type):
5342 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5344 if ( idArray && _mesh )
5346 _idPtr = &_idArray[0];
5347 _idEndPtr = _idPtr + _idArray->length();
5355 virtual const SMDS_MeshElement* next()
5357 const SMDS_MeshElement* res = _elem;
5359 while ( _idPtr < _idEndPtr && !_elem )
5361 if ( _type == SMDSAbs_Node )
5363 _elem = _mesh->FindNode( *_idPtr++ );
5365 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5366 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5374 //-----------------------------------------------------------------------------
5376 struct NodeOfElemIterator : public SMDS_ElemIterator
5378 TColStd_MapOfInteger _checkedNodeIDs;
5379 SMDS_ElemIteratorPtr _elemIter;
5380 SMDS_ElemIteratorPtr _nodeIter;
5381 const SMDS_MeshElement* _node;
5383 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5385 if ( _elemIter && _elemIter->more() )
5387 _nodeIter = _elemIter->next()->nodesIterator();
5395 virtual const SMDS_MeshElement* next()
5397 const SMDS_MeshElement* res = _node;
5399 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5401 if ( _nodeIter->more() )
5403 _node = _nodeIter->next();
5404 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5409 _nodeIter = _elemIter->next()->nodesIterator();
5417 //=============================================================================
5419 * Return iterator on elements of given type in given object
5421 //=============================================================================
5423 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5424 SMESH::ElementType theType)
5426 SMDS_ElemIteratorPtr elemIt;
5427 bool typeOK = ( theType == SMESH::ALL );
5428 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5430 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5431 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5432 if ( !mesh_i ) return elemIt;
5433 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5435 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5437 elemIt = meshDS->elementsIterator( elemType );
5440 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5442 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5445 elemIt = sm->GetElements();
5446 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5448 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5449 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5453 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5455 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5456 if ( groupDS && ( elemType == groupDS->GetType() ||
5457 elemType == SMDSAbs_Node ||
5458 elemType == SMDSAbs_All ))
5460 elemIt = groupDS->GetElements();
5461 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5464 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5466 if ( filter_i->GetElementType() == theType ||
5467 elemType == SMDSAbs_Node ||
5468 elemType == SMDSAbs_All)
5470 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5471 if ( pred_i && pred_i->GetPredicate() )
5473 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5474 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5475 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5476 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5482 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5483 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5484 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5486 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5489 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5490 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5494 SMESH::long_array_var ids = theObject->GetIDs();
5495 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5497 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5500 if ( elemIt && elemIt->more() && !typeOK )
5502 if ( elemType == SMDSAbs_Node )
5504 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5508 elemIt = SMDS_ElemIteratorPtr();
5514 //=============================================================================
5515 namespace // Finding concurrent hypotheses
5516 //=============================================================================
5520 * \brief mapping of mesh dimension into shape type
5522 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5524 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5526 case 0: aType = TopAbs_VERTEX; break;
5527 case 1: aType = TopAbs_EDGE; break;
5528 case 2: aType = TopAbs_FACE; break;
5530 default:aType = TopAbs_SOLID; break;
5535 //-----------------------------------------------------------------------------
5537 * \brief Internal structure used to find concurent submeshes
5539 * It represents a pair < submesh, concurent dimension >, where
5540 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5541 * with another submesh. In other words, it is dimension of a hypothesis assigned
5548 int _dim; //!< a dimension the algo can build (concurrent dimension)
5549 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5550 TopTools_MapOfShape _shapeMap;
5551 SMESH_subMesh* _subMesh;
5552 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5554 //-----------------------------------------------------------------------------
5555 // Return the algorithm
5556 const SMESH_Algo* GetAlgo() const
5557 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5559 //-----------------------------------------------------------------------------
5561 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5563 const TopoDS_Shape& theShape)
5565 _subMesh = (SMESH_subMesh*)theSubMesh;
5566 SetShape( theDim, theShape );
5569 //-----------------------------------------------------------------------------
5571 void SetShape(const int theDim,
5572 const TopoDS_Shape& theShape)
5575 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5576 if (_dim >= _ownDim)
5577 _shapeMap.Add( theShape );
5579 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5580 for( ; anExp.More(); anExp.Next() )
5581 _shapeMap.Add( anExp.Current() );
5585 //-----------------------------------------------------------------------------
5586 //! Check sharing of sub-shapes
5587 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5588 const TopTools_MapOfShape& theToFind,
5589 const TopAbs_ShapeEnum theType)
5591 bool isShared = false;
5592 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5593 for (; !isShared && anItr.More(); anItr.Next() )
5595 const TopoDS_Shape aSubSh = anItr.Key();
5596 // check for case when concurrent dimensions are same
5597 isShared = theToFind.Contains( aSubSh );
5598 // check for sub-shape with concurrent dimension
5599 TopExp_Explorer anExp( aSubSh, theType );
5600 for ( ; !isShared && anExp.More(); anExp.Next() )
5601 isShared = theToFind.Contains( anExp.Current() );
5606 //-----------------------------------------------------------------------------
5607 //! check algorithms
5608 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5609 const SMESHDS_Hypothesis* theA2)
5611 if ( !theA1 || !theA2 ||
5612 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5613 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5614 return false; // one of the hypothesis is not algorithm
5615 // check algorithm names (should be equal)
5616 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5620 //-----------------------------------------------------------------------------
5621 //! Check if sub-shape hypotheses are concurrent
5622 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5624 if ( _subMesh == theOther->_subMesh )
5625 return false; // same sub-shape - should not be
5627 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5628 // any of the two submeshes is not on COMPOUND shape )
5629 // -> no concurrency
5630 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5631 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5632 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5633 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5634 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5637 // bool checkSubShape = ( _dim >= theOther->_dim )
5638 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5639 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5640 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5641 if ( !checkSubShape )
5644 // check algorithms to be same
5645 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5646 return true; // different algorithms -> concurrency !
5648 // check hypothesises for concurrence (skip first as algorithm)
5650 // pointers should be same, because it is referened from mesh hypothesis partition
5651 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5652 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5653 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5654 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5656 // the submeshes are concurrent if their algorithms has different parameters
5657 return nbSame != (int)theOther->_hypotheses.size() - 1;
5660 // Return true if algorithm of this SMESH_DimHyp is used if no
5661 // sub-mesh order is imposed by the user
5662 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5664 // NeedDiscreteBoundary() algo has a higher priority
5665 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5666 theOther->GetAlgo()->NeedDiscreteBoundary() )
5667 return !this->GetAlgo()->NeedDiscreteBoundary();
5669 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5672 }; // end of SMESH_DimHyp
5673 //-----------------------------------------------------------------------------
5675 typedef list<const SMESH_DimHyp*> TDimHypList;
5677 //-----------------------------------------------------------------------------
5679 void addDimHypInstance(const int theDim,
5680 const TopoDS_Shape& theShape,
5681 const SMESH_Algo* theAlgo,
5682 const SMESH_subMesh* theSubMesh,
5683 const list <const SMESHDS_Hypothesis*>& theHypList,
5684 TDimHypList* theDimHypListArr )
5686 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5687 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5688 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5689 dimHyp->_hypotheses.push_front(theAlgo);
5690 listOfdimHyp.push_back( dimHyp );
5693 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5694 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5695 theHypList.begin(), theHypList.end() );
5698 //-----------------------------------------------------------------------------
5699 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5700 TDimHypList& theListOfConcurr)
5702 if ( theListOfConcurr.empty() )
5704 theListOfConcurr.push_back( theDimHyp );
5708 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5709 while ( hypIt != theListOfConcurr.end() &&
5710 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5712 theListOfConcurr.insert( hypIt, theDimHyp );
5716 //-----------------------------------------------------------------------------
5717 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5718 const TDimHypList& theListOfDimHyp,
5719 TDimHypList& theListOfConcurrHyp,
5720 set<int>& theSetOfConcurrId )
5722 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5723 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5725 const SMESH_DimHyp* curDimHyp = *rIt;
5726 if ( curDimHyp == theDimHyp )
5727 break; // meet own dimHyp pointer in same dimension
5729 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5730 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5732 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5737 //-----------------------------------------------------------------------------
5738 void unionLists(TListOfInt& theListOfId,
5739 TListOfListOfInt& theListOfListOfId,
5742 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5743 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5745 continue; //skip already treated lists
5746 // check if other list has any same submesh object
5747 TListOfInt& otherListOfId = *it;
5748 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5749 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5752 // union two lists (from source into target)
5753 TListOfInt::iterator it2 = otherListOfId.begin();
5754 for ( ; it2 != otherListOfId.end(); it2++ ) {
5755 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5756 theListOfId.push_back(*it2);
5758 // clear source list
5759 otherListOfId.clear();
5762 //-----------------------------------------------------------------------------
5764 //! free memory allocated for dimension-hypothesis objects
5765 void removeDimHyps( TDimHypList* theArrOfList )
5767 for (int i = 0; i < 4; i++ ) {
5768 TDimHypList& listOfdimHyp = theArrOfList[i];
5769 TDimHypList::const_iterator it = listOfdimHyp.begin();
5770 for ( ; it != listOfdimHyp.end(); it++ )
5775 //-----------------------------------------------------------------------------
5777 * \brief find common submeshes with given submesh
5778 * \param theSubMeshList list of already collected submesh to check
5779 * \param theSubMesh given submesh to intersect with other
5780 * \param theCommonSubMeshes collected common submeshes
5782 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5783 const SMESH_subMesh* theSubMesh,
5784 set<const SMESH_subMesh*>& theCommon )
5788 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5789 for ( ; it != theSubMeshList.end(); it++ )
5790 theSubMesh->FindIntersection( *it, theCommon );
5791 theSubMeshList.push_back( theSubMesh );
5792 //theCommon.insert( theSubMesh );
5795 //-----------------------------------------------------------------------------
5796 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5798 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5799 for ( ; listsIt != smLists.end(); ++listsIt )
5801 const TListOfInt& smIDs = *listsIt;
5802 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5810 //=============================================================================
5812 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5814 //=============================================================================
5816 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5818 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5819 if ( isSubMeshInList( submeshID, anOrder ))
5822 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5823 return isSubMeshInList( submeshID, allConurrent );
5826 //=============================================================================
5828 * \brief Return submesh objects list in meshing order
5830 //=============================================================================
5832 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5834 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5836 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5838 return aResult._retn();
5840 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5841 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5842 anOrder.splice( anOrder.end(), allConurrent );
5845 TListOfListOfInt::iterator listIt = anOrder.begin();
5846 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5847 unionLists( *listIt, anOrder, listIndx + 1 );
5849 // convert submesh ids into interface instances
5850 // and dump command into python
5851 convertMeshOrder( anOrder, aResult, false );
5853 return aResult._retn();
5856 //=============================================================================
5858 * \brief Finds concurrent sub-meshes
5860 //=============================================================================
5862 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5864 TListOfListOfInt anOrder;
5865 ::SMESH_Mesh& mesh = GetImpl();
5867 // collect submeshes and detect concurrent algorithms and hypothesises
5868 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5870 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5871 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5872 ::SMESH_subMesh* sm = (*i_sm).second;
5874 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5876 // list of assigned hypothesises
5877 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5878 // Find out dimensions where the submesh can be concurrent.
5879 // We define the dimensions by algo of each of hypotheses in hypList
5880 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5881 for( ; hypIt != hypList.end(); hypIt++ ) {
5882 SMESH_Algo* anAlgo = 0;
5883 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5884 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5885 // hyp it-self is algo
5886 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5888 // try to find algorithm with help of sub-shapes
5889 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5890 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5891 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5894 continue; // no algorithm assigned to a current submesh
5896 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5897 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5899 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5900 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5901 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5903 } // end iterations on submesh
5905 // iterate on created dimension-hypotheses and check for concurrents
5906 for ( int i = 0; i < 4; i++ ) {
5907 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5908 // check for concurrents in own and other dimensions (step-by-step)
5909 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5910 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5911 const SMESH_DimHyp* dimHyp = *dhIt;
5912 TDimHypList listOfConcurr;
5913 set<int> setOfConcurrIds;
5914 // looking for concurrents and collect into own list
5915 for ( int j = i; j < 4; j++ )
5916 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5917 // check if any concurrents found
5918 if ( listOfConcurr.size() > 0 ) {
5919 // add own submesh to list of concurrent
5920 addInOrderOfPriority( dimHyp, listOfConcurr );
5921 list<int> listOfConcurrIds;
5922 TDimHypList::iterator hypIt = listOfConcurr.begin();
5923 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5924 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5925 anOrder.push_back( listOfConcurrIds );
5930 removeDimHyps(dimHypListArr);
5932 // now, minimise the number of concurrent groups
5933 // Here we assume that lists of submeshes can have same submesh
5934 // in case of multi-dimension algorithms, as result
5935 // list with common submesh has to be united into one list
5937 TListOfListOfInt::iterator listIt = anOrder.begin();
5938 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5939 unionLists( *listIt, anOrder, listIndx + 1 );
5945 //=============================================================================
5947 * \brief Set submesh object order
5948 * \param theSubMeshArray submesh array order
5950 //=============================================================================
5952 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5955 _preMeshInfo->ForgetOrLoad();
5958 ::SMESH_Mesh& mesh = GetImpl();
5960 TPythonDump aPythonDump; // prevent dump of called methods
5961 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5963 TListOfListOfInt subMeshOrder;
5964 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5966 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5967 TListOfInt subMeshIds;
5969 aPythonDump << ", ";
5970 aPythonDump << "[ ";
5971 // Collect subMeshes which should be clear
5972 // do it list-by-list, because modification of submesh order
5973 // take effect between concurrent submeshes only
5974 set<const SMESH_subMesh*> subMeshToClear;
5975 list<const SMESH_subMesh*> subMeshList;
5976 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5978 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5980 aPythonDump << ", ";
5981 aPythonDump << subMesh;
5982 subMeshIds.push_back( subMesh->GetId() );
5983 // detect common parts of submeshes
5984 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5985 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5987 aPythonDump << " ]";
5988 subMeshOrder.push_back( subMeshIds );
5990 // clear collected submeshes
5991 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5992 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5993 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5994 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5996 aPythonDump << " ])";
5998 mesh.SetMeshOrder( subMeshOrder );
6004 //=============================================================================
6006 * \brief Convert submesh ids into submesh interfaces
6008 //=============================================================================
6010 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6011 SMESH::submesh_array_array& theResOrder,
6012 const bool theIsDump)
6014 int nbSet = theIdsOrder.size();
6015 TPythonDump aPythonDump; // prevent dump of called methods
6017 aPythonDump << "[ ";
6018 theResOrder.length(nbSet);
6019 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6021 for( ; it != theIdsOrder.end(); it++ ) {
6022 // translate submesh identificators into submesh objects
6023 // takeing into account real number of concurrent lists
6024 const TListOfInt& aSubOrder = (*it);
6025 if (!aSubOrder.size())
6028 aPythonDump << "[ ";
6029 // convert shape indeces into interfaces
6030 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6031 aResSubSet->length(aSubOrder.size());
6032 TListOfInt::const_iterator subIt = aSubOrder.begin();
6034 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6035 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6037 SMESH::SMESH_subMesh_var subMesh =
6038 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6041 aPythonDump << ", ";
6042 aPythonDump << subMesh;
6044 aResSubSet[ j++ ] = subMesh;
6047 aPythonDump << " ]";
6049 theResOrder[ listIndx++ ] = aResSubSet;
6051 // correct number of lists
6052 theResOrder.length( listIndx );
6055 // finilise python dump
6056 aPythonDump << " ]";
6057 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6061 //================================================================================
6063 // Implementation of SMESH_MeshPartDS
6065 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6066 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6068 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6069 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 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6142 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6144 typedef SMDS_SetIterator
6145 <const SMDS_MeshElement*,
6146 TIDSortedElemSet::const_iterator,
6147 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6148 SMDS_MeshElement::GeomFilter
6151 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6153 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6154 _elements[type].end(),
6155 SMDS_MeshElement::GeomFilter( geomType )));
6157 // -------------------------------------------------------------------------------------
6158 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6160 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6162 typedef SMDS_SetIterator
6163 <const SMDS_MeshElement*,
6164 TIDSortedElemSet::const_iterator,
6165 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6166 SMDS_MeshElement::EntityFilter
6169 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6171 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6172 _elements[type].end(),
6173 SMDS_MeshElement::EntityFilter( entity )));
6175 // -------------------------------------------------------------------------------------
6176 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6178 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6179 if ( type == SMDSAbs_All && !_meshDS )
6181 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6183 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6184 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6186 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6188 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6189 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6191 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6192 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6194 // -------------------------------------------------------------------------------------
6195 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6196 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6198 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6199 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6200 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6202 // -------------------------------------------------------------------------------------
6203 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6204 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6205 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6206 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6207 #undef _GET_ITER_DEFINE
6209 // END Implementation of SMESH_MeshPartDS
6211 //================================================================================