1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
113 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cashed shapes if no more meshes remain; (the cash is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
243 if ( study->_is_nil() ) break;
244 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Return false if the mesh is not yet fully loaded from the study file
262 //================================================================================
264 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
267 return !_preMeshInfo;
270 //================================================================================
272 * \brief Load full mesh data from the study file
274 //================================================================================
276 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
278 Unexpect aCatch(SALOME_SalomeException);
280 _preMeshInfo->FullLoadFromFile();
283 //================================================================================
285 * \brief Remove all nodes and elements
287 //================================================================================
289 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
291 Unexpect aCatch(SALOME_SalomeException);
293 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
297 //CheckGeomGroupModif(); // issue 20145
299 catch(SALOME_Exception & S_ex) {
300 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
303 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
306 //================================================================================
308 * \brief Remove all nodes and elements for indicated shape
310 //================================================================================
312 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
313 throw (SALOME::SALOME_Exception)
315 Unexpect aCatch(SALOME_SalomeException);
317 _preMeshInfo->FullLoadFromFile();
320 _impl->ClearSubMesh( ShapeID );
322 catch(SALOME_Exception & S_ex) {
323 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
325 _impl->GetMeshDS()->Modified();
327 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
330 //=============================================================================
332 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
334 //=============================================================================
336 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
338 SMESH::DriverMED_ReadStatus res;
341 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
342 res = SMESH::DRS_OK; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
344 res = SMESH::DRS_EMPTY; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
346 res = SMESH::DRS_WARN_RENUMBER; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
348 res = SMESH::DRS_WARN_SKIP_ELEM; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
350 res = SMESH::DRS_WARN_DESCENDING; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
353 res = SMESH::DRS_FAIL; break;
358 //=============================================================================
360 * Convert ::SMESH_ComputeError to SMESH::ComputeError
362 //=============================================================================
364 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
366 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
367 errVar->subShapeID = -1;
368 errVar->hasBadMesh = false;
370 if ( !errorPtr || errorPtr->IsOK() )
372 errVar->code = SMESH::COMPERR_OK;
376 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
377 errVar->comment = errorPtr->myComment.c_str();
379 return errVar._retn();
382 //=============================================================================
386 * Imports mesh data from MED file
388 //=============================================================================
390 SMESH::DriverMED_ReadStatus
391 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
392 throw ( SALOME::SALOME_Exception )
394 Unexpect aCatch(SALOME_SalomeException);
397 status = _impl->MEDToMesh( theFileName, theMeshName );
399 catch( SALOME_Exception& S_ex ) {
400 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
403 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
406 CreateGroupServants();
408 int major, minor, release;
409 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
410 major = minor = release = -1;
411 _medFileInfo = new SMESH::MedFileInfo();
412 _medFileInfo->fileName = theFileName;
413 _medFileInfo->fileSize = 0;
414 _medFileInfo->major = major;
415 _medFileInfo->minor = minor;
416 _medFileInfo->release = release;
417 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
419 return ConvertDriverMEDReadStatus(status);
422 //================================================================================
424 * \brief Imports mesh data from the CGNS file
426 //================================================================================
428 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
429 const int theMeshIndex,
430 std::string& theMeshName )
431 throw ( SALOME::SALOME_Exception )
433 Unexpect aCatch(SALOME_SalomeException);
436 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
438 catch( SALOME_Exception& S_ex ) {
439 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
442 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
445 CreateGroupServants();
447 return ConvertDriverMEDReadStatus(status);
450 //================================================================================
452 * \brief Return string representation of a MED file version comprising nbDigits
454 //================================================================================
456 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
458 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
460 return CORBA::string_dup( ver.c_str() );
463 //=============================================================================
467 * Imports mesh data from MED file
469 //=============================================================================
471 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
472 throw ( SALOME::SALOME_Exception )
476 // Read mesh with name = <theMeshName> into SMESH_Mesh
477 _impl->UNVToMesh( theFileName );
479 CreateGroupServants();
481 SMESH_CATCH( SMESH::throwCorbaException );
486 //=============================================================================
490 * Imports mesh data from STL file
492 //=============================================================================
493 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
494 throw ( SALOME::SALOME_Exception )
498 // Read mesh with name = <theMeshName> into SMESH_Mesh
499 std::string name = _impl->STLToMesh( theFileName );
502 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
503 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( study, _this() );
504 _gen_i->SetName( meshSO, name.c_str() );
507 SMESH_CATCH( SMESH::throwCorbaException );
512 //================================================================================
514 * \brief Function used in SMESH_CATCH by ImportGMFFile()
516 //================================================================================
520 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
522 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
526 //================================================================================
528 * \brief Imports data from a GMF file and returns an error description
530 //================================================================================
532 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
533 bool theMakeRequiredGroups )
534 throw (SALOME::SALOME_Exception)
536 SMESH_ComputeErrorPtr error;
539 #define SMESH_CAUGHT error =
542 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
544 SMESH_CATCH( exceptionToComputeError );
548 CreateGroupServants();
550 return ConvertComputeError( error );
553 //=============================================================================
557 //=============================================================================
559 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
561 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
562 (SMESH_Hypothesis::Hypothesis_Status theStatus)
565 RETURNCASE( HYP_OK );
566 RETURNCASE( HYP_MISSING );
567 RETURNCASE( HYP_CONCURENT );
568 RETURNCASE( HYP_BAD_PARAMETER );
569 RETURNCASE( HYP_HIDDEN_ALGO );
570 RETURNCASE( HYP_HIDING_ALGO );
571 RETURNCASE( HYP_UNKNOWN_FATAL );
572 RETURNCASE( HYP_INCOMPATIBLE );
573 RETURNCASE( HYP_NOTCONFORM );
574 RETURNCASE( HYP_ALREADY_EXIST );
575 RETURNCASE( HYP_BAD_DIM );
576 RETURNCASE( HYP_BAD_SUBSHAPE );
577 RETURNCASE( HYP_BAD_GEOMETRY );
578 RETURNCASE( HYP_NEED_SHAPE );
579 RETURNCASE( HYP_INCOMPAT_HYPS );
582 return SMESH::HYP_UNKNOWN_FATAL;
585 //=============================================================================
589 * calls internal addHypothesis() and then adds a reference to <anHyp> under
590 * the SObject actually having a reference to <aSubShape>.
591 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
593 //=============================================================================
595 SMESH::Hypothesis_Status
596 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
597 SMESH::SMESH_Hypothesis_ptr anHyp,
598 CORBA::String_out anErrorText)
599 throw(SALOME::SALOME_Exception)
601 Unexpect aCatch(SALOME_SalomeException);
603 _preMeshInfo->ForgetOrLoad();
606 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
607 anErrorText = error.c_str();
609 SMESH::SMESH_Mesh_var mesh( _this() );
610 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
612 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
613 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
615 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
617 // Update Python script
618 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
619 << aSubShape << ", " << anHyp << " )";
621 return ConvertHypothesisStatus(status);
624 //=============================================================================
628 //=============================================================================
630 SMESH_Hypothesis::Hypothesis_Status
631 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
632 SMESH::SMESH_Hypothesis_ptr anHyp,
633 std::string* anErrorText)
635 if(MYDEBUG) MESSAGE("addHypothesis");
637 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
638 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
640 if (CORBA::is_nil( anHyp ))
641 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
643 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
646 TopoDS_Shape myLocSubShape;
647 //use PseudoShape in case if mesh has no shape
649 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
651 myLocSubShape = _impl->GetShapeToMesh();
653 const int hypId = anHyp->GetId();
655 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
656 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
658 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
660 // assure there is a corresponding submesh
661 if ( !_impl->IsMainShape( myLocSubShape )) {
662 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
663 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
664 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
667 else if ( anErrorText )
669 *anErrorText = error;
672 catch(SALOME_Exception & S_ex)
674 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
679 //=============================================================================
683 //=============================================================================
685 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
686 SMESH::SMESH_Hypothesis_ptr anHyp)
687 throw(SALOME::SALOME_Exception)
689 Unexpect aCatch(SALOME_SalomeException);
691 _preMeshInfo->ForgetOrLoad();
693 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
694 SMESH::SMESH_Mesh_var mesh = _this();
696 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
698 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
699 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
701 // Update Python script
702 if(_impl->HasShapeToMesh())
703 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
704 << aSubShape << ", " << anHyp << " )";
706 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
709 return ConvertHypothesisStatus(status);
712 //=============================================================================
716 //=============================================================================
718 SMESH_Hypothesis::Hypothesis_Status
719 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
720 SMESH::SMESH_Hypothesis_ptr anHyp)
722 if(MYDEBUG) MESSAGE("removeHypothesis()");
724 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
725 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
727 if (CORBA::is_nil( anHyp ))
728 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
730 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
733 TopoDS_Shape myLocSubShape;
734 //use PseudoShape in case if mesh has no shape
735 if( _impl->HasShapeToMesh() )
736 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
738 myLocSubShape = _impl->GetShapeToMesh();
740 const int hypId = anHyp->GetId();
741 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
742 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
744 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
748 catch(SALOME_Exception & S_ex)
750 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
755 //=============================================================================
759 //=============================================================================
761 SMESH::ListOfHypothesis *
762 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
763 throw(SALOME::SALOME_Exception)
765 Unexpect aCatch(SALOME_SalomeException);
766 if (MYDEBUG) MESSAGE("GetHypothesisList");
767 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
768 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
770 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
773 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
774 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
775 myLocSubShape = _impl->GetShapeToMesh();
776 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
777 int i = 0, n = aLocalList.size();
780 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
781 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
782 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
784 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
785 if ( id_hypptr != _mapHypo.end() )
786 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
790 catch(SALOME_Exception & S_ex) {
791 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
794 return aList._retn();
797 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
799 Unexpect aCatch(SALOME_SalomeException);
800 if (MYDEBUG) MESSAGE("GetSubMeshes");
802 SMESH::submesh_array_var aList = new SMESH::submesh_array();
805 TPythonDump aPythonDump;
806 if ( !_mapSubMeshIor.empty() )
810 aList->length( _mapSubMeshIor.size() );
812 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
813 for ( ; it != _mapSubMeshIor.end(); it++ ) {
814 if ( CORBA::is_nil( it->second )) continue;
815 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
817 if (i > 1) aPythonDump << ", ";
818 aPythonDump << it->second;
822 catch(SALOME_Exception & S_ex) {
823 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
826 // Update Python script
827 if ( !_mapSubMeshIor.empty() )
828 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
830 return aList._retn();
833 //=============================================================================
837 //=============================================================================
839 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
840 const char* theName )
841 throw(SALOME::SALOME_Exception)
843 Unexpect aCatch(SALOME_SalomeException);
844 if (CORBA::is_nil(aSubShape))
845 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
847 SMESH::SMESH_subMesh_var subMesh;
848 SMESH::SMESH_Mesh_var aMesh = _this();
850 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
852 //Get or Create the SMESH_subMesh object implementation
854 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
856 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
858 TopoDS_Iterator it( myLocSubShape );
860 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
862 subMesh = getSubMesh( subMeshId );
864 // create a new subMesh object servant if there is none for the shape
865 if ( subMesh->_is_nil() )
866 subMesh = createSubMesh( aSubShape );
867 if ( _gen_i->CanPublishInStudy( subMesh ))
869 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
870 SALOMEDS::SObject_wrap aSO =
871 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
872 if ( !aSO->_is_nil()) {
873 // Update Python script
874 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
875 << aSubShape << ", '" << theName << "' )";
879 catch(SALOME_Exception & S_ex) {
880 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
882 return subMesh._retn();
885 //=============================================================================
889 //=============================================================================
891 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
892 throw (SALOME::SALOME_Exception)
896 if ( theSubMesh->_is_nil() )
899 GEOM::GEOM_Object_var aSubShape;
900 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
901 if ( !aStudy->_is_nil() ) {
902 // Remove submesh's SObject
903 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
904 if ( !anSO->_is_nil() ) {
905 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
906 SALOMEDS::SObject_wrap anObj, aRef;
907 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
908 anObj->ReferencedObject( aRef.inout() ))
910 CORBA::Object_var obj = aRef->GetObject();
911 aSubShape = GEOM::GEOM_Object::_narrow( obj );
913 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
914 // aSubShape = theSubMesh->GetSubShape();
916 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
917 builder->RemoveObjectWithChildren( anSO );
919 // Update Python script
920 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
924 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
926 _preMeshInfo->ForgetOrLoad();
928 SMESH_CATCH( SMESH::throwCorbaException );
931 //=============================================================================
935 //=============================================================================
937 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
938 const char* theName )
939 throw(SALOME::SALOME_Exception)
941 Unexpect aCatch(SALOME_SalomeException);
943 _preMeshInfo->FullLoadFromFile();
945 SMESH::SMESH_Group_var aNewGroup =
946 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
948 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
950 SMESH::SMESH_Mesh_var mesh = _this();
951 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
952 SALOMEDS::SObject_wrap aSO =
953 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
954 if ( !aSO->_is_nil())
955 // Update Python script
956 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
957 << theElemType << ", '" << theName << "' )";
959 return aNewGroup._retn();
962 //=============================================================================
966 //=============================================================================
967 SMESH::SMESH_GroupOnGeom_ptr
968 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
970 GEOM::GEOM_Object_ptr theGeomObj)
971 throw(SALOME::SALOME_Exception)
973 Unexpect aCatch(SALOME_SalomeException);
975 _preMeshInfo->FullLoadFromFile();
977 SMESH::SMESH_GroupOnGeom_var aNewGroup;
979 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
980 if ( !aShape.IsNull() )
983 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
985 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
987 SMESH::SMESH_Mesh_var mesh = _this();
988 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
989 SALOMEDS::SObject_wrap aSO =
990 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
991 if ( !aSO->_is_nil())
992 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
993 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
997 return aNewGroup._retn();
1000 //================================================================================
1002 * \brief Creates a group whose contents is defined by filter
1003 * \param theElemType - group type
1004 * \param theName - group name
1005 * \param theFilter - the filter
1006 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1008 //================================================================================
1010 SMESH::SMESH_GroupOnFilter_ptr
1011 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1012 const char* theName,
1013 SMESH::Filter_ptr theFilter )
1014 throw (SALOME::SALOME_Exception)
1016 Unexpect aCatch(SALOME_SalomeException);
1018 _preMeshInfo->FullLoadFromFile();
1020 if ( CORBA::is_nil( theFilter ))
1021 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1023 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1025 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1027 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1028 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1031 if ( !aNewGroup->_is_nil() )
1032 aNewGroup->SetFilter( theFilter );
1034 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1036 SMESH::SMESH_Mesh_var mesh = _this();
1037 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1038 SALOMEDS::SObject_wrap aSO =
1039 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1041 if ( !aSO->_is_nil())
1042 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1043 << theElemType << ", '" << theName << "', " << theFilter << " )";
1045 return aNewGroup._retn();
1048 //=============================================================================
1052 //=============================================================================
1054 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1055 throw (SALOME::SALOME_Exception)
1057 if ( theGroup->_is_nil() )
1062 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1066 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1067 if ( !aStudy->_is_nil() )
1069 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1070 if ( !aGroupSO->_is_nil() )
1072 // Update Python script
1073 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1075 // Remove group's SObject
1076 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1077 builder->RemoveObjectWithChildren( aGroupSO );
1080 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1082 // Remove the group from SMESH data structures
1083 removeGroup( aGroup->GetLocalID() );
1085 SMESH_CATCH( SMESH::throwCorbaException );
1088 //=============================================================================
1090 * Remove group with its contents
1092 //=============================================================================
1094 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1095 throw (SALOME::SALOME_Exception)
1099 _preMeshInfo->FullLoadFromFile();
1101 if ( theGroup->_is_nil() )
1104 vector<int> nodeIds; // to remove nodes becoming free
1105 if ( !theGroup->IsEmpty() )
1107 CORBA::Long elemID = theGroup->GetID( 1 );
1108 int nbElemNodes = GetElemNbNodes( elemID );
1109 if ( nbElemNodes > 0 )
1110 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1114 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1115 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1116 while ( elemIt->more() )
1118 const SMDS_MeshElement* e = elemIt->next();
1120 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1121 while ( nIt->more() )
1122 nodeIds.push_back( nIt->next()->GetID() );
1124 _impl->GetMeshDS()->RemoveElement( e );
1127 // Remove free nodes
1128 if ( theGroup->GetType() != SMESH::NODE )
1129 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1130 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1131 if ( n->NbInverseElements() == 0 )
1132 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1134 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1136 // Update Python script (theGroup must be alive for this)
1137 pyDump << SMESH::SMESH_Mesh_var(_this())
1138 << ".RemoveGroupWithContents( " << theGroup << " )";
1141 RemoveGroup( theGroup );
1143 SMESH_CATCH( SMESH::throwCorbaException );
1146 //================================================================================
1148 * \brief Get the list of groups existing in the mesh
1149 * \retval SMESH::ListOfGroups * - list of groups
1151 //================================================================================
1153 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1155 Unexpect aCatch(SALOME_SalomeException);
1156 if (MYDEBUG) MESSAGE("GetGroups");
1158 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1161 TPythonDump aPythonDump;
1162 if ( !_mapGroups.empty() )
1164 aPythonDump << "[ ";
1166 aList->length( _mapGroups.size() );
1168 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1169 for ( ; it != _mapGroups.end(); it++ ) {
1170 if ( CORBA::is_nil( it->second )) continue;
1171 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1173 if (i > 1) aPythonDump << ", ";
1174 aPythonDump << it->second;
1178 catch(SALOME_Exception & S_ex) {
1179 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1181 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1183 return aList._retn();
1186 //=============================================================================
1188 * Get number of groups existing in the mesh
1190 //=============================================================================
1192 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1194 Unexpect aCatch(SALOME_SalomeException);
1195 return _mapGroups.size();
1198 //=============================================================================
1200 * New group including all mesh elements present in initial groups is created.
1202 //=============================================================================
1204 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1205 SMESH::SMESH_GroupBase_ptr theGroup2,
1206 const char* theName )
1207 throw (SALOME::SALOME_Exception)
1209 SMESH::SMESH_Group_var aResGrp;
1213 _preMeshInfo->FullLoadFromFile();
1215 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1216 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1218 if ( theGroup1->GetType() != theGroup2->GetType() )
1219 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1224 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1225 if ( aResGrp->_is_nil() )
1226 return SMESH::SMESH_Group::_nil();
1228 aResGrp->AddFrom( theGroup1 );
1229 aResGrp->AddFrom( theGroup2 );
1231 // Update Python script
1232 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1233 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1235 SMESH_CATCH( SMESH::throwCorbaException );
1237 return aResGrp._retn();
1240 //=============================================================================
1242 * \brief New group including all mesh elements present in initial groups is created.
1243 * \param theGroups list of groups
1244 * \param theName name of group to be created
1245 * \return pointer to the new group
1247 //=============================================================================
1249 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1250 const char* theName )
1251 throw (SALOME::SALOME_Exception)
1253 SMESH::SMESH_Group_var aResGrp;
1256 _preMeshInfo->FullLoadFromFile();
1259 return SMESH::SMESH_Group::_nil();
1264 SMESH::ElementType aType = SMESH::ALL;
1265 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1267 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1268 if ( CORBA::is_nil( aGrp ) )
1270 if ( aType == SMESH::ALL )
1271 aType = aGrp->GetType();
1272 else if ( aType != aGrp->GetType() )
1273 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1276 if ( aType == SMESH::ALL )
1277 return SMESH::SMESH_Group::_nil();
1282 aResGrp = CreateGroup( aType, theName );
1283 if ( aResGrp->_is_nil() )
1284 return SMESH::SMESH_Group::_nil();
1286 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1287 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1289 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1290 if ( !CORBA::is_nil( aGrp ) )
1292 aResGrp->AddFrom( aGrp );
1293 if ( g > 0 ) pyDump << ", ";
1297 pyDump << " ], '" << theName << "' )";
1299 SMESH_CATCH( SMESH::throwCorbaException );
1301 return aResGrp._retn();
1304 //=============================================================================
1306 * New group is created. All mesh elements that are
1307 * present in both initial groups are added to the new one.
1309 //=============================================================================
1311 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1312 SMESH::SMESH_GroupBase_ptr theGroup2,
1313 const char* theName )
1314 throw (SALOME::SALOME_Exception)
1316 SMESH::SMESH_Group_var aResGrp;
1321 _preMeshInfo->FullLoadFromFile();
1323 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1324 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1326 if ( theGroup1->GetType() != theGroup2->GetType() )
1327 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1331 // Create Intersection
1332 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1333 if ( aResGrp->_is_nil() )
1334 return aResGrp._retn();
1336 SMESHDS_GroupBase* groupDS1 = 0;
1337 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1338 groupDS1 = grp_i->GetGroupDS();
1340 SMESHDS_GroupBase* groupDS2 = 0;
1341 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1342 groupDS2 = grp_i->GetGroupDS();
1344 SMESHDS_Group* resGroupDS = 0;
1345 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1346 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1348 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1350 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1351 while ( elemIt1->more() )
1353 const SMDS_MeshElement* e = elemIt1->next();
1354 if ( groupDS2->Contains( e ))
1355 resGroupDS->SMDSGroup().Add( e );
1358 // Update Python script
1359 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1360 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1362 SMESH_CATCH( SMESH::throwCorbaException );
1364 return aResGrp._retn();
1367 //=============================================================================
1369 \brief Intersect list of groups. New group is created. All mesh elements that
1370 are present in all initial groups simultaneously are added to the new one.
1371 \param theGroups list of groups
1372 \param theName name of group to be created
1373 \return pointer on the group
1375 //=============================================================================
1376 SMESH::SMESH_Group_ptr
1377 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1378 const char* theName )
1379 throw (SALOME::SALOME_Exception)
1381 SMESH::SMESH_Group_var aResGrp;
1386 _preMeshInfo->FullLoadFromFile();
1389 return SMESH::SMESH_Group::_nil();
1391 // check types and get SMESHDS_GroupBase's
1392 SMESH::ElementType aType = SMESH::ALL;
1393 vector< SMESHDS_GroupBase* > groupVec;
1394 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1396 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1397 if ( CORBA::is_nil( aGrp ) )
1399 if ( aType == SMESH::ALL )
1400 aType = aGrp->GetType();
1401 else if ( aType != aGrp->GetType() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1405 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1406 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1408 if ( grpDS->IsEmpty() )
1413 groupVec.push_back( grpDS );
1416 if ( aType == SMESH::ALL ) // all groups are nil
1417 return SMESH::SMESH_Group::_nil();
1422 aResGrp = CreateGroup( aType, theName );
1424 SMESHDS_Group* resGroupDS = 0;
1425 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1426 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1427 if ( !resGroupDS || groupVec.empty() )
1428 return aResGrp._retn();
1431 size_t i, nb = groupVec.size();
1432 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1433 while ( elemIt1->more() )
1435 const SMDS_MeshElement* e = elemIt1->next();
1437 for ( i = 1; ( i < nb && inAll ); ++i )
1438 inAll = groupVec[i]->Contains( e );
1441 resGroupDS->SMDSGroup().Add( e );
1444 // Update Python script
1445 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1446 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1448 SMESH_CATCH( SMESH::throwCorbaException );
1450 return aResGrp._retn();
1453 //=============================================================================
1455 * New group is created. All mesh elements that are present in
1456 * a main group but is not present in a tool group are added to the new one
1458 //=============================================================================
1460 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1461 SMESH::SMESH_GroupBase_ptr theGroup2,
1462 const char* theName )
1463 throw (SALOME::SALOME_Exception)
1465 SMESH::SMESH_Group_var aResGrp;
1470 _preMeshInfo->FullLoadFromFile();
1472 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1473 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1475 if ( theGroup1->GetType() != theGroup2->GetType() )
1476 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1480 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1481 if ( aResGrp->_is_nil() )
1482 return aResGrp._retn();
1484 SMESHDS_GroupBase* groupDS1 = 0;
1485 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1486 groupDS1 = grp_i->GetGroupDS();
1488 SMESHDS_GroupBase* groupDS2 = 0;
1489 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1490 groupDS2 = grp_i->GetGroupDS();
1492 SMESHDS_Group* resGroupDS = 0;
1493 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1494 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1496 if ( groupDS1 && groupDS2 && resGroupDS )
1498 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1499 while ( elemIt1->more() )
1501 const SMDS_MeshElement* e = elemIt1->next();
1502 if ( !groupDS2->Contains( e ))
1503 resGroupDS->SMDSGroup().Add( e );
1506 // Update Python script
1507 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1508 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1510 SMESH_CATCH( SMESH::throwCorbaException );
1512 return aResGrp._retn();
1515 //=============================================================================
1517 \brief Cut lists of groups. New group is created. All mesh elements that are
1518 present in main groups but do not present in tool groups are added to the new one
1519 \param theMainGroups list of main groups
1520 \param theToolGroups list of tool groups
1521 \param theName name of group to be created
1522 \return pointer on the group
1524 //=============================================================================
1525 SMESH::SMESH_Group_ptr
1526 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1527 const SMESH::ListOfGroups& theToolGroups,
1528 const char* theName )
1529 throw (SALOME::SALOME_Exception)
1531 SMESH::SMESH_Group_var aResGrp;
1536 _preMeshInfo->FullLoadFromFile();
1539 return SMESH::SMESH_Group::_nil();
1541 // check types and get SMESHDS_GroupBase's
1542 SMESH::ElementType aType = SMESH::ALL;
1543 vector< SMESHDS_GroupBase* > toolGroupVec;
1544 vector< SMDS_ElemIteratorPtr > mainIterVec;
1546 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1548 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1549 if ( CORBA::is_nil( aGrp ) )
1551 if ( aType == SMESH::ALL )
1552 aType = aGrp->GetType();
1553 else if ( aType != aGrp->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1556 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1557 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1558 if ( !grpDS->IsEmpty() )
1559 mainIterVec.push_back( grpDS->GetElements() );
1561 if ( aType == SMESH::ALL ) // all main groups are nil
1562 return SMESH::SMESH_Group::_nil();
1563 if ( mainIterVec.empty() ) // all main groups are empty
1564 return aResGrp._retn();
1566 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1568 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1569 if ( CORBA::is_nil( aGrp ) )
1571 if ( aType != aGrp->GetType() )
1572 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1574 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1575 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1576 toolGroupVec.push_back( grpDS );
1582 aResGrp = CreateGroup( aType, theName );
1584 SMESHDS_Group* resGroupDS = 0;
1585 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1586 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1588 return aResGrp._retn();
1591 size_t i, nb = toolGroupVec.size();
1592 SMDS_ElemIteratorPtr mainElemIt
1593 ( new SMDS_IteratorOnIterators
1594 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1595 while ( mainElemIt->more() )
1597 const SMDS_MeshElement* e = mainElemIt->next();
1599 for ( i = 0; ( i < nb && !isIn ); ++i )
1600 isIn = toolGroupVec[i]->Contains( e );
1603 resGroupDS->SMDSGroup().Add( e );
1606 // Update Python script
1607 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1608 << ".CutListOfGroups( " << theMainGroups << ", "
1609 << theToolGroups << ", '" << theName << "' )";
1611 SMESH_CATCH( SMESH::throwCorbaException );
1613 return aResGrp._retn();
1616 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1618 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1619 bool & toStopChecking )
1621 toStopChecking = ( nbCommon < nbChecked );
1622 return nbCommon == nbNodes;
1624 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1625 bool & toStopChecking )
1627 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1628 return nbCommon == nbCorners;
1630 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1631 bool & toStopChecking )
1633 return nbCommon > 0;
1635 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1636 bool & toStopChecking )
1638 return nbCommon >= (nbNodes+1) / 2;
1642 //=============================================================================
1644 * Create a group of entities basing on nodes of other groups.
1645 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1646 * \param [in] anElemType - a type of elements to include to the new group.
1647 * \param [in] theName - a name of the new group.
1648 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1649 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1650 * new group provided that it is based on nodes of an element of \a aListOfGroups
1651 * \return SMESH_Group - the created group
1653 // IMP 19939, bug 22010, IMP 22635
1654 //=============================================================================
1656 SMESH::SMESH_Group_ptr
1657 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1658 SMESH::ElementType theElemType,
1659 const char* theName,
1660 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1661 CORBA::Boolean theUnderlyingOnly)
1662 throw (SALOME::SALOME_Exception)
1664 SMESH::SMESH_Group_var aResGrp;
1668 _preMeshInfo->FullLoadFromFile();
1670 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1672 if ( !theName || !aMeshDS )
1673 return SMESH::SMESH_Group::_nil();
1675 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1677 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1678 SMESH_Comment nbCoNoStr( "SMESH.");
1679 switch ( theNbCommonNodes ) {
1680 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1681 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1682 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1683 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1684 default: return aResGrp._retn();
1686 int nbChecked, nbCommon, nbNodes, nbCorners;
1692 aResGrp = CreateGroup( theElemType, theName );
1693 if ( aResGrp->_is_nil() )
1694 return SMESH::SMESH_Group::_nil();
1696 SMESHDS_GroupBase* groupBaseDS =
1697 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1698 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1700 vector<bool> isNodeInGroups;
1702 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1704 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1705 if ( CORBA::is_nil( aGrp ) )
1707 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1708 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1711 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1712 if ( !elIt ) continue;
1714 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1716 while ( elIt->more() ) {
1717 const SMDS_MeshElement* el = elIt->next();
1718 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1719 while ( nIt->more() )
1720 resGroupCore.Add( nIt->next() );
1723 // get elements of theElemType based on nodes of every element of group
1724 else if ( theUnderlyingOnly )
1726 while ( elIt->more() )
1728 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1729 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1730 TIDSortedElemSet checkedElems;
1731 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1732 while ( nIt->more() )
1734 const SMDS_MeshNode* n = nIt->next();
1735 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1736 // check nodes of elements of theElemType around el
1737 while ( elOfTypeIt->more() )
1739 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1740 if ( !checkedElems.insert( elOfType ).second ) continue;
1741 nbNodes = elOfType->NbNodes();
1742 nbCorners = elOfType->NbCornerNodes();
1744 bool toStopChecking = false;
1745 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1746 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1747 if ( elNodes.count( nIt2->next() ) &&
1748 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1750 resGroupCore.Add( elOfType );
1757 // get all nodes of elements of groups
1760 while ( elIt->more() )
1762 const SMDS_MeshElement* el = elIt->next(); // an element of group
1763 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1764 while ( nIt->more() )
1766 const SMDS_MeshNode* n = nIt->next();
1767 if ( n->GetID() >= (int) isNodeInGroups.size() )
1768 isNodeInGroups.resize( n->GetID() + 1, false );
1769 isNodeInGroups[ n->GetID() ] = true;
1775 // Get elements of theElemType based on a certain number of nodes of elements of groups
1776 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1778 const SMDS_MeshNode* n;
1779 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1780 const int isNodeInGroupsSize = isNodeInGroups.size();
1781 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1783 if ( !isNodeInGroups[ iN ] ||
1784 !( n = aMeshDS->FindNode( iN )))
1787 // check nodes of elements of theElemType around n
1788 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1789 while ( elOfTypeIt->more() )
1791 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1792 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1797 nbNodes = elOfType->NbNodes();
1798 nbCorners = elOfType->NbCornerNodes();
1800 bool toStopChecking = false;
1801 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1802 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1804 const int nID = nIt->next()->GetID();
1805 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1806 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1808 resGroupCore.Add( elOfType );
1816 // Update Python script
1817 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1818 << ".CreateDimGroup( "
1819 << theGroups << ", " << theElemType << ", '" << theName << "', "
1820 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1822 SMESH_CATCH( SMESH::throwCorbaException );
1824 return aResGrp._retn();
1827 //================================================================================
1829 * \brief Remember GEOM group data
1831 //================================================================================
1833 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1834 CORBA::Object_ptr theSmeshObj)
1836 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1839 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1840 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1841 if ( groupSO->_is_nil() )
1844 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1845 GEOM::GEOM_IGroupOperations_wrap groupOp =
1846 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1847 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1850 _geomGroupData.push_back( TGeomGroupData() );
1851 TGeomGroupData & groupData = _geomGroupData.back();
1853 CORBA::String_var entry = groupSO->GetID();
1854 groupData._groupEntry = entry.in();
1856 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1857 groupData._indices.insert( ids[i] );
1859 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1860 // shape index in SMESHDS
1861 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1862 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1865 //================================================================================
1867 * Remove GEOM group data relating to removed smesh object
1869 //================================================================================
1871 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1873 list<TGeomGroupData>::iterator
1874 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1875 for ( ; data != dataEnd; ++data ) {
1876 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1877 _geomGroupData.erase( data );
1883 //================================================================================
1885 * \brief Return new group contents if it has been changed and update group data
1887 //================================================================================
1889 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1891 TopoDS_Shape newShape;
1894 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1895 if ( study->_is_nil() ) return newShape; // means "not changed"
1896 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1897 if ( !groupSO->_is_nil() )
1899 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1900 if ( CORBA::is_nil( groupObj )) return newShape;
1901 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1903 // get indices of group items
1904 set<int> curIndices;
1905 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1906 GEOM::GEOM_IGroupOperations_wrap groupOp =
1907 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1908 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1909 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1910 curIndices.insert( ids[i] );
1912 if ( groupData._indices == curIndices )
1913 return newShape; // group not changed
1916 groupData._indices = curIndices;
1918 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1919 if ( !geomClient ) return newShape;
1920 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1921 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1922 newShape = _gen_i->GeomObjectToShape( geomGroup );
1925 if ( newShape.IsNull() ) {
1926 // geom group becomes empty - return empty compound
1927 TopoDS_Compound compound;
1928 BRep_Builder().MakeCompound(compound);
1929 newShape = compound;
1936 //-----------------------------------------------------------------------------
1938 * \brief Storage of shape and index used in CheckGeomGroupModif()
1940 struct TIndexedShape
1943 TopoDS_Shape _shape;
1944 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1946 //-----------------------------------------------------------------------------
1948 * \brief Data to re-create a group on geometry
1950 struct TGroupOnGeomData
1954 SMDSAbs_ElementType _type;
1956 Quantity_Color _color;
1960 //=============================================================================
1962 * \brief Update data if geometry changes
1966 //=============================================================================
1968 void SMESH_Mesh_i::CheckGeomModif()
1970 if ( !_impl->HasShapeToMesh() ) return;
1972 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1973 if ( study->_is_nil() ) return;
1975 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1976 //if ( mainGO->_is_nil() ) return;
1978 // Update after group modification
1980 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1981 called by other mesh (IPAL52735) */
1982 mainGO->GetType() == GEOM_GROUP ||
1983 mainGO->GetTick() == _mainShapeTick )
1985 CheckGeomGroupModif();
1989 // Update after shape transformation like Translate
1991 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1992 if ( !geomClient ) return;
1993 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1994 if ( geomGen->_is_nil() ) return;
1996 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1997 geomClient->RemoveShapeFromBuffer( ior.in() );
1999 // Update data taking into account that
2000 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2003 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2004 if ( newShape.IsNull() )
2007 _mainShapeTick = mainGO->GetTick();
2009 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2011 // store data of groups on geometry
2012 vector< TGroupOnGeomData > groupsData;
2013 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2014 groupsData.reserve( groups.size() );
2015 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2016 for ( ; g != groups.end(); ++g )
2017 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2019 TGroupOnGeomData data;
2020 data._oldID = group->GetID();
2021 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2022 data._type = group->GetType();
2023 data._name = group->GetStoreName();
2024 data._color = group->GetColor();
2025 groupsData.push_back( data );
2027 // store assigned hypotheses
2028 vector< pair< int, THypList > > ids2Hyps;
2029 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2030 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2032 const TopoDS_Shape& s = s2hyps.Key();
2033 const THypList& hyps = s2hyps.ChangeValue();
2034 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2037 // change shape to mesh
2038 int oldNbSubShapes = meshDS->MaxShapeIndex();
2039 _impl->ShapeToMesh( TopoDS_Shape() );
2040 _impl->ShapeToMesh( newShape );
2042 // re-add shapes of geom groups
2043 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2044 for ( ; data != _geomGroupData.end(); ++data )
2046 TopoDS_Shape newShape = newGroupShape( *data );
2047 if ( !newShape.IsNull() )
2049 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2051 TopoDS_Compound compound;
2052 BRep_Builder().MakeCompound( compound );
2053 BRep_Builder().Add( compound, newShape );
2054 newShape = compound;
2056 _impl->GetSubMesh( newShape );
2059 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2060 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2061 SALOME::INTERNAL_ERROR );
2063 // re-assign hypotheses
2064 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2066 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2067 const THypList& hyps = ids2Hyps[i].second;
2068 THypList::const_iterator h = hyps.begin();
2069 for ( ; h != hyps.end(); ++h )
2070 _impl->AddHypothesis( s, (*h)->GetID() );
2074 for ( size_t i = 0; i < groupsData.size(); ++i )
2076 const TGroupOnGeomData& data = groupsData[i];
2078 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2079 if ( i2g == _mapGroups.end() ) continue;
2081 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2082 if ( !gr_i ) continue;
2085 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2086 meshDS->IndexToShape( data._shapeID ));
2089 _mapGroups.erase( i2g );
2093 g->GetGroupDS()->SetColor( data._color );
2094 gr_i->changeLocalId( id );
2095 _mapGroups[ id ] = i2g->second;
2096 if ( data._oldID != id )
2097 _mapGroups.erase( i2g );
2101 // update _mapSubMesh
2102 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2103 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2104 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2108 //=============================================================================
2110 * \brief Update objects depending on changed geom groups
2112 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2113 * issue 0020210: Update of a smesh group after modification of the associated geom group
2115 //=============================================================================
2117 void SMESH_Mesh_i::CheckGeomGroupModif()
2119 if ( !_impl->HasShapeToMesh() ) return;
2121 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2122 if ( study->_is_nil() ) return;
2124 CORBA::Long nbEntities = NbNodes() + NbElements();
2126 // Check if group contents changed
2128 typedef map< string, TopoDS_Shape > TEntry2Geom;
2129 TEntry2Geom newGroupContents;
2131 list<TGeomGroupData>::iterator
2132 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2133 for ( ; data != dataEnd; ++data )
2135 pair< TEntry2Geom::iterator, bool > it_new =
2136 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2137 bool processedGroup = !it_new.second;
2138 TopoDS_Shape& newShape = it_new.first->second;
2139 if ( !processedGroup )
2140 newShape = newGroupShape( *data );
2141 if ( newShape.IsNull() )
2142 continue; // no changes
2145 _preMeshInfo->ForgetOrLoad();
2147 if ( processedGroup ) { // update group indices
2148 list<TGeomGroupData>::iterator data2 = data;
2149 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2150 data->_indices = data2->_indices;
2153 // Update SMESH objects according to new GEOM group contents
2155 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2156 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2158 int oldID = submesh->GetId();
2159 if ( !_mapSubMeshIor.count( oldID ))
2161 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2163 // update hypotheses
2164 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2165 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2166 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2168 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2169 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2171 // care of submeshes
2172 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2173 int newID = newSubmesh->GetId();
2174 if ( newID != oldID ) {
2175 _mapSubMesh [ newID ] = newSubmesh;
2176 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2177 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2178 _mapSubMesh. erase(oldID);
2179 _mapSubMesh_i. erase(oldID);
2180 _mapSubMeshIor.erase(oldID);
2181 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2186 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2187 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2188 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2190 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2192 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2193 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2194 ds->SetShape( newShape );
2199 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2200 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2202 // Remove groups and submeshes basing on removed sub-shapes
2204 TopTools_MapOfShape newShapeMap;
2205 TopoDS_Iterator shapeIt( newShape );
2206 for ( ; shapeIt.More(); shapeIt.Next() )
2207 newShapeMap.Add( shapeIt.Value() );
2209 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2210 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2212 if ( newShapeMap.Contains( shapeIt.Value() ))
2214 TopTools_IndexedMapOfShape oldShapeMap;
2215 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2216 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2218 const TopoDS_Shape& oldShape = oldShapeMap(i);
2219 int oldInd = meshDS->ShapeToIndex( oldShape );
2221 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2222 if ( i_smIor != _mapSubMeshIor.end() ) {
2223 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2226 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2227 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2229 // check if a group bases on oldInd shape
2230 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2231 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2232 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2233 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2235 RemoveGroup( i_grp->second ); // several groups can base on same shape
2236 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2241 // Reassign hypotheses and update groups after setting the new shape to mesh
2243 // collect anassigned hypotheses
2244 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2245 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2246 TShapeHypList assignedHyps;
2247 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2249 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2250 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2251 if ( !hyps.empty() ) {
2252 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2253 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2254 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2257 // collect shapes supporting groups
2258 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2259 TShapeTypeList groupData;
2260 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2261 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2262 for ( ; grIt != groups.end(); ++grIt )
2264 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2266 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2268 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2270 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2271 _impl->ShapeToMesh( newShape );
2273 // reassign hypotheses
2274 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2275 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2277 TIndexedShape& geom = indS_hyps->first;
2278 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2279 int oldID = geom._index;
2280 int newID = meshDS->ShapeToIndex( geom._shape );
2281 if ( oldID == 1 ) { // main shape
2283 geom._shape = newShape;
2287 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2288 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2289 // care of sub-meshes
2290 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2291 if ( newID != oldID ) {
2292 _mapSubMesh [ newID ] = newSubmesh;
2293 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2294 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2295 _mapSubMesh. erase(oldID);
2296 _mapSubMesh_i. erase(oldID);
2297 _mapSubMeshIor.erase(oldID);
2298 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2302 TShapeTypeList::iterator geomType = groupData.begin();
2303 for ( ; geomType != groupData.end(); ++geomType )
2305 const TIndexedShape& geom = geomType->first;
2306 int oldID = geom._index;
2307 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2310 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2311 CORBA::String_var name = groupSO->GetName();
2313 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2315 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2316 group_i->changeLocalId( newID );
2319 break; // everything has been updated
2322 } // loop on group data
2326 CORBA::Long newNbEntities = NbNodes() + NbElements();
2327 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2328 if ( newNbEntities != nbEntities )
2330 // Add all SObjects with icons to soToUpdateIcons
2331 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2333 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2334 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2335 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2337 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2338 i_gr != _mapGroups.end(); ++i_gr ) // groups
2339 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2342 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2343 for ( ; so != soToUpdateIcons.end(); ++so )
2344 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2347 //=============================================================================
2349 * \brief Create standalone group from a group on geometry or filter
2351 //=============================================================================
2353 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2354 throw (SALOME::SALOME_Exception)
2356 SMESH::SMESH_Group_var aGroup;
2361 _preMeshInfo->FullLoadFromFile();
2363 if ( theGroup->_is_nil() )
2364 return aGroup._retn();
2366 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2368 return aGroup._retn();
2370 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2372 const int anId = aGroupToRem->GetLocalID();
2373 if ( !_impl->ConvertToStandalone( anId ) )
2374 return aGroup._retn();
2375 removeGeomGroupData( theGroup );
2377 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2379 // remove old instance of group from own map
2380 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2381 _mapGroups.erase( anId );
2383 SALOMEDS::StudyBuilder_var builder;
2384 SALOMEDS::SObject_wrap aGroupSO;
2385 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2386 if ( !aStudy->_is_nil() ) {
2387 builder = aStudy->NewBuilder();
2388 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2389 if ( !aGroupSO->_is_nil() )
2391 // remove reference to geometry
2392 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2393 for ( ; chItr->More(); chItr->Next() )
2394 // Remove group's child SObject
2395 builder->RemoveObject( chItr->Value() );
2397 // Update Python script
2398 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2399 << ".ConvertToStandalone( " << aGroupSO << " )";
2401 // change icon of Group on Filter
2404 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2405 const int isEmpty = ( elemTypes->length() == 0 );
2408 SALOMEDS::GenericAttribute_wrap anAttr =
2409 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2410 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2411 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2417 // remember new group in own map
2418 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2419 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2421 // register CORBA object for persistence
2422 _gen_i->RegisterObject( aGroup );
2424 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2425 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2426 //aGroup->Register();
2427 aGroupToRem->UnRegister();
2429 SMESH_CATCH( SMESH::throwCorbaException );
2431 return aGroup._retn();
2434 //=============================================================================
2438 //=============================================================================
2440 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2442 if(MYDEBUG) MESSAGE( "createSubMesh" );
2443 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2444 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2445 const int subMeshId = mySubMesh->GetId();
2447 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2448 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2450 _mapSubMesh [subMeshId] = mySubMesh;
2451 _mapSubMesh_i [subMeshId] = subMeshServant;
2452 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2454 subMeshServant->Register();
2456 // register CORBA object for persistence
2457 int nextId = _gen_i->RegisterObject( subMesh );
2458 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2459 else { nextId = 0; } // avoid "unused variable" warning
2461 // to track changes of GEOM groups
2462 addGeomGroupData( theSubShapeObject, subMesh );
2464 return subMesh._retn();
2467 //=======================================================================
2468 //function : getSubMesh
2470 //=======================================================================
2472 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2474 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2475 if ( it == _mapSubMeshIor.end() )
2476 return SMESH::SMESH_subMesh::_nil();
2478 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2481 //=============================================================================
2485 //=============================================================================
2487 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2488 GEOM::GEOM_Object_ptr theSubShapeObject )
2490 bool isHypChanged = false;
2491 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2492 return isHypChanged;
2494 const int subMeshId = theSubMesh->GetId();
2496 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2498 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2500 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2503 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2504 isHypChanged = !hyps.empty();
2505 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2506 for ( ; hyp != hyps.end(); ++hyp )
2507 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2514 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2515 isHypChanged = ( aHypList->length() > 0 );
2516 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2517 removeHypothesis( theSubShapeObject, aHypList[i] );
2520 catch( const SALOME::SALOME_Exception& ) {
2521 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2523 removeGeomGroupData( theSubShapeObject );
2527 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2528 if ( id_smi != _mapSubMesh_i.end() )
2529 id_smi->second->UnRegister();
2531 // remove a CORBA object
2532 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2533 if ( id_smptr != _mapSubMeshIor.end() )
2534 SMESH::SMESH_subMesh_var( id_smptr->second );
2536 _mapSubMesh.erase(subMeshId);
2537 _mapSubMesh_i.erase(subMeshId);
2538 _mapSubMeshIor.erase(subMeshId);
2540 return isHypChanged;
2543 //=============================================================================
2547 //=============================================================================
2549 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2550 const char* theName,
2551 const TopoDS_Shape& theShape,
2552 const SMESH_PredicatePtr& thePredicate )
2554 std::string newName;
2555 if ( !theName || strlen( theName ) == 0 )
2557 std::set< std::string > presentNames;
2558 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2559 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2561 CORBA::String_var name = i_gr->second->GetName();
2562 presentNames.insert( name.in() );
2565 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2566 } while ( !presentNames.insert( newName ).second );
2567 theName = newName.c_str();
2570 SMESH::SMESH_GroupBase_var aGroup;
2571 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2573 SMESH_GroupBase_i* aGroupImpl;
2574 if ( !theShape.IsNull() )
2575 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2576 else if ( thePredicate )
2577 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2579 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2581 aGroup = aGroupImpl->_this();
2582 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2583 aGroupImpl->Register();
2585 // register CORBA object for persistence
2586 int nextId = _gen_i->RegisterObject( aGroup );
2587 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2588 else { nextId = 0; } // avoid "unused variable" warning in release mode
2590 // to track changes of GEOM groups
2591 if ( !theShape.IsNull() ) {
2592 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2593 addGeomGroupData( geom, aGroup );
2596 return aGroup._retn();
2599 //=============================================================================
2601 * SMESH_Mesh_i::removeGroup
2603 * Should be called by ~SMESH_Group_i()
2605 //=============================================================================
2607 void SMESH_Mesh_i::removeGroup( const int theId )
2609 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2610 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2611 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2612 _mapGroups.erase( theId );
2613 removeGeomGroupData( group );
2614 if ( !_impl->RemoveGroup( theId ))
2616 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2617 RemoveGroup( group );
2619 group->UnRegister();
2623 //=============================================================================
2627 //=============================================================================
2629 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2630 throw(SALOME::SALOME_Exception)
2632 SMESH::log_array_var aLog;
2636 _preMeshInfo->FullLoadFromFile();
2638 list < SMESHDS_Command * >logDS = _impl->GetLog();
2639 aLog = new SMESH::log_array;
2641 int lg = logDS.size();
2644 list < SMESHDS_Command * >::iterator its = logDS.begin();
2645 while(its != logDS.end()){
2646 SMESHDS_Command *com = *its;
2647 int comType = com->GetType();
2649 int lgcom = com->GetNumber();
2651 const list < int >&intList = com->GetIndexes();
2652 int inum = intList.size();
2654 list < int >::const_iterator ii = intList.begin();
2655 const list < double >&coordList = com->GetCoords();
2656 int rnum = coordList.size();
2658 list < double >::const_iterator ir = coordList.begin();
2659 aLog[indexLog].commandType = comType;
2660 aLog[indexLog].number = lgcom;
2661 aLog[indexLog].coords.length(rnum);
2662 aLog[indexLog].indexes.length(inum);
2663 for(int i = 0; i < rnum; i++){
2664 aLog[indexLog].coords[i] = *ir;
2665 //MESSAGE(" "<<i<<" "<<ir.Value());
2668 for(int i = 0; i < inum; i++){
2669 aLog[indexLog].indexes[i] = *ii;
2670 //MESSAGE(" "<<i<<" "<<ii.Value());
2679 SMESH_CATCH( SMESH::throwCorbaException );
2681 return aLog._retn();
2685 //=============================================================================
2689 //=============================================================================
2691 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2695 SMESH_CATCH( SMESH::throwCorbaException );
2698 //=============================================================================
2702 //=============================================================================
2704 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2709 //=============================================================================
2713 //=============================================================================
2715 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2720 //=============================================================================
2723 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2724 // issue 0020918: groups removal is caused by hyp modification
2725 // issue 0021208: to forget not loaded mesh data at hyp modification
2726 struct TCallUp_i : public SMESH_Mesh::TCallUp
2728 SMESH_Mesh_i* _mesh;
2729 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2730 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2731 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2732 virtual void Load () { _mesh->Load(); }
2736 //================================================================================
2738 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2740 //================================================================================
2742 void SMESH_Mesh_i::onHypothesisModified()
2745 _preMeshInfo->ForgetOrLoad();
2748 //=============================================================================
2752 //=============================================================================
2754 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2756 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2759 _impl->SetCallUp( new TCallUp_i(this));
2762 //=============================================================================
2766 //=============================================================================
2768 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2770 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2774 //=============================================================================
2776 * Return mesh editor
2778 //=============================================================================
2780 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2781 throw (SALOME::SALOME_Exception)
2783 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2787 _preMeshInfo->FullLoadFromFile();
2789 // Create MeshEditor
2791 _editor = new SMESH_MeshEditor_i( this, false );
2792 aMeshEdVar = _editor->_this();
2794 // Update Python script
2795 TPythonDump() << _editor << " = "
2796 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2798 SMESH_CATCH( SMESH::throwCorbaException );
2800 return aMeshEdVar._retn();
2803 //=============================================================================
2805 * Return mesh edition previewer
2807 //=============================================================================
2809 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2810 throw (SALOME::SALOME_Exception)
2812 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2816 _preMeshInfo->FullLoadFromFile();
2818 if ( !_previewEditor )
2819 _previewEditor = new SMESH_MeshEditor_i( this, true );
2820 aMeshEdVar = _previewEditor->_this();
2822 SMESH_CATCH( SMESH::throwCorbaException );
2824 return aMeshEdVar._retn();
2827 //================================================================================
2829 * \brief Return true if the mesh has been edited since a last total re-compute
2830 * and those modifications may prevent successful partial re-compute
2832 //================================================================================
2834 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2836 Unexpect aCatch(SALOME_SalomeException);
2837 return _impl->HasModificationsToDiscard();
2840 //================================================================================
2842 * \brief Returns a random unique color
2844 //================================================================================
2846 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2848 const int MAX_ATTEMPTS = 100;
2850 double tolerance = 0.5;
2851 SALOMEDS::Color col;
2855 // generate random color
2856 double red = (double)rand() / RAND_MAX;
2857 double green = (double)rand() / RAND_MAX;
2858 double blue = (double)rand() / RAND_MAX;
2859 // check existence in the list of the existing colors
2860 bool matched = false;
2861 std::list<SALOMEDS::Color>::const_iterator it;
2862 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2863 SALOMEDS::Color color = *it;
2864 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2865 matched = tol < tolerance;
2867 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2868 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2876 //=============================================================================
2878 * Sets auto-color mode. If it is on, groups get unique random colors
2880 //=============================================================================
2882 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2884 Unexpect aCatch(SALOME_SalomeException);
2885 _impl->SetAutoColor(theAutoColor);
2887 TPythonDump pyDump; // not to dump group->SetColor() from below code
2888 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2890 std::list<SALOMEDS::Color> aReservedColors;
2891 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2892 for ( ; it != _mapGroups.end(); it++ ) {
2893 if ( CORBA::is_nil( it->second )) continue;
2894 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2895 it->second->SetColor( aColor );
2896 aReservedColors.push_back( aColor );
2900 //=============================================================================
2902 * Returns true if auto-color mode is on
2904 //=============================================================================
2906 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2908 Unexpect aCatch(SALOME_SalomeException);
2909 return _impl->GetAutoColor();
2912 //=============================================================================
2914 * Checks if there are groups with equal names
2916 //=============================================================================
2918 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2920 return _impl->HasDuplicatedGroupNamesMED();
2923 //================================================================================
2925 * \brief Care of a file before exporting mesh into it
2927 //================================================================================
2929 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2931 SMESH_File aFile( file );
2933 if (aFile.exists()) {
2934 // existing filesystem node
2935 if ( !aFile.isDirectory() ) {
2936 if ( aFile.openForWriting() ) {
2937 if ( overwrite && ! aFile.remove()) {
2938 msg << "Can't replace " << aFile.getName();
2941 msg << "Can't write into " << aFile.getName();
2944 msg << "Location " << aFile.getName() << " is not a file";
2948 // nonexisting file; check if it can be created
2949 if ( !aFile.openForWriting() ) {
2950 msg << "You cannot create the file "
2952 << ". Check the directory existence and access rights";
2960 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2964 //================================================================================
2966 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2967 * \param file - file name
2968 * \param overwrite - to erase the file or not
2969 * \retval string - mesh name
2971 //================================================================================
2973 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2974 CORBA::Boolean overwrite)
2977 PrepareForWriting(file, overwrite);
2978 string aMeshName = "Mesh";
2979 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2980 if ( !aStudy->_is_nil() ) {
2981 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2982 if ( !aMeshSO->_is_nil() ) {
2983 CORBA::String_var name = aMeshSO->GetName();
2985 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2986 if ( !aStudy->GetProperties()->IsLocked() )
2988 SALOMEDS::GenericAttribute_wrap anAttr;
2989 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2990 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2991 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2992 ASSERT(!aFileName->_is_nil());
2993 aFileName->SetValue(file);
2994 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2995 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2996 ASSERT(!aFileType->_is_nil());
2997 aFileType->SetValue("FICHIERMED");
3001 // Update Python script
3002 // set name of mesh before export
3003 TPythonDump() << _gen_i << ".SetName("
3004 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3006 // check names of groups
3012 //================================================================================
3014 * \brief Export to med file
3016 //================================================================================
3018 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3019 CORBA::Boolean auto_groups,
3020 SMESH::MED_VERSION theVersion,
3021 CORBA::Boolean overwrite,
3022 CORBA::Boolean autoDimension)
3023 throw(SALOME::SALOME_Exception)
3027 _preMeshInfo->FullLoadFromFile();
3029 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3030 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3032 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3033 << file << "', " << auto_groups << ", "
3034 << theVersion << ", " << overwrite << ", "
3035 << autoDimension << " )";
3037 SMESH_CATCH( SMESH::throwCorbaException );
3040 //================================================================================
3042 * \brief Export a mesh to a med file
3044 //================================================================================
3046 void SMESH_Mesh_i::ExportToMED (const char* file,
3047 CORBA::Boolean auto_groups,
3048 SMESH::MED_VERSION theVersion)
3049 throw(SALOME::SALOME_Exception)
3051 ExportToMEDX(file,auto_groups,theVersion,true);
3054 //================================================================================
3056 * \brief Export a mesh to a med file
3058 //================================================================================
3060 void SMESH_Mesh_i::ExportMED (const char* file,
3061 CORBA::Boolean auto_groups)
3062 throw(SALOME::SALOME_Exception)
3064 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3067 //================================================================================
3069 * \brief Export a mesh to a SAUV file
3071 //================================================================================
3073 void SMESH_Mesh_i::ExportSAUV (const char* file,
3074 CORBA::Boolean auto_groups)
3075 throw(SALOME::SALOME_Exception)
3077 Unexpect aCatch(SALOME_SalomeException);
3079 _preMeshInfo->FullLoadFromFile();
3081 string aMeshName = prepareMeshNameAndGroups(file, true);
3082 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3083 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3084 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3088 //================================================================================
3090 * \brief Export a mesh to a DAT file
3092 //================================================================================
3094 void SMESH_Mesh_i::ExportDAT (const char *file)
3095 throw(SALOME::SALOME_Exception)
3097 Unexpect aCatch(SALOME_SalomeException);
3099 _preMeshInfo->FullLoadFromFile();
3101 // Update Python script
3102 // check names of groups
3104 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3107 PrepareForWriting(file);
3108 _impl->ExportDAT(file);
3111 //================================================================================
3113 * \brief Export a mesh to an UNV file
3115 //================================================================================
3117 void SMESH_Mesh_i::ExportUNV (const char *file)
3118 throw(SALOME::SALOME_Exception)
3120 Unexpect aCatch(SALOME_SalomeException);
3122 _preMeshInfo->FullLoadFromFile();
3124 // Update Python script
3125 // check names of groups
3127 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3130 PrepareForWriting(file);
3131 _impl->ExportUNV(file);
3134 //================================================================================
3136 * \brief Export a mesh to an STL file
3138 //================================================================================
3140 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3141 throw(SALOME::SALOME_Exception)
3143 Unexpect aCatch(SALOME_SalomeException);
3145 _preMeshInfo->FullLoadFromFile();
3147 // Update Python script
3148 // check names of groups
3150 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3151 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3153 CORBA::String_var name;
3154 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3155 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() );
3156 if ( !so->_is_nil() )
3157 name = so->GetName();
3160 PrepareForWriting( file );
3161 _impl->ExportSTL( file, isascii, name.in() );
3164 //================================================================================
3166 * \brief Export a part of mesh to a med file
3168 //================================================================================
3170 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3172 CORBA::Boolean auto_groups,
3173 SMESH::MED_VERSION version,
3174 CORBA::Boolean overwrite,
3175 CORBA::Boolean autoDimension,
3176 const GEOM::ListOfFields& fields,
3177 const char* geomAssocFields)
3178 throw (SALOME::SALOME_Exception)
3182 _preMeshInfo->FullLoadFromFile();
3185 bool have0dField = false;
3186 if ( fields.length() > 0 )
3188 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3189 if ( shapeToMesh->_is_nil() )
3190 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3192 for ( size_t i = 0; i < fields.length(); ++i )
3194 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3195 THROW_SALOME_CORBA_EXCEPTION
3196 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3197 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3198 if ( fieldShape->_is_nil() )
3199 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3200 if ( !fieldShape->IsSame( shapeToMesh ) )
3201 THROW_SALOME_CORBA_EXCEPTION
3202 ( "Field defined not on shape", SALOME::BAD_PARAM);
3203 if ( fields[i]->GetDimension() == 0 )
3206 if ( geomAssocFields )
3207 for ( int i = 0; geomAssocFields[i]; ++i )
3208 switch ( geomAssocFields[i] ) {
3209 case 'v':case 'e':case 'f':case 's': break;
3210 case 'V':case 'E':case 'F':case 'S': break;
3211 default: THROW_SALOME_CORBA_EXCEPTION
3212 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3216 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3220 string aMeshName = "Mesh";
3221 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3222 if ( CORBA::is_nil( meshPart ) ||
3223 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3225 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3226 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3227 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3228 meshDS = _impl->GetMeshDS();
3233 _preMeshInfo->FullLoadFromFile();
3235 PrepareForWriting(file, overwrite);
3237 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3238 if ( !aStudy->_is_nil() ) {
3239 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3240 if ( !SO->_is_nil() ) {
3241 CORBA::String_var name = SO->GetName();
3245 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3246 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3247 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3248 meshDS = tmpDSDeleter._obj = partDS;
3253 if ( _impl->HasShapeToMesh() )
3255 DriverMED_W_Field fieldWriter;
3256 fieldWriter.SetFile( file );
3257 fieldWriter.SetMeshName( aMeshName );
3258 fieldWriter.AddODOnVertices( have0dField );
3260 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3264 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3265 goList->length( fields.length() );
3266 for ( size_t i = 0; i < fields.length(); ++i )
3268 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3271 TPythonDump() << _this() << ".ExportPartToMED( "
3272 << meshPart << ", r'" << file << "', "
3273 << auto_groups << ", " << version << ", " << overwrite << ", "
3274 << autoDimension << ", " << goList
3275 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3277 SMESH_CATCH( SMESH::throwCorbaException );
3280 //================================================================================
3282 * Write GEOM fields to MED file
3284 //================================================================================
3286 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3287 SMESHDS_Mesh* meshDS,
3288 const GEOM::ListOfFields& fields,
3289 const char* geomAssocFields)
3291 #define METH "SMESH_Mesh_i::exportMEDFields() "
3293 if (( fields.length() < 1 ) &&
3294 ( !geomAssocFields || !geomAssocFields[0] ))
3297 std::vector< std::vector< double > > dblVals;
3298 std::vector< std::vector< int > > intVals;
3299 std::vector< int > subIdsByDim[ 4 ];
3300 const double noneDblValue = 0.;
3301 const double noneIntValue = 0;
3303 for ( size_t iF = 0; iF < fields.length(); ++iF )
3307 int dim = fields[ iF ]->GetDimension();
3308 SMDSAbs_ElementType elemType;
3309 TopAbs_ShapeEnum shapeType;
3311 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3312 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3313 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3314 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3316 continue; // skip fields on whole shape
3318 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3319 if ( dataType == GEOM::FDT_String )
3321 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3322 if ( stepIDs->length() < 1 )
3324 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3325 if ( comps->length() < 1 )
3327 CORBA::String_var name = fields[ iF ]->GetName();
3329 if ( !fieldWriter.Set( meshDS,
3333 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3336 for ( size_t iC = 0; iC < comps->length(); ++iC )
3337 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3339 dblVals.resize( comps->length() );
3340 intVals.resize( comps->length() );
3342 // find sub-shape IDs
3344 std::vector< int >& subIds = subIdsByDim[ dim ];
3345 if ( subIds.empty() )
3346 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3347 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3348 subIds.push_back( id );
3352 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3356 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3358 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3359 if ( step->_is_nil() )
3362 CORBA::Long stamp = step->GetStamp();
3363 CORBA::Long id = step->GetID();
3364 fieldWriter.SetDtIt( int( stamp ), int( id ));
3366 // fill dblVals or intVals
3367 for ( size_t iC = 0; iC < comps->length(); ++iC )
3368 if ( dataType == GEOM::FDT_Double )
3370 dblVals[ iC ].clear();
3371 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3375 intVals[ iC ].clear();
3376 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3380 case GEOM::FDT_Double:
3382 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3383 if ( dblStep->_is_nil() ) continue;
3384 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3385 if ( vv->length() != subIds.size() * comps->length() )
3386 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3387 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3388 for ( size_t iC = 0; iC < comps->length(); ++iC )
3389 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3394 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3395 if ( intStep->_is_nil() ) continue;
3396 GEOM::ListOfLong_var vv = intStep->GetValues();
3397 if ( vv->length() != subIds.size() * comps->length() )
3398 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3399 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3400 for ( size_t iC = 0; iC < comps->length(); ++iC )
3401 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3404 case GEOM::FDT_Bool:
3406 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3407 if ( boolStep->_is_nil() ) continue;
3408 GEOM::short_array_var vv = boolStep->GetValues();
3409 if ( vv->length() != subIds.size() * comps->length() )
3410 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3411 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3412 for ( size_t iC = 0; iC < comps->length(); ++iC )
3413 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3419 // pass values to fieldWriter
3420 elemIt = fieldWriter.GetOrderedElems();
3421 if ( dataType == GEOM::FDT_Double )
3422 while ( elemIt->more() )
3424 const SMDS_MeshElement* e = elemIt->next();
3425 const int shapeID = e->getshapeId();
3426 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3427 for ( size_t iC = 0; iC < comps->length(); ++iC )
3428 fieldWriter.AddValue( noneDblValue );
3430 for ( size_t iC = 0; iC < comps->length(); ++iC )
3431 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3434 while ( elemIt->more() )
3436 const SMDS_MeshElement* e = elemIt->next();
3437 const int shapeID = e->getshapeId();
3438 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3439 for ( size_t iC = 0; iC < comps->length(); ++iC )
3440 fieldWriter.AddValue( (double) noneIntValue );
3442 for ( size_t iC = 0; iC < comps->length(); ++iC )
3443 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3447 fieldWriter.Perform();
3448 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3449 if ( res && res->IsKO() )
3451 if ( res->myComment.empty() )
3452 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3454 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3460 if ( !geomAssocFields || !geomAssocFields[0] )
3463 // write geomAssocFields
3465 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3466 shapeDim[ TopAbs_COMPOUND ] = 3;
3467 shapeDim[ TopAbs_COMPSOLID ] = 3;
3468 shapeDim[ TopAbs_SOLID ] = 3;
3469 shapeDim[ TopAbs_SHELL ] = 2;
3470 shapeDim[ TopAbs_FACE ] = 2;
3471 shapeDim[ TopAbs_WIRE ] = 1;
3472 shapeDim[ TopAbs_EDGE ] = 1;
3473 shapeDim[ TopAbs_VERTEX ] = 0;
3474 shapeDim[ TopAbs_SHAPE ] = 3;
3476 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3478 std::vector< std::string > compNames;
3479 switch ( geomAssocFields[ iF ]) {
3481 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3482 compNames.push_back( "dim" );
3485 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3488 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3491 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3495 compNames.push_back( "id" );
3496 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3497 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3499 fieldWriter.SetDtIt( -1, -1 );
3501 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3505 if ( compNames.size() == 2 ) // _vertices_
3506 while ( elemIt->more() )
3508 const SMDS_MeshElement* e = elemIt->next();
3509 const int shapeID = e->getshapeId();
3512 fieldWriter.AddValue( (double) -1 );
3513 fieldWriter.AddValue( (double) -1 );
3517 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3518 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3519 fieldWriter.AddValue( (double) shapeID );
3523 while ( elemIt->more() )
3525 const SMDS_MeshElement* e = elemIt->next();
3526 const int shapeID = e->getshapeId();
3528 fieldWriter.AddValue( (double) -1 );
3530 fieldWriter.AddValue( (double) shapeID );
3534 fieldWriter.Perform();
3535 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3536 if ( res && res->IsKO() )
3538 if ( res->myComment.empty() )
3539 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3541 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3544 } // loop on geomAssocFields
3549 //================================================================================
3551 * \brief Export a part of mesh to a DAT file
3553 //================================================================================
3555 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3557 throw (SALOME::SALOME_Exception)
3559 Unexpect aCatch(SALOME_SalomeException);
3561 _preMeshInfo->FullLoadFromFile();
3563 PrepareForWriting(file);
3565 SMESH_MeshPartDS partDS( meshPart );
3566 _impl->ExportDAT(file,&partDS);
3568 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3569 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3571 //================================================================================
3573 * \brief Export a part of mesh to an UNV file
3575 //================================================================================
3577 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3579 throw (SALOME::SALOME_Exception)
3581 Unexpect aCatch(SALOME_SalomeException);
3583 _preMeshInfo->FullLoadFromFile();
3585 PrepareForWriting(file);
3587 SMESH_MeshPartDS partDS( meshPart );
3588 _impl->ExportUNV(file, &partDS);
3590 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3591 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3593 //================================================================================
3595 * \brief Export a part of mesh to an STL file
3597 //================================================================================
3599 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3601 ::CORBA::Boolean isascii)
3602 throw (SALOME::SALOME_Exception)
3604 Unexpect aCatch(SALOME_SalomeException);
3606 _preMeshInfo->FullLoadFromFile();
3608 PrepareForWriting(file);
3610 CORBA::String_var name;
3611 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3612 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3613 if ( !so->_is_nil() )
3614 name = so->GetName();
3616 SMESH_MeshPartDS partDS( meshPart );
3617 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3619 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3620 << meshPart<< ", r'" << file << "', " << isascii << ")";
3623 //================================================================================
3625 * \brief Export a part of mesh to an STL file
3627 //================================================================================
3629 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3631 CORBA::Boolean overwrite)
3632 throw (SALOME::SALOME_Exception)
3635 Unexpect aCatch(SALOME_SalomeException);
3637 _preMeshInfo->FullLoadFromFile();
3639 PrepareForWriting(file,overwrite);
3641 std::string meshName("");
3642 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3643 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3644 if ( !so->_is_nil() )
3646 CORBA::String_var name = so->GetName();
3647 meshName = name.in();
3649 SMESH_MeshPartDS partDS( meshPart );
3650 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3652 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3653 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3655 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3659 //================================================================================
3661 * \brief Export a part of mesh to a GMF file
3663 //================================================================================
3665 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3667 bool withRequiredGroups)
3668 throw (SALOME::SALOME_Exception)
3670 Unexpect aCatch(SALOME_SalomeException);
3672 _preMeshInfo->FullLoadFromFile();
3674 PrepareForWriting(file,/*overwrite=*/true);
3676 SMESH_MeshPartDS partDS( meshPart );
3677 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3679 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3680 << meshPart<< ", r'"
3682 << withRequiredGroups << ")";
3685 //=============================================================================
3687 * Return computation progress [0.,1]
3689 //=============================================================================
3691 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3695 return _impl->GetComputeProgress();
3697 SMESH_CATCH( SMESH::doNothing );
3701 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3703 Unexpect aCatch(SALOME_SalomeException);
3705 return _preMeshInfo->NbNodes();
3707 return _impl->NbNodes();
3710 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3712 Unexpect aCatch(SALOME_SalomeException);
3714 return _preMeshInfo->NbElements();
3716 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3719 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->Nb0DElements();
3725 return _impl->Nb0DElements();
3728 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 return _preMeshInfo->NbBalls();
3734 return _impl->NbBalls();
3737 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3739 Unexpect aCatch(SALOME_SalomeException);
3741 return _preMeshInfo->NbEdges();
3743 return _impl->NbEdges();
3746 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3747 throw(SALOME::SALOME_Exception)
3749 Unexpect aCatch(SALOME_SalomeException);
3751 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3753 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3756 //=============================================================================
3758 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3760 Unexpect aCatch(SALOME_SalomeException);
3762 return _preMeshInfo->NbFaces();
3764 return _impl->NbFaces();
3767 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3769 Unexpect aCatch(SALOME_SalomeException);
3771 return _preMeshInfo->NbTriangles();
3773 return _impl->NbTriangles();
3776 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3778 Unexpect aCatch(SALOME_SalomeException);
3780 return _preMeshInfo->NbBiQuadTriangles();
3782 return _impl->NbBiQuadTriangles();
3785 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3787 Unexpect aCatch(SALOME_SalomeException);
3789 return _preMeshInfo->NbQuadrangles();
3791 return _impl->NbQuadrangles();
3794 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3796 Unexpect aCatch(SALOME_SalomeException);
3798 return _preMeshInfo->NbBiQuadQuadrangles();
3800 return _impl->NbBiQuadQuadrangles();
3803 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3805 Unexpect aCatch(SALOME_SalomeException);
3807 return _preMeshInfo->NbPolygons();
3809 return _impl->NbPolygons();
3812 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3814 Unexpect aCatch(SALOME_SalomeException);
3816 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3818 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3821 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3822 throw(SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3828 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3831 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3832 throw(SALOME::SALOME_Exception)
3834 Unexpect aCatch(SALOME_SalomeException);
3836 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3838 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3841 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3842 throw(SALOME::SALOME_Exception)
3844 Unexpect aCatch(SALOME_SalomeException);
3846 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3848 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3851 //=============================================================================
3853 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3855 Unexpect aCatch(SALOME_SalomeException);
3857 return _preMeshInfo->NbVolumes();
3859 return _impl->NbVolumes();
3862 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3864 Unexpect aCatch(SALOME_SalomeException);
3866 return _preMeshInfo->NbTetras();
3868 return _impl->NbTetras();
3871 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3873 Unexpect aCatch(SALOME_SalomeException);
3875 return _preMeshInfo->NbHexas();
3877 return _impl->NbHexas();
3880 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3882 Unexpect aCatch(SALOME_SalomeException);
3884 return _preMeshInfo->NbTriQuadHexas();
3886 return _impl->NbTriQuadraticHexas();
3889 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3891 Unexpect aCatch(SALOME_SalomeException);
3893 return _preMeshInfo->NbPyramids();
3895 return _impl->NbPyramids();
3898 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3900 Unexpect aCatch(SALOME_SalomeException);
3902 return _preMeshInfo->NbPrisms();
3904 return _impl->NbPrisms();
3907 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3909 Unexpect aCatch(SALOME_SalomeException);
3911 return _preMeshInfo->NbHexPrisms();
3913 return _impl->NbHexagonalPrisms();
3916 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3918 Unexpect aCatch(SALOME_SalomeException);
3920 return _preMeshInfo->NbPolyhedrons();
3922 return _impl->NbPolyhedrons();
3925 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3926 throw(SALOME::SALOME_Exception)
3928 Unexpect aCatch(SALOME_SalomeException);
3930 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3932 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3935 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3936 throw(SALOME::SALOME_Exception)
3938 Unexpect aCatch(SALOME_SalomeException);
3940 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3942 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3945 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3946 throw(SALOME::SALOME_Exception)
3948 Unexpect aCatch(SALOME_SalomeException);
3950 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3952 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3955 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3956 throw(SALOME::SALOME_Exception)
3958 Unexpect aCatch(SALOME_SalomeException);
3960 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3962 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3965 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3966 throw(SALOME::SALOME_Exception)
3968 Unexpect aCatch(SALOME_SalomeException);
3970 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3972 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3975 //=============================================================================
3977 * Returns nb of published sub-meshes
3979 //=============================================================================
3981 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3983 Unexpect aCatch(SALOME_SalomeException);
3984 return _mapSubMesh_i.size();
3987 //=============================================================================
3989 * Dumps mesh into a string
3991 //=============================================================================
3993 char* SMESH_Mesh_i::Dump()
3997 return CORBA::string_dup( os.str().c_str() );
4000 //=============================================================================
4002 * Method of SMESH_IDSource interface
4004 //=============================================================================
4006 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4008 return GetElementsId();
4011 //=============================================================================
4013 * Returns ids of all elements
4015 //=============================================================================
4017 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4018 throw (SALOME::SALOME_Exception)
4020 Unexpect aCatch(SALOME_SalomeException);
4022 _preMeshInfo->FullLoadFromFile();
4024 SMESH::long_array_var aResult = new SMESH::long_array();
4025 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4027 if ( aSMESHDS_Mesh == NULL )
4028 return aResult._retn();
4030 long nbElements = NbElements();
4031 aResult->length( nbElements );
4032 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4033 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4034 aResult[i] = anIt->next()->GetID();
4036 return aResult._retn();
4040 //=============================================================================
4042 * Returns ids of all elements of given type
4044 //=============================================================================
4046 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4047 throw (SALOME::SALOME_Exception)
4049 Unexpect aCatch(SALOME_SalomeException);
4051 _preMeshInfo->FullLoadFromFile();
4053 SMESH::long_array_var aResult = new SMESH::long_array();
4054 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4056 if ( aSMESHDS_Mesh == NULL )
4057 return aResult._retn();
4059 long nbElements = NbElements();
4061 // No sense in returning ids of elements along with ids of nodes:
4062 // when theElemType == SMESH::ALL, return node ids only if
4063 // there are no elements
4064 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4065 return GetNodesId();
4067 aResult->length( nbElements );
4071 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4072 while ( i < nbElements && anIt->more() )
4073 aResult[i++] = anIt->next()->GetID();
4075 aResult->length( i );
4077 return aResult._retn();
4080 //=============================================================================
4082 * Returns ids of all nodes
4084 //=============================================================================
4086 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4087 throw (SALOME::SALOME_Exception)
4089 Unexpect aCatch(SALOME_SalomeException);
4091 _preMeshInfo->FullLoadFromFile();
4093 SMESH::long_array_var aResult = new SMESH::long_array();
4094 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4096 if ( aSMESHDS_Mesh == NULL )
4097 return aResult._retn();
4099 long nbNodes = NbNodes();
4100 aResult->length( nbNodes );
4101 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4102 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4103 aResult[i] = anIt->next()->GetID();
4105 return aResult._retn();
4108 //=============================================================================
4112 //=============================================================================
4114 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4115 throw (SALOME::SALOME_Exception)
4117 SMESH::ElementType type = SMESH::ALL;
4121 _preMeshInfo->FullLoadFromFile();
4123 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4125 SMESH_CATCH( SMESH::throwCorbaException );
4130 //=============================================================================
4134 //=============================================================================
4136 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4137 throw (SALOME::SALOME_Exception)
4140 _preMeshInfo->FullLoadFromFile();
4142 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4144 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4146 return ( SMESH::EntityType ) e->GetEntityType();
4149 //=============================================================================
4153 //=============================================================================
4155 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4156 throw (SALOME::SALOME_Exception)
4159 _preMeshInfo->FullLoadFromFile();
4161 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4163 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4165 return ( SMESH::GeometryType ) e->GetGeomType();
4168 //=============================================================================
4170 * Returns ID of elements for given submesh
4172 //=============================================================================
4173 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4174 throw (SALOME::SALOME_Exception)
4176 SMESH::long_array_var aResult = new SMESH::long_array();
4180 _preMeshInfo->FullLoadFromFile();
4182 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4183 if(!SM) return aResult._retn();
4185 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4186 if(!SDSM) return aResult._retn();
4188 aResult->length(SDSM->NbElements());
4190 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4192 while ( eIt->more() ) {
4193 aResult[i++] = eIt->next()->GetID();
4196 SMESH_CATCH( SMESH::throwCorbaException );
4198 return aResult._retn();
4201 //=============================================================================
4203 * Returns ID of nodes for given submesh
4204 * If param all==true - returns all nodes, else -
4205 * returns only nodes on shapes.
4207 //=============================================================================
4209 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4211 throw (SALOME::SALOME_Exception)
4213 SMESH::long_array_var aResult = new SMESH::long_array();
4217 _preMeshInfo->FullLoadFromFile();
4219 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4220 if(!SM) return aResult._retn();
4222 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4223 if(!SDSM) return aResult._retn();
4226 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4227 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4228 while ( nIt->more() ) {
4229 const SMDS_MeshNode* elem = nIt->next();
4230 theElems.insert( elem->GetID() );
4233 else { // all nodes of submesh elements
4234 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4235 while ( eIt->more() ) {
4236 const SMDS_MeshElement* anElem = eIt->next();
4237 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4238 while ( nIt->more() ) {
4239 const SMDS_MeshElement* elem = nIt->next();
4240 theElems.insert( elem->GetID() );
4245 aResult->length(theElems.size());
4246 set<int>::iterator itElem;
4248 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4249 aResult[i++] = *itElem;
4251 SMESH_CATCH( SMESH::throwCorbaException );
4253 return aResult._retn();
4256 //=============================================================================
4258 * Returns type of elements for given submesh
4260 //=============================================================================
4262 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4263 throw (SALOME::SALOME_Exception)
4265 SMESH::ElementType type = SMESH::ALL;
4269 _preMeshInfo->FullLoadFromFile();
4271 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4272 if(!SM) return SMESH::ALL;
4274 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4275 if(!SDSM) return SMESH::ALL;
4277 if(SDSM->NbElements()==0)
4278 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4280 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4281 const SMDS_MeshElement* anElem = eIt->next();
4283 type = ( SMESH::ElementType ) anElem->GetType();
4285 SMESH_CATCH( SMESH::throwCorbaException );
4291 //=============================================================================
4293 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4295 //=============================================================================
4297 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4300 _preMeshInfo->FullLoadFromFile();
4302 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4303 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4308 //=============================================================================
4310 * Get XYZ coordinates of node as list of double
4311 * If there is not node for given ID - returns empty list
4313 //=============================================================================
4315 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4318 _preMeshInfo->FullLoadFromFile();
4320 SMESH::double_array_var aResult = new SMESH::double_array();
4321 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4322 if ( aSMESHDS_Mesh == NULL )
4323 return aResult._retn();
4326 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4328 return aResult._retn();
4332 aResult[0] = aNode->X();
4333 aResult[1] = aNode->Y();
4334 aResult[2] = aNode->Z();
4335 return aResult._retn();
4339 //=============================================================================
4341 * For given node returns list of IDs of inverse elements
4342 * If there is not node for given ID - returns empty list
4344 //=============================================================================
4346 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4349 _preMeshInfo->FullLoadFromFile();
4351 SMESH::long_array_var aResult = new SMESH::long_array();
4352 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4353 if ( aSMESHDS_Mesh == NULL )
4354 return aResult._retn();
4357 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4359 return aResult._retn();
4361 // find inverse elements
4362 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4363 aResult->length( aNode->NbInverseElements() );
4364 for( int i = 0; eIt->more(); ++i )
4366 const SMDS_MeshElement* elem = eIt->next();
4367 aResult[ i ] = elem->GetID();
4369 return aResult._retn();
4372 //=============================================================================
4374 * \brief Return position of a node on shape
4376 //=============================================================================
4378 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4381 _preMeshInfo->FullLoadFromFile();
4383 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4384 aNodePosition->shapeID = 0;
4385 aNodePosition->shapeType = GEOM::SHAPE;
4387 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4388 if ( !mesh ) return aNodePosition;
4390 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4392 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4394 aNodePosition->shapeID = aNode->getshapeId();
4395 switch ( pos->GetTypeOfPosition() ) {
4397 aNodePosition->shapeType = GEOM::EDGE;
4398 aNodePosition->params.length(1);
4399 aNodePosition->params[0] =
4400 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4403 aNodePosition->shapeType = GEOM::FACE;
4404 aNodePosition->params.length(2);
4405 aNodePosition->params[0] =
4406 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4407 aNodePosition->params[1] =
4408 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4410 case SMDS_TOP_VERTEX:
4411 aNodePosition->shapeType = GEOM::VERTEX;
4413 case SMDS_TOP_3DSPACE:
4414 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4415 aNodePosition->shapeType = GEOM::SOLID;
4416 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4417 aNodePosition->shapeType = GEOM::SHELL;
4423 return aNodePosition;
4426 //=============================================================================
4428 * \brief Return position of an element on shape
4430 //=============================================================================
4432 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4435 _preMeshInfo->FullLoadFromFile();
4437 SMESH::ElementPosition anElementPosition;
4438 anElementPosition.shapeID = 0;
4439 anElementPosition.shapeType = GEOM::SHAPE;
4441 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4442 if ( !mesh ) return anElementPosition;
4444 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4446 anElementPosition.shapeID = anElem->getshapeId();
4447 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4448 if ( !aSp.IsNull() ) {
4449 switch ( aSp.ShapeType() ) {
4451 anElementPosition.shapeType = GEOM::EDGE;
4454 anElementPosition.shapeType = GEOM::FACE;
4457 anElementPosition.shapeType = GEOM::VERTEX;
4460 anElementPosition.shapeType = GEOM::SOLID;
4463 anElementPosition.shapeType = GEOM::SHELL;
4469 return anElementPosition;
4472 //=============================================================================
4474 * If given element is node returns IDs of shape from position
4475 * If there is not node for given ID - returns -1
4477 //=============================================================================
4479 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4482 _preMeshInfo->FullLoadFromFile();
4484 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4485 if ( aSMESHDS_Mesh == NULL )
4489 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4491 return aNode->getshapeId();
4498 //=============================================================================
4500 * For given element returns ID of result shape after
4501 * ::FindShape() from SMESH_MeshEditor
4502 * If there is not element for given ID - returns -1
4504 //=============================================================================
4506 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4509 _preMeshInfo->FullLoadFromFile();
4511 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4512 if ( aSMESHDS_Mesh == NULL )
4515 // try to find element
4516 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4520 ::SMESH_MeshEditor aMeshEditor(_impl);
4521 int index = aMeshEditor.FindShape( elem );
4529 //=============================================================================
4531 * Returns number of nodes for given element
4532 * If there is not element for given ID - returns -1
4534 //=============================================================================
4536 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4539 _preMeshInfo->FullLoadFromFile();
4541 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4542 if ( aSMESHDS_Mesh == NULL ) return -1;
4543 // try to find element
4544 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4545 if(!elem) return -1;
4546 return elem->NbNodes();
4550 //=============================================================================
4552 * Returns ID of node by given index for given element
4553 * If there is not element for given ID - returns -1
4554 * If there is not node for given index - returns -2
4556 //=============================================================================
4558 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4561 _preMeshInfo->FullLoadFromFile();
4563 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4564 if ( aSMESHDS_Mesh == NULL ) return -1;
4565 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4566 if(!elem) return -1;
4567 if( index>=elem->NbNodes() || index<0 ) return -1;
4568 return elem->GetNode(index)->GetID();
4571 //=============================================================================
4573 * Returns IDs of nodes of given element
4575 //=============================================================================
4577 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4580 _preMeshInfo->FullLoadFromFile();
4582 SMESH::long_array_var aResult = new SMESH::long_array();
4583 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4585 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4587 aResult->length( elem->NbNodes() );
4588 for ( int i = 0; i < elem->NbNodes(); ++i )
4589 aResult[ i ] = elem->GetNode( i )->GetID();
4592 return aResult._retn();
4595 //=============================================================================
4597 * Returns true if given node is medium node
4598 * in given quadratic element
4600 //=============================================================================
4602 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4605 _preMeshInfo->FullLoadFromFile();
4607 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4608 if ( aSMESHDS_Mesh == NULL ) return false;
4610 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4611 if(!aNode) return false;
4612 // try to find element
4613 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4614 if(!elem) return false;
4616 return elem->IsMediumNode(aNode);
4620 //=============================================================================
4622 * Returns true if given node is medium node
4623 * in one of quadratic elements
4625 //=============================================================================
4627 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4628 SMESH::ElementType theElemType)
4631 _preMeshInfo->FullLoadFromFile();
4633 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4634 if ( aSMESHDS_Mesh == NULL ) return false;
4637 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4638 if(!aNode) return false;
4640 SMESH_MesherHelper aHelper( *(_impl) );
4642 SMDSAbs_ElementType aType;
4643 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4644 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4645 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4646 else aType = SMDSAbs_All;
4648 return aHelper.IsMedium(aNode,aType);
4652 //=============================================================================
4654 * Returns number of edges for given element
4656 //=============================================================================
4658 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4661 _preMeshInfo->FullLoadFromFile();
4663 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4664 if ( aSMESHDS_Mesh == NULL ) return -1;
4665 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4666 if(!elem) return -1;
4667 return elem->NbEdges();
4671 //=============================================================================
4673 * Returns number of faces for given element
4675 //=============================================================================
4677 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4680 _preMeshInfo->FullLoadFromFile();
4682 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4683 if ( aSMESHDS_Mesh == NULL ) return -1;
4684 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4685 if(!elem) return -1;
4686 return elem->NbFaces();
4689 //=======================================================================
4690 //function : GetElemFaceNodes
4691 //purpose : Returns nodes of given face (counted from zero) for given element.
4692 //=======================================================================
4694 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4695 CORBA::Short faceIndex)
4698 _preMeshInfo->FullLoadFromFile();
4700 SMESH::long_array_var aResult = new SMESH::long_array();
4701 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4703 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4705 SMDS_VolumeTool vtool( elem );
4706 if ( faceIndex < vtool.NbFaces() )
4708 aResult->length( vtool.NbFaceNodes( faceIndex ));
4709 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4710 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4711 aResult[ i ] = nn[ i ]->GetID();
4715 return aResult._retn();
4718 //=======================================================================
4719 //function : GetElemFaceNodes
4720 //purpose : Returns three components of normal of given mesh face.
4721 //=======================================================================
4723 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4724 CORBA::Boolean normalized)
4727 _preMeshInfo->FullLoadFromFile();
4729 SMESH::double_array_var aResult = new SMESH::double_array();
4731 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4734 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4736 aResult->length( 3 );
4737 aResult[ 0 ] = normal.X();
4738 aResult[ 1 ] = normal.Y();
4739 aResult[ 2 ] = normal.Z();
4742 return aResult._retn();
4745 //=======================================================================
4746 //function : FindElementByNodes
4747 //purpose : Returns an element based on all given nodes.
4748 //=======================================================================
4750 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4753 _preMeshInfo->FullLoadFromFile();
4755 CORBA::Long elemID(0);
4756 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4758 vector< const SMDS_MeshNode * > nn( nodes.length() );
4759 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4760 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4763 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4764 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4765 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4766 _impl->NbVolumes( ORDER_QUADRATIC )))
4767 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4769 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4774 //=============================================================================
4776 * Returns true if given element is polygon
4778 //=============================================================================
4780 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4783 _preMeshInfo->FullLoadFromFile();
4785 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4786 if ( aSMESHDS_Mesh == NULL ) return false;
4787 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4788 if(!elem) return false;
4789 return elem->IsPoly();
4793 //=============================================================================
4795 * Returns true if given element is quadratic
4797 //=============================================================================
4799 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4802 _preMeshInfo->FullLoadFromFile();
4804 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4805 if ( aSMESHDS_Mesh == NULL ) return false;
4806 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4807 if(!elem) return false;
4808 return elem->IsQuadratic();
4811 //=============================================================================
4813 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4815 //=============================================================================
4817 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4820 _preMeshInfo->FullLoadFromFile();
4822 if ( const SMDS_BallElement* ball =
4823 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4824 return ball->GetDiameter();
4829 //=============================================================================
4831 * Returns bary center for given element
4833 //=============================================================================
4835 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4838 _preMeshInfo->FullLoadFromFile();
4840 SMESH::double_array_var aResult = new SMESH::double_array();
4841 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4842 if ( aSMESHDS_Mesh == NULL )
4843 return aResult._retn();
4845 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4847 return aResult._retn();
4849 if(elem->GetType()==SMDSAbs_Volume) {
4850 SMDS_VolumeTool aTool;
4851 if(aTool.Set(elem)) {
4853 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4858 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4860 double x=0., y=0., z=0.;
4861 for(; anIt->more(); ) {
4863 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4877 return aResult._retn();
4880 //================================================================================
4882 * \brief Create a group of elements preventing computation of a sub-shape
4884 //================================================================================
4886 SMESH::ListOfGroups*
4887 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4888 const char* theGroupName )
4889 throw ( SALOME::SALOME_Exception )
4891 Unexpect aCatch(SALOME_SalomeException);
4893 if ( !theGroupName || strlen( theGroupName) == 0 )
4894 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4896 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4897 ::SMESH_MeshEditor::ElemFeatures elemType;
4899 // submesh by subshape id
4900 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4901 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4904 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4905 if ( error && !error->myBadElements.empty())
4907 // sort bad elements by type
4908 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4909 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4910 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4911 for ( ; elemIt != elemEnd; ++elemIt )
4913 const SMDS_MeshElement* elem = *elemIt;
4914 if ( !elem ) continue;
4916 if ( elem->GetID() < 1 )
4918 // elem is a temporary element, make a real element
4919 vector< const SMDS_MeshNode* > nodes;
4920 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4921 while ( nIt->more() && elem )
4923 nodes.push_back( nIt->next() );
4924 if ( nodes.back()->GetID() < 1 )
4925 elem = 0; // a temporary element on temporary nodes
4929 ::SMESH_MeshEditor editor( _impl );
4930 elem = editor.AddElement( nodes, elemType.Init( elem ));
4934 elemsByType[ elem->GetType() ].push_back( elem );
4937 // how many groups to create?
4939 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4940 nbTypes += int( !elemsByType[ i ].empty() );
4941 groups->length( nbTypes );
4944 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4946 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4947 if ( elems.empty() ) continue;
4949 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4950 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4952 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4953 SMESH::SMESH_Mesh_var mesh = _this();
4954 SALOMEDS::SObject_wrap aSO =
4955 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4956 GEOM::GEOM_Object::_nil(), theGroupName);
4958 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4959 if ( !grp_i ) continue;
4961 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4962 for ( size_t iE = 0; iE < elems.size(); ++iE )
4963 grpDS->SMDSGroup().Add( elems[ iE ]);
4968 return groups._retn();
4971 //=============================================================================
4973 * Create and publish group servants if any groups were imported or created anyhow
4975 //=============================================================================
4977 void SMESH_Mesh_i::CreateGroupServants()
4979 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4980 SMESH::SMESH_Mesh_var aMesh = _this();
4983 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4984 while ( groupIt->more() )
4986 ::SMESH_Group* group = groupIt->next();
4987 int anId = group->GetGroupDS()->GetID();
4989 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4990 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4992 addedIDs.insert( anId );
4994 SMESH_GroupBase_i* aGroupImpl;
4996 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4997 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4999 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5000 shape = groupOnGeom->GetShape();
5003 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5006 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5007 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5008 aGroupImpl->Register();
5010 // register CORBA object for persistence
5011 int nextId = _gen_i->RegisterObject( groupVar );
5012 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5013 else { nextId = 0; } // avoid "unused variable" warning in release mode
5015 // publishing the groups in the study
5016 if ( !aStudy->_is_nil() ) {
5017 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5018 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5021 if ( !addedIDs.empty() )
5024 set<int>::iterator id = addedIDs.begin();
5025 for ( ; id != addedIDs.end(); ++id )
5027 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5028 int i = std::distance( _mapGroups.begin(), it );
5029 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5034 //=============================================================================
5036 * \brief Return groups cantained in _mapGroups by their IDs
5038 //=============================================================================
5040 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5042 int nbGroups = groupIDs.size();
5043 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5044 aList->length( nbGroups );
5046 list<int>::const_iterator ids = groupIDs.begin();
5047 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5049 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5050 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5051 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5053 aList->length( nbGroups );
5054 return aList._retn();
5057 //=============================================================================
5059 * \brief Return information about imported file
5061 //=============================================================================
5063 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5065 SMESH::MedFileInfo_var res( _medFileInfo );
5066 if ( !res.operator->() ) {
5067 res = new SMESH::MedFileInfo;
5069 res->fileSize = res->major = res->minor = res->release = -1;
5074 //=============================================================================
5076 * \brief Pass names of mesh groups from study to mesh DS
5078 //=============================================================================
5080 void SMESH_Mesh_i::checkGroupNames()
5082 int nbGrp = NbGroups();
5086 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5087 if ( aStudy->_is_nil() )
5088 return; // nothing to do
5090 SMESH::ListOfGroups* grpList = 0;
5091 // avoid dump of "GetGroups"
5093 // store python dump into a local variable inside local scope
5094 SMESH::TPythonDump pDump; // do not delete this line of code
5095 grpList = GetGroups();
5098 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5099 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5102 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5103 if ( aGrpSO->_is_nil() )
5105 // correct name of the mesh group if necessary
5106 const char* guiName = aGrpSO->GetName();
5107 if ( strcmp(guiName, aGrp->GetName()) )
5108 aGrp->SetName( guiName );
5112 //=============================================================================
5114 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5116 //=============================================================================
5117 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5119 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5123 //=============================================================================
5125 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5127 //=============================================================================
5129 char* SMESH_Mesh_i::GetParameters()
5131 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5134 //=============================================================================
5136 * \brief Returns list of notebook variables used for last Mesh operation
5138 //=============================================================================
5139 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5141 SMESH::string_array_var aResult = new SMESH::string_array();
5142 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5144 CORBA::String_var aParameters = GetParameters();
5145 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5146 if ( !aStudy->_is_nil()) {
5147 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5148 if ( aSections->length() > 0 ) {
5149 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5150 aResult->length( aVars.length() );
5151 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5152 aResult[i] = CORBA::string_dup( aVars[i] );
5156 return aResult._retn();
5159 //=======================================================================
5160 //function : GetTypes
5161 //purpose : Returns types of elements it contains
5162 //=======================================================================
5164 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5167 return _preMeshInfo->GetTypes();
5169 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5173 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5174 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5175 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5176 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5177 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5178 if (_impl->NbNodes() &&
5179 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5180 types->length( nbTypes );
5182 return types._retn();
5185 //=======================================================================
5186 //function : GetMesh
5187 //purpose : Returns self
5188 //=======================================================================
5190 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5192 return SMESH::SMESH_Mesh::_duplicate( _this() );
5195 //=======================================================================
5196 //function : IsMeshInfoCorrect
5197 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5198 // * happen if mesh data is not yet fully loaded from the file of study.
5199 //=======================================================================
5201 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5203 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5206 //=============================================================================
5208 * \brief Returns number of mesh elements per each \a EntityType
5210 //=============================================================================
5212 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5215 return _preMeshInfo->GetMeshInfo();
5217 SMESH::long_array_var aRes = new SMESH::long_array();
5218 aRes->length(SMESH::Entity_Last);
5219 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5221 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5223 return aRes._retn();
5224 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5225 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5226 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5227 return aRes._retn();
5230 //=============================================================================
5232 * \brief Returns number of mesh elements per each \a ElementType
5234 //=============================================================================
5236 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5238 SMESH::long_array_var aRes = new SMESH::long_array();
5239 aRes->length(SMESH::NB_ELEMENT_TYPES);
5240 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5243 const SMDS_MeshInfo* meshInfo = 0;
5245 meshInfo = _preMeshInfo;
5246 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5247 meshInfo = & meshDS->GetMeshInfo();
5250 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5251 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5253 return aRes._retn();
5256 //=============================================================================
5258 * Collect statistic of mesh elements given by iterator
5260 //=============================================================================
5262 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5263 SMESH::long_array& theInfo)
5265 if (!theItr) return;
5266 while (theItr->more())
5267 theInfo[ theItr->next()->GetEntityType() ]++;
5269 //=============================================================================
5271 * Returns mesh unstructed grid information.
5273 //=============================================================================
5275 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5277 SALOMEDS::TMPFile_var SeqFile;
5278 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5279 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5281 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5282 aWriter->WriteToOutputStringOn();
5283 aWriter->SetInputData(aGrid);
5284 aWriter->SetFileTypeToBinary();
5286 char* str = aWriter->GetOutputString();
5287 int size = aWriter->GetOutputStringLength();
5289 //Allocate octect buffer of required size
5290 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5291 //Copy ostrstream content to the octect buffer
5292 memcpy(OctetBuf, str, size);
5293 //Create and return TMPFile
5294 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5298 return SeqFile._retn();
5301 //=============================================================================
5302 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5303 * SMESH::ElementType type) */
5305 using namespace SMESH::Controls;
5306 //-----------------------------------------------------------------------------
5307 struct PredicateIterator : public SMDS_ElemIterator
5309 SMDS_ElemIteratorPtr _elemIter;
5310 PredicatePtr _predicate;
5311 const SMDS_MeshElement* _elem;
5313 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5314 PredicatePtr predicate):
5315 _elemIter(iterator), _predicate(predicate)
5323 virtual const SMDS_MeshElement* next()
5325 const SMDS_MeshElement* res = _elem;
5327 while ( _elemIter->more() && !_elem )
5329 _elem = _elemIter->next();
5330 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5337 //-----------------------------------------------------------------------------
5338 struct IDSourceIterator : public SMDS_ElemIterator
5340 const CORBA::Long* _idPtr;
5341 const CORBA::Long* _idEndPtr;
5342 SMESH::long_array_var _idArray;
5343 const SMDS_Mesh* _mesh;
5344 const SMDSAbs_ElementType _type;
5345 const SMDS_MeshElement* _elem;
5347 IDSourceIterator( const SMDS_Mesh* mesh,
5348 const CORBA::Long* ids,
5350 SMDSAbs_ElementType type):
5351 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5353 if ( _idPtr && nbIds && _mesh )
5356 IDSourceIterator( const SMDS_Mesh* mesh,
5357 SMESH::long_array* idArray,
5358 SMDSAbs_ElementType type):
5359 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5361 if ( idArray && _mesh )
5363 _idPtr = &_idArray[0];
5364 _idEndPtr = _idPtr + _idArray->length();
5372 virtual const SMDS_MeshElement* next()
5374 const SMDS_MeshElement* res = _elem;
5376 while ( _idPtr < _idEndPtr && !_elem )
5378 if ( _type == SMDSAbs_Node )
5380 _elem = _mesh->FindNode( *_idPtr++ );
5382 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5383 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5391 //-----------------------------------------------------------------------------
5393 struct NodeOfElemIterator : public SMDS_ElemIterator
5395 TColStd_MapOfInteger _checkedNodeIDs;
5396 SMDS_ElemIteratorPtr _elemIter;
5397 SMDS_ElemIteratorPtr _nodeIter;
5398 const SMDS_MeshElement* _node;
5400 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5402 if ( _elemIter && _elemIter->more() )
5404 _nodeIter = _elemIter->next()->nodesIterator();
5412 virtual const SMDS_MeshElement* next()
5414 const SMDS_MeshElement* res = _node;
5416 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5418 if ( _nodeIter->more() )
5420 _node = _nodeIter->next();
5421 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5426 _nodeIter = _elemIter->next()->nodesIterator();
5434 //=============================================================================
5436 * Return iterator on elements of given type in given object
5438 //=============================================================================
5440 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5441 SMESH::ElementType theType)
5443 SMDS_ElemIteratorPtr elemIt;
5444 bool typeOK = ( theType == SMESH::ALL );
5445 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5447 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5448 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5449 if ( !mesh_i ) return elemIt;
5450 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5452 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5454 elemIt = meshDS->elementsIterator( elemType );
5457 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5459 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5462 elemIt = sm->GetElements();
5463 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5465 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5466 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5470 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5472 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5473 if ( groupDS && ( elemType == groupDS->GetType() ||
5474 elemType == SMDSAbs_Node ||
5475 elemType == SMDSAbs_All ))
5477 elemIt = groupDS->GetElements();
5478 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5481 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5483 if ( filter_i->GetElementType() == theType ||
5484 elemType == SMDSAbs_Node ||
5485 elemType == SMDSAbs_All)
5487 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5488 if ( pred_i && pred_i->GetPredicate() )
5490 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5491 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5492 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5493 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5499 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5500 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5501 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5503 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5506 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5507 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5511 SMESH::long_array_var ids = theObject->GetIDs();
5512 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5514 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5517 if ( elemIt && elemIt->more() && !typeOK )
5519 if ( elemType == SMDSAbs_Node )
5521 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5525 elemIt = SMDS_ElemIteratorPtr();
5531 //=============================================================================
5532 namespace // Finding concurrent hypotheses
5533 //=============================================================================
5537 * \brief mapping of mesh dimension into shape type
5539 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5541 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5543 case 0: aType = TopAbs_VERTEX; break;
5544 case 1: aType = TopAbs_EDGE; break;
5545 case 2: aType = TopAbs_FACE; break;
5547 default:aType = TopAbs_SOLID; break;
5552 //-----------------------------------------------------------------------------
5554 * \brief Internal structure used to find concurent submeshes
5556 * It represents a pair < submesh, concurent dimension >, where
5557 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5558 * with another submesh. In other words, it is dimension of a hypothesis assigned
5565 int _dim; //!< a dimension the algo can build (concurrent dimension)
5566 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5567 TopTools_MapOfShape _shapeMap;
5568 SMESH_subMesh* _subMesh;
5569 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5571 //-----------------------------------------------------------------------------
5572 // Return the algorithm
5573 const SMESH_Algo* GetAlgo() const
5574 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5576 //-----------------------------------------------------------------------------
5578 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5580 const TopoDS_Shape& theShape)
5582 _subMesh = (SMESH_subMesh*)theSubMesh;
5583 SetShape( theDim, theShape );
5586 //-----------------------------------------------------------------------------
5588 void SetShape(const int theDim,
5589 const TopoDS_Shape& theShape)
5592 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5593 if (_dim >= _ownDim)
5594 _shapeMap.Add( theShape );
5596 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5597 for( ; anExp.More(); anExp.Next() )
5598 _shapeMap.Add( anExp.Current() );
5602 //-----------------------------------------------------------------------------
5603 //! Check sharing of sub-shapes
5604 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5605 const TopTools_MapOfShape& theToFind,
5606 const TopAbs_ShapeEnum theType)
5608 bool isShared = false;
5609 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5610 for (; !isShared && anItr.More(); anItr.Next() )
5612 const TopoDS_Shape aSubSh = anItr.Key();
5613 // check for case when concurrent dimensions are same
5614 isShared = theToFind.Contains( aSubSh );
5615 // check for sub-shape with concurrent dimension
5616 TopExp_Explorer anExp( aSubSh, theType );
5617 for ( ; !isShared && anExp.More(); anExp.Next() )
5618 isShared = theToFind.Contains( anExp.Current() );
5623 //-----------------------------------------------------------------------------
5624 //! check algorithms
5625 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5626 const SMESHDS_Hypothesis* theA2)
5628 if ( !theA1 || !theA2 ||
5629 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5630 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5631 return false; // one of the hypothesis is not algorithm
5632 // check algorithm names (should be equal)
5633 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5637 //-----------------------------------------------------------------------------
5638 //! Check if sub-shape hypotheses are concurrent
5639 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5641 if ( _subMesh == theOther->_subMesh )
5642 return false; // same sub-shape - should not be
5644 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5645 // any of the two submeshes is not on COMPOUND shape )
5646 // -> no concurrency
5647 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5648 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5649 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5650 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5651 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5654 // bool checkSubShape = ( _dim >= theOther->_dim )
5655 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5656 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5657 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5658 if ( !checkSubShape )
5661 // check algorithms to be same
5662 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5663 return true; // different algorithms -> concurrency !
5665 // check hypothesises for concurrence (skip first as algorithm)
5667 // pointers should be same, because it is referened from mesh hypothesis partition
5668 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5669 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5670 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5671 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5673 // the submeshes are concurrent if their algorithms has different parameters
5674 return nbSame != (int)theOther->_hypotheses.size() - 1;
5677 // Return true if algorithm of this SMESH_DimHyp is used if no
5678 // sub-mesh order is imposed by the user
5679 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5681 // NeedDiscreteBoundary() algo has a higher priority
5682 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5683 theOther->GetAlgo()->NeedDiscreteBoundary() )
5684 return !this->GetAlgo()->NeedDiscreteBoundary();
5686 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5689 }; // end of SMESH_DimHyp
5690 //-----------------------------------------------------------------------------
5692 typedef list<const SMESH_DimHyp*> TDimHypList;
5694 //-----------------------------------------------------------------------------
5696 void addDimHypInstance(const int theDim,
5697 const TopoDS_Shape& theShape,
5698 const SMESH_Algo* theAlgo,
5699 const SMESH_subMesh* theSubMesh,
5700 const list <const SMESHDS_Hypothesis*>& theHypList,
5701 TDimHypList* theDimHypListArr )
5703 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5704 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5705 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5706 dimHyp->_hypotheses.push_front(theAlgo);
5707 listOfdimHyp.push_back( dimHyp );
5710 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5711 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5712 theHypList.begin(), theHypList.end() );
5715 //-----------------------------------------------------------------------------
5716 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5717 TDimHypList& theListOfConcurr)
5719 if ( theListOfConcurr.empty() )
5721 theListOfConcurr.push_back( theDimHyp );
5725 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5726 while ( hypIt != theListOfConcurr.end() &&
5727 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5729 theListOfConcurr.insert( hypIt, theDimHyp );
5733 //-----------------------------------------------------------------------------
5734 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5735 const TDimHypList& theListOfDimHyp,
5736 TDimHypList& theListOfConcurrHyp,
5737 set<int>& theSetOfConcurrId )
5739 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5740 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5742 const SMESH_DimHyp* curDimHyp = *rIt;
5743 if ( curDimHyp == theDimHyp )
5744 break; // meet own dimHyp pointer in same dimension
5746 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5747 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5749 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5754 //-----------------------------------------------------------------------------
5755 void unionLists(TListOfInt& theListOfId,
5756 TListOfListOfInt& theListOfListOfId,
5759 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5760 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5762 continue; //skip already treated lists
5763 // check if other list has any same submesh object
5764 TListOfInt& otherListOfId = *it;
5765 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5766 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5769 // union two lists (from source into target)
5770 TListOfInt::iterator it2 = otherListOfId.begin();
5771 for ( ; it2 != otherListOfId.end(); it2++ ) {
5772 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5773 theListOfId.push_back(*it2);
5775 // clear source list
5776 otherListOfId.clear();
5779 //-----------------------------------------------------------------------------
5781 //! free memory allocated for dimension-hypothesis objects
5782 void removeDimHyps( TDimHypList* theArrOfList )
5784 for (int i = 0; i < 4; i++ ) {
5785 TDimHypList& listOfdimHyp = theArrOfList[i];
5786 TDimHypList::const_iterator it = listOfdimHyp.begin();
5787 for ( ; it != listOfdimHyp.end(); it++ )
5792 //-----------------------------------------------------------------------------
5794 * \brief find common submeshes with given submesh
5795 * \param theSubMeshList list of already collected submesh to check
5796 * \param theSubMesh given submesh to intersect with other
5797 * \param theCommonSubMeshes collected common submeshes
5799 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5800 const SMESH_subMesh* theSubMesh,
5801 set<const SMESH_subMesh*>& theCommon )
5805 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5806 for ( ; it != theSubMeshList.end(); it++ )
5807 theSubMesh->FindIntersection( *it, theCommon );
5808 theSubMeshList.push_back( theSubMesh );
5809 //theCommon.insert( theSubMesh );
5812 //-----------------------------------------------------------------------------
5813 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5815 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5816 for ( ; listsIt != smLists.end(); ++listsIt )
5818 const TListOfInt& smIDs = *listsIt;
5819 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5827 //=============================================================================
5829 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5831 //=============================================================================
5833 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5835 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5836 if ( isSubMeshInList( submeshID, anOrder ))
5839 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5840 return isSubMeshInList( submeshID, allConurrent );
5843 //=============================================================================
5845 * \brief Return submesh objects list in meshing order
5847 //=============================================================================
5849 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5851 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5853 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5855 return aResult._retn();
5857 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5858 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5859 anOrder.splice( anOrder.end(), allConurrent );
5862 TListOfListOfInt::iterator listIt = anOrder.begin();
5863 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5864 unionLists( *listIt, anOrder, listIndx + 1 );
5866 // convert submesh ids into interface instances
5867 // and dump command into python
5868 convertMeshOrder( anOrder, aResult, false );
5870 return aResult._retn();
5873 //=============================================================================
5875 * \brief Finds concurrent sub-meshes
5877 //=============================================================================
5879 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5881 TListOfListOfInt anOrder;
5882 ::SMESH_Mesh& mesh = GetImpl();
5884 // collect submeshes and detect concurrent algorithms and hypothesises
5885 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5887 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5888 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5889 ::SMESH_subMesh* sm = (*i_sm).second;
5891 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5893 // list of assigned hypothesises
5894 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5895 // Find out dimensions where the submesh can be concurrent.
5896 // We define the dimensions by algo of each of hypotheses in hypList
5897 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5898 for( ; hypIt != hypList.end(); hypIt++ ) {
5899 SMESH_Algo* anAlgo = 0;
5900 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5901 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5902 // hyp it-self is algo
5903 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5905 // try to find algorithm with help of sub-shapes
5906 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5907 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5908 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5911 continue; // no algorithm assigned to a current submesh
5913 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5914 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5916 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5917 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5918 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5920 } // end iterations on submesh
5922 // iterate on created dimension-hypotheses and check for concurrents
5923 for ( int i = 0; i < 4; i++ ) {
5924 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5925 // check for concurrents in own and other dimensions (step-by-step)
5926 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5927 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5928 const SMESH_DimHyp* dimHyp = *dhIt;
5929 TDimHypList listOfConcurr;
5930 set<int> setOfConcurrIds;
5931 // looking for concurrents and collect into own list
5932 for ( int j = i; j < 4; j++ )
5933 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5934 // check if any concurrents found
5935 if ( listOfConcurr.size() > 0 ) {
5936 // add own submesh to list of concurrent
5937 addInOrderOfPriority( dimHyp, listOfConcurr );
5938 list<int> listOfConcurrIds;
5939 TDimHypList::iterator hypIt = listOfConcurr.begin();
5940 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5941 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5942 anOrder.push_back( listOfConcurrIds );
5947 removeDimHyps(dimHypListArr);
5949 // now, minimise the number of concurrent groups
5950 // Here we assume that lists of submeshes can have same submesh
5951 // in case of multi-dimension algorithms, as result
5952 // list with common submesh has to be united into one list
5954 TListOfListOfInt::iterator listIt = anOrder.begin();
5955 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5956 unionLists( *listIt, anOrder, listIndx + 1 );
5962 //=============================================================================
5964 * \brief Set submesh object order
5965 * \param theSubMeshArray submesh array order
5967 //=============================================================================
5969 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5972 _preMeshInfo->ForgetOrLoad();
5975 ::SMESH_Mesh& mesh = GetImpl();
5977 TPythonDump aPythonDump; // prevent dump of called methods
5978 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5980 TListOfListOfInt subMeshOrder;
5981 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5983 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5984 TListOfInt subMeshIds;
5986 aPythonDump << ", ";
5987 aPythonDump << "[ ";
5988 // Collect subMeshes which should be clear
5989 // do it list-by-list, because modification of submesh order
5990 // take effect between concurrent submeshes only
5991 set<const SMESH_subMesh*> subMeshToClear;
5992 list<const SMESH_subMesh*> subMeshList;
5993 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5995 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5997 aPythonDump << ", ";
5998 aPythonDump << subMesh;
5999 subMeshIds.push_back( subMesh->GetId() );
6000 // detect common parts of submeshes
6001 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6002 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6004 aPythonDump << " ]";
6005 subMeshOrder.push_back( subMeshIds );
6007 // clear collected submeshes
6008 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6009 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6010 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6011 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6013 aPythonDump << " ])";
6015 mesh.SetMeshOrder( subMeshOrder );
6021 //=============================================================================
6023 * \brief Convert submesh ids into submesh interfaces
6025 //=============================================================================
6027 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6028 SMESH::submesh_array_array& theResOrder,
6029 const bool theIsDump)
6031 int nbSet = theIdsOrder.size();
6032 TPythonDump aPythonDump; // prevent dump of called methods
6034 aPythonDump << "[ ";
6035 theResOrder.length(nbSet);
6036 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6038 for( ; it != theIdsOrder.end(); it++ ) {
6039 // translate submesh identificators into submesh objects
6040 // takeing into account real number of concurrent lists
6041 const TListOfInt& aSubOrder = (*it);
6042 if (!aSubOrder.size())
6045 aPythonDump << "[ ";
6046 // convert shape indeces into interfaces
6047 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6048 aResSubSet->length(aSubOrder.size());
6049 TListOfInt::const_iterator subIt = aSubOrder.begin();
6051 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6052 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6054 SMESH::SMESH_subMesh_var subMesh =
6055 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6058 aPythonDump << ", ";
6059 aPythonDump << subMesh;
6061 aResSubSet[ j++ ] = subMesh;
6064 aPythonDump << " ]";
6066 theResOrder[ listIndx++ ] = aResSubSet;
6068 // correct number of lists
6069 theResOrder.length( listIndx );
6072 // finilise python dump
6073 aPythonDump << " ]";
6074 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6078 //================================================================================
6080 // Implementation of SMESH_MeshPartDS
6082 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6083 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6085 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6086 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6088 _meshDS = mesh_i->GetImpl().GetMeshDS();
6090 SetPersistentId( _meshDS->GetPersistentId() );
6092 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6094 // <meshPart> is the whole mesh
6095 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6097 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6098 myGroupSet = _meshDS->GetGroups();
6103 SMESH::long_array_var anIDs = meshPart->GetIDs();
6104 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6105 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6107 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6108 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6109 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6114 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6115 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6116 if ( _elements[ e->GetType() ].insert( e ).second )
6119 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6120 while ( nIt->more() )
6122 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6123 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6130 ShapeToMesh( _meshDS->ShapeToMesh() );
6132 _meshDS = 0; // to enforce iteration on _elements and _nodes
6135 // -------------------------------------------------------------------------------------
6136 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6137 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6140 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6141 for ( ; partIt != meshPart.end(); ++partIt )
6142 if ( const SMDS_MeshElement * e = *partIt )
6143 if ( _elements[ e->GetType() ].insert( e ).second )
6146 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6147 while ( nIt->more() )
6149 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6150 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6156 // -------------------------------------------------------------------------------------
6157 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6159 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6161 typedef SMDS_SetIterator
6162 <const SMDS_MeshElement*,
6163 TIDSortedElemSet::const_iterator,
6164 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6165 SMDS_MeshElement::GeomFilter
6168 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6170 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6171 _elements[type].end(),
6172 SMDS_MeshElement::GeomFilter( geomType )));
6174 // -------------------------------------------------------------------------------------
6175 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6177 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6179 typedef SMDS_SetIterator
6180 <const SMDS_MeshElement*,
6181 TIDSortedElemSet::const_iterator,
6182 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6183 SMDS_MeshElement::EntityFilter
6186 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6188 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6189 _elements[type].end(),
6190 SMDS_MeshElement::EntityFilter( entity )));
6192 // -------------------------------------------------------------------------------------
6193 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6195 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6196 if ( type == SMDSAbs_All && !_meshDS )
6198 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6200 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6201 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6203 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6205 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6206 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6208 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6209 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6211 // -------------------------------------------------------------------------------------
6212 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6213 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6215 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6216 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6217 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6219 // -------------------------------------------------------------------------------------
6220 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6221 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6222 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6223 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6224 #undef _GET_ITER_DEFINE
6226 // END Implementation of SMESH_MeshPartDS
6228 //================================================================================