1 // Copyright (C) 2007-2012 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.
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_SMESHDS_Mesh.h"
30 #include "SMDS_EdgePosition.hxx"
31 #include "SMDS_ElemIterator.hxx"
32 #include "SMDS_FacePosition.hxx"
33 #include "SMDS_IteratorOnIterators.hxx"
34 #include "SMDS_MeshGroup.hxx"
35 #include "SMDS_SetIterator.hxx"
36 #include "SMDS_VolumeTool.hxx"
37 #include "SMESHDS_Command.hxx"
38 #include "SMESHDS_CommandType.hxx"
39 #include "SMESHDS_Group.hxx"
40 #include "SMESHDS_GroupOnGeom.hxx"
41 #include "SMESH_Filter_i.hxx"
42 #include "SMESH_Gen_i.hxx"
43 #include "SMESH_Group.hxx"
44 #include "SMESH_Group_i.hxx"
45 #include "SMESH_MEDMesh_i.hxx"
46 #include "SMESH_MeshEditor.hxx"
47 #include "SMESH_MeshEditor_i.hxx"
48 #include "SMESH_MeshPartDS.hxx"
49 #include "SMESH_MesherHelper.hxx"
50 #include "SMESH_PreMeshInfo.hxx"
51 #include "SMESH_PythonDump.hxx"
52 #include "SMESH_subMesh_i.hxx"
55 #include <SALOMEDS_Attributes_wrap.hxx>
56 #include <SALOMEDS_wrap.hxx>
57 #include <SALOME_NamingService.hxx>
58 #include <Utils_CorbaException.hxx>
59 #include <Utils_ExceptHandlers.hxx>
60 #include <Utils_SINGLETON.hxx>
61 #include <utilities.h>
63 #include <GEOMImpl_Types.hxx>
64 #include <GEOM_GenericObjPtr.h>
67 #include <BRep_Builder.hxx>
68 #include <OSD_Directory.hxx>
69 #include <OSD_File.hxx>
70 #include <OSD_Path.hxx>
71 #include <OSD_Protection.hxx>
72 #include <Standard_OutOfMemory.hxx>
73 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
74 #include <TColStd_MapOfInteger.hxx>
75 #include <TColStd_SequenceOfInteger.hxx>
76 #include <TCollection_AsciiString.hxx>
78 #include <TopExp_Explorer.hxx>
79 #include <TopTools_MapIteratorOfMapOfShape.hxx>
80 #include <TopTools_MapOfShape.hxx>
81 #include <TopoDS_Compound.hxx>
91 static int MYDEBUG = 0;
93 static int MYDEBUG = 0;
97 using SMESH::TPythonDump;
99 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 CORBA::Long studyId )
111 : SALOME::GenericObj_i( thePOA )
113 MESSAGE("SMESH_Mesh_i");
116 _id = _idGenerator++;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
129 MESSAGE("~SMESH_Mesh_i");
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
137 //_impl->RemoveGroup( aGroup->GetLocalID() );
138 aGroup->myMeshServant = 0;
139 aGroup->UnRegister();
144 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
145 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
146 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
148 aSubMesh->UnRegister();
150 _mapSubMeshIor.clear();
152 // destroy hypotheses
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
155 if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
161 delete _impl; _impl = NULL;
162 delete _preMeshInfo; _preMeshInfo = NULL;
165 //=============================================================================
169 * Associates <this> mesh with <theShape> and puts a reference
170 * to <theShape> into the current study;
171 * the previous shape is substituted by the new one.
173 //=============================================================================
175 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
176 throw (SALOME::SALOME_Exception)
178 Unexpect aCatch(SALOME_SalomeException);
180 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
182 catch(SALOME_Exception & S_ex) {
183 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
185 // to track changes of GEOM groups
186 addGeomGroupData( theShapeObject, _this() );
189 //================================================================================
191 * \brief return true if mesh has a shape to build a shape on
193 //================================================================================
195 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
196 throw (SALOME::SALOME_Exception)
198 Unexpect aCatch(SALOME_SalomeException);
201 res = _impl->HasShapeToMesh();
203 catch(SALOME_Exception & S_ex) {
204 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
209 //=======================================================================
210 //function : GetShapeToMesh
212 //=======================================================================
214 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
215 throw (SALOME::SALOME_Exception)
217 Unexpect aCatch(SALOME_SalomeException);
218 GEOM::GEOM_Object_var aShapeObj;
220 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
222 aShapeObj = _gen_i->ShapeToGeomObject( S );
224 catch(SALOME_Exception & S_ex) {
225 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
227 return aShapeObj._retn();
230 //================================================================================
232 * \brief Return false if the mesh is not yet fully loaded from the study file
234 //================================================================================
236 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
238 Unexpect aCatch(SALOME_SalomeException);
239 return !_preMeshInfo;
242 //================================================================================
244 * \brief Load full mesh data from the study file
246 //================================================================================
248 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
250 Unexpect aCatch(SALOME_SalomeException);
252 _preMeshInfo->FullLoadFromFile();
255 //================================================================================
257 * \brief Remove all nodes and elements
259 //================================================================================
261 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->ForgetAllData();
269 CheckGeomGroupModif(); // issue 20145
271 catch(SALOME_Exception & S_ex) {
272 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
274 _impl->GetMeshDS()->Modified();
276 TPythonDump() << _this() << ".Clear()";
279 //================================================================================
281 * \brief Remove all nodes and elements for indicated shape
283 //================================================================================
285 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
286 throw (SALOME::SALOME_Exception)
288 Unexpect aCatch(SALOME_SalomeException);
290 _preMeshInfo->FullLoadFromFile();
293 _impl->ClearSubMesh( ShapeID );
295 catch(SALOME_Exception & S_ex) {
296 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
298 _impl->GetMeshDS()->Modified();
300 TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )";
303 //=============================================================================
305 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
307 //=============================================================================
309 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
311 SMESH::DriverMED_ReadStatus res;
314 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
315 res = SMESH::DRS_OK; break;
316 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
317 res = SMESH::DRS_EMPTY; break;
318 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
319 res = SMESH::DRS_WARN_RENUMBER; break;
320 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
321 res = SMESH::DRS_WARN_SKIP_ELEM; break;
322 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
324 res = SMESH::DRS_FAIL; break;
329 //=============================================================================
331 * Convert ::SMESH_ComputeError to SMESH::ComputeError
333 //=============================================================================
335 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
337 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
338 errVar->subShapeID = -1;
339 errVar->hasBadMesh = false;
341 if ( !errorPtr || errorPtr->IsOK() )
343 errVar->code = SMESH::COMPERR_OK;
347 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
348 errVar->comment = errorPtr->myComment.c_str();
350 return errVar._retn();
353 //=============================================================================
357 * Imports mesh data from MED file
359 //=============================================================================
361 SMESH::DriverMED_ReadStatus
362 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
363 throw ( SALOME::SALOME_Exception )
365 Unexpect aCatch(SALOME_SalomeException);
368 status = _impl->MEDToMesh( theFileName, theMeshName );
370 catch( SALOME_Exception& S_ex ) {
371 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
374 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
377 CreateGroupServants();
379 int major, minor, release;
380 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
381 major = minor = release = -1;
382 _medFileInfo = new SALOME_MED::MedFileInfo();
383 _medFileInfo->fileName = theFileName;
384 _medFileInfo->fileSize = 0;
387 if ( ::_stati64( theFileName, &d ) != -1 )
390 if ( ::stat64( theFileName, &d ) != -1 )
392 _medFileInfo->fileSize = d.st_size;
393 _medFileInfo->major = major;
394 _medFileInfo->minor = minor;
395 _medFileInfo->release = release;
397 return ConvertDriverMEDReadStatus(status);
400 //================================================================================
402 * \brief Imports mesh data from the CGNS file
404 //================================================================================
406 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
407 const int theMeshIndex,
408 std::string& theMeshName )
409 throw ( SALOME::SALOME_Exception )
411 Unexpect aCatch(SALOME_SalomeException);
414 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
416 catch( SALOME_Exception& S_ex ) {
417 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
420 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
423 CreateGroupServants();
425 return ConvertDriverMEDReadStatus(status);
428 //================================================================================
430 * \brief Return string representation of a MED file version comprising nbDigits
432 //================================================================================
434 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
436 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
438 return CORBA::string_dup( ver.c_str() );
441 //=============================================================================
445 * Imports mesh data from MED file
447 //=============================================================================
449 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
450 throw ( SALOME::SALOME_Exception )
452 // Read mesh with name = <theMeshName> into SMESH_Mesh
453 _impl->UNVToMesh( theFileName );
455 CreateGroupServants();
460 //=============================================================================
464 * Imports mesh data from STL file
466 //=============================================================================
467 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
468 throw ( SALOME::SALOME_Exception )
470 // Read mesh with name = <theMeshName> into SMESH_Mesh
471 _impl->STLToMesh( theFileName );
476 //================================================================================
478 * \brief Imports data from a GMF file and returns an error description
480 //================================================================================
482 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
483 bool theMakeRequiredGroups )
484 throw (SALOME::SALOME_Exception)
486 SMESH_ComputeErrorPtr error;
488 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
490 catch ( std::bad_alloc& exc ) {
491 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "std::bad_alloc raised" );
493 catch ( Standard_OutOfMemory& exc ) {
494 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Standard_OutOfMemory raised" );
496 catch (Standard_Failure& ex) {
497 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, ex.DynamicType()->Name() );
498 if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
499 error->myComment += string(": ") + ex.GetMessageString();
501 catch ( SALOME_Exception& S_ex ) {
502 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, S_ex.what() );
504 catch ( std::exception& exc ) {
505 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, exc.what() );
508 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Unknown exception" );
511 CreateGroupServants();
513 return ConvertComputeError( error );
516 //=============================================================================
520 //=============================================================================
522 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
524 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
525 (SMESH_Hypothesis::Hypothesis_Status theStatus)
528 RETURNCASE( HYP_OK );
529 RETURNCASE( HYP_MISSING );
530 RETURNCASE( HYP_CONCURENT );
531 RETURNCASE( HYP_BAD_PARAMETER );
532 RETURNCASE( HYP_HIDDEN_ALGO );
533 RETURNCASE( HYP_HIDING_ALGO );
534 RETURNCASE( HYP_UNKNOWN_FATAL );
535 RETURNCASE( HYP_INCOMPATIBLE );
536 RETURNCASE( HYP_NOTCONFORM );
537 RETURNCASE( HYP_ALREADY_EXIST );
538 RETURNCASE( HYP_BAD_DIM );
539 RETURNCASE( HYP_BAD_SUBSHAPE );
540 RETURNCASE( HYP_BAD_GEOMETRY );
541 RETURNCASE( HYP_NEED_SHAPE );
544 return SMESH::HYP_UNKNOWN_FATAL;
547 //=============================================================================
551 * calls internal addHypothesis() and then adds a reference to <anHyp> under
552 * the SObject actually having a reference to <aSubShape>.
553 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
555 //=============================================================================
557 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
558 SMESH::SMESH_Hypothesis_ptr anHyp)
559 throw(SALOME::SALOME_Exception)
561 Unexpect aCatch(SALOME_SalomeException);
563 _preMeshInfo->ForgetOrLoad();
565 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
567 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
568 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
569 aSubShapeObject, anHyp );
571 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
573 // Update Python script
574 if(_impl->HasShapeToMesh()) {
575 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
576 << aSubShapeObject << ", " << anHyp << " )";
579 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
582 return ConvertHypothesisStatus(status);
585 //=============================================================================
589 //=============================================================================
591 SMESH_Hypothesis::Hypothesis_Status
592 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
593 SMESH::SMESH_Hypothesis_ptr anHyp)
595 if(MYDEBUG) MESSAGE("addHypothesis");
597 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
598 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
601 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
602 if (CORBA::is_nil(myHyp))
603 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
606 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
609 TopoDS_Shape myLocSubShape;
610 //use PseudoShape in case if mesh has no shape
612 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
614 myLocSubShape = _impl->GetShapeToMesh();
616 int hypId = myHyp->GetId();
617 status = _impl->AddHypothesis(myLocSubShape, hypId);
618 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
619 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
620 _mapHypo[hypId]->Register();
621 // assure there is a corresponding submesh
622 if ( !_impl->IsMainShape( myLocSubShape )) {
623 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
624 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
625 createSubMesh( aSubShapeObject );
629 catch(SALOME_Exception & S_ex)
631 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
636 //=============================================================================
640 //=============================================================================
642 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
643 SMESH::SMESH_Hypothesis_ptr anHyp)
644 throw(SALOME::SALOME_Exception)
646 Unexpect aCatch(SALOME_SalomeException);
648 _preMeshInfo->ForgetOrLoad();
650 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
652 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
653 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
654 aSubShapeObject, anHyp );
656 // Update Python script
657 // Update Python script
658 if(_impl->HasShapeToMesh()) {
659 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
660 << aSubShapeObject << ", " << anHyp << " )";
663 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
667 return ConvertHypothesisStatus(status);
670 //=============================================================================
674 //=============================================================================
676 SMESH_Hypothesis::Hypothesis_Status
677 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
678 SMESH::SMESH_Hypothesis_ptr anHyp)
680 if(MYDEBUG) MESSAGE("removeHypothesis()");
681 // **** proposer liste de sub-shape (selection multiple)
683 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
684 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
686 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
687 if (CORBA::is_nil(myHyp))
688 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
690 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
693 TopoDS_Shape myLocSubShape;
694 //use PseudoShape in case if mesh has no shape
696 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
698 myLocSubShape = _impl->GetShapeToMesh();
700 int hypId = myHyp->GetId();
701 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
702 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
703 // _mapHypo.erase( hypId );
705 catch(SALOME_Exception & S_ex)
707 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
712 //=============================================================================
716 //=============================================================================
718 SMESH::ListOfHypothesis *
719 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
720 throw(SALOME::SALOME_Exception)
722 Unexpect aCatch(SALOME_SalomeException);
723 if (MYDEBUG) MESSAGE("GetHypothesisList");
724 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
725 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
727 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
730 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
731 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
732 myLocSubShape = _impl->GetShapeToMesh();
733 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
734 int i = 0, n = aLocalList.size();
737 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
738 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
739 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
740 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
745 catch(SALOME_Exception & S_ex) {
746 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
749 return aList._retn();
752 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
754 Unexpect aCatch(SALOME_SalomeException);
755 if (MYDEBUG) MESSAGE("GetSubMeshes");
757 SMESH::submesh_array_var aList = new SMESH::submesh_array();
760 TPythonDump aPythonDump;
761 if ( !_mapSubMeshIor.empty() )
765 aList->length( _mapSubMeshIor.size() );
767 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
768 for ( ; it != _mapSubMeshIor.end(); it++ ) {
769 if ( CORBA::is_nil( it->second )) continue;
770 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
772 if (i > 1) aPythonDump << ", ";
773 aPythonDump << it->second;
777 catch(SALOME_Exception & S_ex) {
778 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
781 // Update Python script
782 if ( !_mapSubMeshIor.empty() )
783 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
785 return aList._retn();
788 //=============================================================================
792 //=============================================================================
793 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
794 const char* theName )
795 throw(SALOME::SALOME_Exception)
797 Unexpect aCatch(SALOME_SalomeException);
798 MESSAGE("SMESH_Mesh_i::GetSubMesh");
799 if (CORBA::is_nil(aSubShapeObject))
800 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
803 SMESH::SMESH_subMesh_var subMesh;
804 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
806 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
808 //Get or Create the SMESH_subMesh object implementation
810 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
812 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
814 TopoDS_Iterator it( myLocSubShape );
816 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
818 subMesh = getSubMesh( subMeshId );
820 // create a new subMesh object servant if there is none for the shape
821 if ( subMesh->_is_nil() )
822 subMesh = createSubMesh( aSubShapeObject );
823 if ( _gen_i->CanPublishInStudy( subMesh )) {
824 SALOMEDS::SObject_wrap aSO =
825 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
826 subMesh, aSubShapeObject, theName );
827 if ( !aSO->_is_nil()) {
828 // Update Python script
829 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
830 << aSubShapeObject << ", '" << theName << "' )";
834 catch(SALOME_Exception & S_ex) {
835 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
837 return subMesh._retn();
840 //=============================================================================
844 //=============================================================================
846 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
847 throw (SALOME::SALOME_Exception)
849 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
850 if ( theSubMesh->_is_nil() )
853 GEOM::GEOM_Object_var aSubShapeObject;
854 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
855 if ( !aStudy->_is_nil() ) {
856 // Remove submesh's SObject
857 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
858 if ( !anSO->_is_nil() ) {
859 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
860 SALOMEDS::SObject_wrap anObj, aRef;
861 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
862 anObj->ReferencedObject( aRef.inout() ))
864 CORBA::Object_var obj = aRef->GetObject();
865 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
867 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
868 // aSubShapeObject = theSubMesh->GetSubShape();
870 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
871 builder->RemoveObjectWithChildren( anSO );
873 // Update Python script
874 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
878 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
880 _preMeshInfo->ForgetOrLoad();
883 //=============================================================================
887 //=============================================================================
889 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
890 const char* theName )
891 throw(SALOME::SALOME_Exception)
893 Unexpect aCatch(SALOME_SalomeException);
895 _preMeshInfo->FullLoadFromFile();
897 SMESH::SMESH_Group_var aNewGroup =
898 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
900 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
901 SALOMEDS::SObject_wrap aSO =
902 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
903 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
904 if ( !aSO->_is_nil()) {
905 // Update Python script
906 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
907 << theElemType << ", '" << theName << "' )";
910 return aNewGroup._retn();
914 //=============================================================================
918 //=============================================================================
919 SMESH::SMESH_GroupOnGeom_ptr
920 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
922 GEOM::GEOM_Object_ptr theGeomObj)
923 throw(SALOME::SALOME_Exception)
925 Unexpect aCatch(SALOME_SalomeException);
927 _preMeshInfo->FullLoadFromFile();
929 SMESH::SMESH_GroupOnGeom_var aNewGroup;
931 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
932 if ( !aShape.IsNull() )
934 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
935 ( createGroup( theElemType, theName, aShape ));
937 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
938 SALOMEDS::SObject_wrap aSO =
939 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
940 aNewGroup, theGeomObj, theName);
941 if ( !aSO->_is_nil()) {
942 // Update Python script
943 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
944 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
949 return aNewGroup._retn();
952 //================================================================================
954 * \brief Creates a group whose contents is defined by filter
955 * \param theElemType - group type
956 * \param theName - group name
957 * \param theFilter - the filter
958 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
960 //================================================================================
962 SMESH::SMESH_GroupOnFilter_ptr
963 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
965 SMESH::Filter_ptr theFilter )
966 throw (SALOME::SALOME_Exception)
968 Unexpect aCatch(SALOME_SalomeException);
970 _preMeshInfo->FullLoadFromFile();
972 if ( CORBA::is_nil( theFilter ))
973 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
975 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
977 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
979 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
980 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
983 if ( !aNewGroup->_is_nil() )
984 aNewGroup->SetFilter( theFilter );
986 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
988 SALOMEDS::SObject_wrap aSO =
989 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
990 GEOM::GEOM_Object::_nil(), theName);
991 if ( !aSO->_is_nil()) {
992 // Update Python script
993 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
994 << theElemType << ", '" << theName << "', " << theFilter << " )";
998 return aNewGroup._retn();
1001 //=============================================================================
1005 //=============================================================================
1007 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1008 throw (SALOME::SALOME_Exception)
1010 if ( theGroup->_is_nil() )
1013 SMESH_GroupBase_i* aGroup =
1014 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1018 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1019 if ( !aStudy->_is_nil() ) {
1020 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1022 if ( !aGroupSO->_is_nil() ) {
1023 // Update Python script
1024 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1026 // Remove group's SObject
1027 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1028 builder->RemoveObjectWithChildren( aGroupSO );
1032 // Remove the group from SMESH data structures
1033 removeGroup( aGroup->GetLocalID() );
1036 //=============================================================================
1038 * Remove group with its contents
1040 //=============================================================================
1042 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1043 throw (SALOME::SALOME_Exception)
1046 _preMeshInfo->FullLoadFromFile();
1048 if ( theGroup->_is_nil() )
1051 SMESH_GroupBase_i* aGroup =
1052 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1056 SMESH::long_array_var anIds = aGroup->GetListOfID();
1057 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1059 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1062 if ( aGroup->GetType() == SMESH::NODE )
1063 aMeshEditor->RemoveNodes( anIds );
1065 aMeshEditor->RemoveElements( anIds );
1067 // Update Python script (theGroup must be alive for this)
1068 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1071 RemoveGroup( theGroup );
1074 //================================================================================
1076 * \brief Get the list of groups existing in the mesh
1077 * \retval SMESH::ListOfGroups * - list of groups
1079 //================================================================================
1081 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1083 Unexpect aCatch(SALOME_SalomeException);
1084 if (MYDEBUG) MESSAGE("GetGroups");
1086 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1089 TPythonDump aPythonDump;
1090 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1091 aPythonDump << "[ ";
1094 aList->length( _mapGroups.size() );
1096 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1097 for ( ; it != _mapGroups.end(); it++ ) {
1098 if ( CORBA::is_nil( it->second )) continue;
1099 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1101 if (i > 1) aPythonDump << ", ";
1102 aPythonDump << it->second;
1106 catch(SALOME_Exception & S_ex) {
1107 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1110 // Update Python script
1111 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1112 aPythonDump << " ] = " << _this() << ".GetGroups()";
1114 return aList._retn();
1117 //=============================================================================
1119 * Get number of groups existing in the mesh
1121 //=============================================================================
1123 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1125 Unexpect aCatch(SALOME_SalomeException);
1126 return _mapGroups.size();
1129 //=============================================================================
1131 * New group is created. All mesh elements that are
1132 * present in initial groups are added to the new one
1134 //=============================================================================
1135 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1136 SMESH::SMESH_GroupBase_ptr theGroup2,
1137 const char* theName )
1138 throw (SALOME::SALOME_Exception)
1141 _preMeshInfo->FullLoadFromFile();
1145 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1146 theGroup1->GetType() != theGroup2->GetType() )
1147 return SMESH::SMESH_Group::_nil();
1152 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1153 if ( aResGrp->_is_nil() )
1154 return SMESH::SMESH_Group::_nil();
1156 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1157 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1159 TColStd_MapOfInteger aResMap;
1161 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1162 aResMap.Add( anIds1[ i1 ] );
1164 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1165 aResMap.Add( anIds2[ i2 ] );
1167 SMESH::long_array_var aResIds = new SMESH::long_array;
1168 aResIds->length( aResMap.Extent() );
1171 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1172 for( ; anIter.More(); anIter.Next() )
1173 aResIds[ resI++ ] = anIter.Key();
1175 aResGrp->Add( aResIds );
1177 // Update Python script
1178 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1179 << theGroup1 << ", " << theGroup2 << ", '"
1180 << theName << "' )";
1182 return aResGrp._retn();
1186 return SMESH::SMESH_Group::_nil();
1190 //=============================================================================
1192 \brief Union list of groups. New group is created. All mesh elements that are
1193 present in initial groups are added to the new one.
1194 \param theGroups list of groups
1195 \param theName name of group to be created
1196 \return pointer on the group
1198 //=============================================================================
1199 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1200 const char* theName )
1201 throw (SALOME::SALOME_Exception)
1204 _preMeshInfo->FullLoadFromFile();
1207 return SMESH::SMESH_Group::_nil();
1211 vector< int > anIds;
1212 SMESH::ElementType aType = SMESH::ALL;
1213 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1215 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1216 if ( CORBA::is_nil( aGrp ) )
1220 SMESH::ElementType aCurrType = aGrp->GetType();
1221 if ( aType == SMESH::ALL )
1225 if ( aType != aCurrType )
1226 return SMESH::SMESH_Group::_nil();
1230 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1231 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1233 int aCurrId = aCurrIds[ i ];
1234 anIds.push_back( aCurrId );
1241 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1242 if ( aResGrp->_is_nil() )
1243 return SMESH::SMESH_Group::_nil();
1245 // Create array of identifiers
1246 SMESH::long_array_var aResIds = new SMESH::long_array;
1247 aResIds->length( anIds.size() );
1249 for ( size_t i = 0; i<anIds.size(); i++ )
1250 aResIds[ i ] = anIds[i];
1251 aResGrp->Add( aResIds );
1253 // Update Python script
1254 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1255 << &theGroups << ", '" << theName << "' )";
1257 return aResGrp._retn();
1261 return SMESH::SMESH_Group::_nil();
1265 //=============================================================================
1267 * New group is created. All mesh elements that are
1268 * present in both initial groups are added to the new one.
1270 //=============================================================================
1271 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1272 SMESH::SMESH_GroupBase_ptr theGroup2,
1273 const char* theName )
1274 throw (SALOME::SALOME_Exception)
1277 _preMeshInfo->FullLoadFromFile();
1279 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1280 theGroup1->GetType() != theGroup2->GetType() )
1281 return SMESH::SMESH_Group::_nil();
1285 // Create Intersection
1286 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1287 if ( aResGrp->_is_nil() )
1290 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1291 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1293 TColStd_MapOfInteger aMap1;
1295 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1296 aMap1.Add( anIds1[ i1 ] );
1298 TColStd_SequenceOfInteger aSeq;
1299 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1300 if ( aMap1.Contains( anIds2[ i2 ] ) )
1301 aSeq.Append( anIds2[ i2 ] );
1303 SMESH::long_array_var aResIds = new SMESH::long_array;
1304 aResIds->length( aSeq.Length() );
1305 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1306 aResIds[ resI ] = aSeq( resI + 1 );
1307 aResGrp->Add( aResIds );
1309 // Update Python script
1310 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1311 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1313 return aResGrp._retn();
1316 //=============================================================================
1318 \brief Intersect list of groups. New group is created. All mesh elements that
1319 are present in all initial groups simultaneously are added to the new one.
1320 \param theGroups list of groups
1321 \param theName name of group to be created
1322 \return pointer on the group
1324 //=============================================================================
1325 SMESH::SMESH_Group_ptr
1326 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1327 const char* theName )
1328 throw (SALOME::SALOME_Exception)
1331 _preMeshInfo->FullLoadFromFile();
1334 return SMESH::SMESH_Group::_nil();
1338 NCollection_DataMap< int, int > anIdToCount;
1339 SMESH::ElementType aType = SMESH::ALL;
1340 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1342 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1343 if ( CORBA::is_nil( aGrp ) )
1347 SMESH::ElementType aCurrType = aGrp->GetType();
1348 if ( aType == SMESH::ALL )
1352 if ( aType != aCurrType )
1353 return SMESH::SMESH_Group::_nil();
1356 // calculates number of occurance ids in groups
1357 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1358 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1360 int aCurrId = aCurrIds[ i ];
1361 if ( !anIdToCount.IsBound( aCurrId ) )
1362 anIdToCount.Bind( aCurrId, 1 );
1364 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1368 // create map of ids
1369 int nbGrp = theGroups.length();
1370 vector< int > anIds;
1371 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1372 for ( ; anIter.More(); anIter.Next() )
1374 int aCurrId = anIter.Key();
1375 int aCurrNb = anIter.Value();
1376 if ( aCurrNb == nbGrp )
1377 anIds.push_back( aCurrId );
1383 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1384 if ( aResGrp->_is_nil() )
1385 return SMESH::SMESH_Group::_nil();
1387 // Create array of identifiers
1388 SMESH::long_array_var aResIds = new SMESH::long_array;
1389 aResIds->length( anIds.size() );
1391 for ( size_t i = 0; i<anIds.size(); i++ )
1392 aResIds[ i ] = anIds[i];
1393 aResGrp->Add( aResIds );
1395 // Update Python script
1396 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1397 << &theGroups << ", '" << theName << "' )";
1399 return aResGrp._retn();
1403 return SMESH::SMESH_Group::_nil();
1407 //=============================================================================
1409 * New group is created. All mesh elements that are present in
1410 * main group but do not present in tool group are added to the new one
1412 //=============================================================================
1413 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1414 SMESH::SMESH_GroupBase_ptr theGroup2,
1415 const char* theName )
1416 throw (SALOME::SALOME_Exception)
1419 _preMeshInfo->FullLoadFromFile();
1421 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1422 theGroup1->GetType() != theGroup2->GetType() )
1423 return SMESH::SMESH_Group::_nil();
1428 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1429 if ( aResGrp->_is_nil() )
1432 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1433 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1435 TColStd_MapOfInteger aMap2;
1437 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1438 aMap2.Add( anIds2[ i2 ] );
1440 TColStd_SequenceOfInteger aSeq;
1441 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1442 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1443 aSeq.Append( anIds1[ i1 ] );
1445 SMESH::long_array_var aResIds = new SMESH::long_array;
1446 aResIds->length( aSeq.Length() );
1448 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1449 aResIds[ resI ] = aSeq( resI + 1 );
1450 aResGrp->Add( aResIds );
1452 // Update Python script
1453 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1454 << theGroup1 << ", " << theGroup2 << ", '"
1455 << theName << "' )";
1457 return aResGrp._retn();
1460 //=============================================================================
1462 \brief Cut lists of groups. New group is created. All mesh elements that are
1463 present in main groups but do not present in tool groups are added to the new one
1464 \param theMainGroups list of main groups
1465 \param theToolGroups list of tool groups
1466 \param theName name of group to be created
1467 \return pointer on the group
1469 //=============================================================================
1470 SMESH::SMESH_Group_ptr
1471 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1472 const SMESH::ListOfGroups& theToolGroups,
1473 const char* theName )
1474 throw (SALOME::SALOME_Exception)
1477 _preMeshInfo->FullLoadFromFile();
1480 return SMESH::SMESH_Group::_nil();
1484 set< int > aToolIds;
1485 SMESH::ElementType aType = SMESH::ALL;
1487 // iterate through tool groups
1488 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1490 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1491 if ( CORBA::is_nil( aGrp ) )
1495 SMESH::ElementType aCurrType = aGrp->GetType();
1496 if ( aType == SMESH::ALL )
1500 if ( aType != aCurrType )
1501 return SMESH::SMESH_Group::_nil();
1505 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1506 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1508 int aCurrId = aCurrIds[ i ];
1509 aToolIds.insert( aCurrId );
1513 vector< int > anIds; // result
1515 // Iterate through main group
1516 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1518 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1519 if ( CORBA::is_nil( aGrp ) )
1523 SMESH::ElementType aCurrType = aGrp->GetType();
1524 if ( aType == SMESH::ALL )
1528 if ( aType != aCurrType )
1529 return SMESH::SMESH_Group::_nil();
1533 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1534 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1536 int aCurrId = aCurrIds[ i ];
1537 if ( !aToolIds.count( aCurrId ) )
1538 anIds.push_back( aCurrId );
1545 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1546 if ( aResGrp->_is_nil() )
1547 return SMESH::SMESH_Group::_nil();
1549 // Create array of identifiers
1550 SMESH::long_array_var aResIds = new SMESH::long_array;
1551 aResIds->length( anIds.size() );
1553 for (int i=0; i<anIds.size(); i++ )
1554 aResIds[ i ] = anIds[i];
1555 aResGrp->Add( aResIds );
1557 // Update Python script
1558 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1559 << &theMainGroups << ", " << &theToolGroups << ", '"
1560 << theName << "' )";
1562 return aResGrp._retn();
1566 return SMESH::SMESH_Group::_nil();
1570 //=============================================================================
1572 \brief Create groups of entities from existing groups of superior dimensions
1574 1) extract all nodes from each group,
1575 2) combine all elements of specified dimension laying on these nodes.
1576 \param theGroups list of source groups
1577 \param theElemType dimension of elements
1578 \param theName name of new group
1579 \return pointer on new group
1583 //=============================================================================
1585 SMESH::SMESH_Group_ptr
1586 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1587 SMESH::ElementType theElemType,
1588 const char* theName )
1589 throw (SALOME::SALOME_Exception)
1592 _preMeshInfo->FullLoadFromFile();
1594 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1596 if ( !theName || !aMeshDS )
1597 return SMESH::SMESH_Group::_nil();
1599 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1605 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1606 if ( aResGrp->_is_nil() )
1607 return SMESH::SMESH_Group::_nil();
1609 SMESHDS_GroupBase* groupBaseDS =
1610 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1611 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1615 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1617 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1618 if ( CORBA::is_nil( aGrp ) )
1621 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1622 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1624 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1626 while ( elIt->more() ) {
1627 const SMDS_MeshElement* el = elIt->next();
1628 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1629 while ( nIt->more() )
1630 resGroupCore.Add( nIt->next() );
1633 else // get elements of theElemType based on nodes of every element of group
1635 while ( elIt->more() )
1637 const SMDS_MeshElement* el = elIt->next(); // an element of group
1638 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1639 TIDSortedElemSet checkedElems;
1640 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1641 while ( nIt->more() )
1643 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1644 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1645 // check nodes of elements of theElemType around el
1646 while ( elOfTypeIt->more() )
1648 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1649 if ( !checkedElems.insert( elOfType ).second ) continue;
1651 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1652 bool allNodesOK = true;
1653 while ( nIt2->more() && allNodesOK )
1654 allNodesOK = elNodes.count( nIt2->next() );
1656 resGroupCore.Add( elOfType );
1663 // Update Python script
1664 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1665 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1667 return aResGrp._retn();
1671 return SMESH::SMESH_Group::_nil();
1675 //================================================================================
1677 * \brief Remember GEOM group data
1679 //================================================================================
1681 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1682 CORBA::Object_ptr theSmeshObj)
1684 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1687 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1688 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1689 if ( groupSO->_is_nil() )
1692 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1693 GEOM::GEOM_IGroupOperations_wrap groupOp =
1694 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1695 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1698 _geomGroupData.push_back( TGeomGroupData() );
1699 TGeomGroupData & groupData = _geomGroupData.back();
1701 CORBA::String_var entry = groupSO->GetID();
1702 groupData._groupEntry = entry.in();
1704 for ( int i = 0; i < ids->length(); ++i )
1705 groupData._indices.insert( ids[i] );
1707 groupData._smeshObject = theSmeshObj;
1710 //================================================================================
1712 * Remove GEOM group data relating to removed smesh object
1714 //================================================================================
1716 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1718 list<TGeomGroupData>::iterator
1719 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1720 for ( ; data != dataEnd; ++data ) {
1721 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1722 _geomGroupData.erase( data );
1728 //================================================================================
1730 * \brief Return new group contents if it has been changed and update group data
1732 //================================================================================
1734 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1736 TopoDS_Shape newShape;
1739 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1740 if ( study->_is_nil() ) return newShape; // means "not changed"
1741 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1742 if ( !groupSO->_is_nil() )
1744 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1745 if ( CORBA::is_nil( groupObj )) return newShape;
1746 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1748 // get indices of group items
1749 set<int> curIndices;
1750 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1751 GEOM::GEOM_IGroupOperations_wrap groupOp =
1752 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1753 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1754 for ( int i = 0; i < ids->length(); ++i )
1755 curIndices.insert( ids[i] );
1757 if ( groupData._indices == curIndices )
1758 return newShape; // group not changed
1761 groupData._indices = curIndices;
1763 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1764 if ( !geomClient ) return newShape;
1765 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1766 geomClient->RemoveShapeFromBuffer( groupIOR );
1767 newShape = _gen_i->GeomObjectToShape( geomGroup );
1770 if ( newShape.IsNull() ) {
1771 // geom group becomes empty - return empty compound
1772 TopoDS_Compound compound;
1773 BRep_Builder().MakeCompound(compound);
1774 newShape = compound;
1781 //=============================================================================
1783 * \brief Storage of shape and index used in CheckGeomGroupModif()
1785 //=============================================================================
1786 struct TIndexedShape
1789 TopoDS_Shape _shape;
1790 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1793 //=============================================================================
1795 * \brief Update objects depending on changed geom groups
1797 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1798 * issue 0020210: Update of a smesh group after modification of the associated geom group
1800 //=============================================================================
1802 void SMESH_Mesh_i::CheckGeomGroupModif()
1804 if ( !_impl->HasShapeToMesh() ) return;
1806 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1807 if ( study->_is_nil() ) return;
1809 CORBA::Long nbEntities = NbNodes() + NbElements();
1811 // Check if group contents changed
1813 typedef map< string, TopoDS_Shape > TEntry2Geom;
1814 TEntry2Geom newGroupContents;
1816 list<TGeomGroupData>::iterator
1817 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1818 for ( ; data != dataEnd; ++data )
1820 pair< TEntry2Geom::iterator, bool > it_new =
1821 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1822 bool processedGroup = !it_new.second;
1823 TopoDS_Shape& newShape = it_new.first->second;
1824 if ( !processedGroup )
1825 newShape = newGroupShape( *data );
1826 if ( newShape.IsNull() )
1827 continue; // no changes
1830 _preMeshInfo->ForgetOrLoad();
1832 if ( processedGroup ) { // update group indices
1833 list<TGeomGroupData>::iterator data2 = data;
1834 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1835 data->_indices = data2->_indices;
1838 // Update SMESH objects according to new GEOM group contents
1840 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1841 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1843 int oldID = submesh->GetId();
1844 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1846 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1848 // update hypotheses
1849 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1850 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1851 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1853 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1854 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1856 // care of submeshes
1857 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1858 int newID = newSubmesh->GetId();
1859 if ( newID != oldID ) {
1860 _mapSubMesh [ newID ] = newSubmesh;
1861 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1862 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1863 _mapSubMesh. erase(oldID);
1864 _mapSubMesh_i. erase(oldID);
1865 _mapSubMeshIor.erase(oldID);
1866 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1871 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1872 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1873 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1875 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1877 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1878 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1879 ds->SetShape( newShape );
1884 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1885 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1887 // Remove groups and submeshes basing on removed sub-shapes
1889 TopTools_MapOfShape newShapeMap;
1890 TopoDS_Iterator shapeIt( newShape );
1891 for ( ; shapeIt.More(); shapeIt.Next() )
1892 newShapeMap.Add( shapeIt.Value() );
1894 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1895 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1897 if ( newShapeMap.Contains( shapeIt.Value() ))
1899 TopTools_IndexedMapOfShape oldShapeMap;
1900 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1901 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1903 const TopoDS_Shape& oldShape = oldShapeMap(i);
1904 int oldInd = meshDS->ShapeToIndex( oldShape );
1906 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1907 if ( i_smIor != _mapSubMeshIor.end() ) {
1908 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1911 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1912 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1914 // check if a group bases on oldInd shape
1915 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1916 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1917 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1918 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1920 RemoveGroup( i_grp->second ); // several groups can base on same shape
1921 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1926 // Reassign hypotheses and update groups after setting the new shape to mesh
1928 // collect anassigned hypotheses
1929 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1930 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1931 TShapeHypList assignedHyps;
1932 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1934 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1935 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1936 if ( !hyps.empty() ) {
1937 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1938 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1939 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1942 // collect shapes supporting groups
1943 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1944 TShapeTypeList groupData;
1945 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1946 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
1947 for ( ; grIt != groups.end(); ++grIt )
1949 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
1951 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
1953 // set new shape to mesh -> DS of submeshes and geom groups is deleted
1954 _impl->ShapeToMesh( newShape );
1956 // reassign hypotheses
1957 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
1958 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
1960 TIndexedShape& geom = indS_hyps->first;
1961 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
1962 int oldID = geom._index;
1963 int newID = meshDS->ShapeToIndex( geom._shape );
1966 if ( oldID == 1 ) { // main shape
1968 geom._shape = newShape;
1970 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1971 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
1972 // care of submeshes
1973 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
1974 if ( newID != oldID ) {
1975 _mapSubMesh [ newID ] = newSubmesh;
1976 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1977 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1978 _mapSubMesh. erase(oldID);
1979 _mapSubMesh_i. erase(oldID);
1980 _mapSubMeshIor.erase(oldID);
1981 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1985 TShapeTypeList::iterator geomType = groupData.begin();
1986 for ( ; geomType != groupData.end(); ++geomType )
1988 const TIndexedShape& geom = geomType->first;
1989 int oldID = geom._index;
1990 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
1993 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
1994 CORBA::String_var name = groupSO->GetName();
1996 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
1998 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
1999 group_i->changeLocalId( newID );
2002 break; // everything has been updated
2005 } // loop on group data
2009 CORBA::Long newNbEntities = NbNodes() + NbElements();
2010 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2011 if ( newNbEntities != nbEntities )
2013 // Add all SObjects with icons to soToUpdateIcons
2014 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2016 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2017 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2018 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2020 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2021 i_gr != _mapGroups.end(); ++i_gr ) // groups
2022 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2025 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2026 for ( ; so != soToUpdateIcons.end(); ++so )
2027 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2030 //=============================================================================
2032 * \brief Create standalone group from a group on geometry or filter
2034 //=============================================================================
2036 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2039 _preMeshInfo->FullLoadFromFile();
2041 SMESH::SMESH_Group_var aGroup;
2042 if ( theGroup->_is_nil() )
2043 return aGroup._retn();
2045 Unexpect aCatch(SALOME_SalomeException);
2047 SMESH_GroupBase_i* aGroupToRem =
2048 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2050 return aGroup._retn();
2052 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2054 int anId = aGroupToRem->GetLocalID();
2055 if ( !_impl->ConvertToStandalone( anId ) )
2056 return aGroup._retn();
2057 removeGeomGroupData( theGroup );
2059 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2061 // remove old instance of group from own map
2062 _mapGroups.erase( anId );
2064 SALOMEDS::StudyBuilder_var builder;
2065 SALOMEDS::SObject_wrap aGroupSO;
2066 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2067 if ( !aStudy->_is_nil() ) {
2068 builder = aStudy->NewBuilder();
2069 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2070 if ( !aGroupSO->_is_nil() )
2072 // remove reference to geometry
2073 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2074 for ( ; chItr->More(); chItr->Next() )
2075 // Remove group's child SObject
2076 builder->RemoveObject( chItr->Value() );
2078 // Update Python script
2079 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2080 << aGroupSO << " )";
2082 // change icon of Group on Filter
2085 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2086 const int isEmpty = ( elemTypes->length() == 0 );
2089 SALOMEDS::GenericAttribute_wrap anAttr =
2090 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2091 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2092 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2098 // remember new group in own map
2099 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2100 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2102 // register CORBA object for persistence
2103 _gen_i->RegisterObject( aGroup );
2105 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2106 builder->SetIOR( aGroupSO, ior.in() );
2108 return aGroup._retn();
2111 //=============================================================================
2115 //=============================================================================
2117 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2119 if(MYDEBUG) MESSAGE( "createSubMesh" );
2120 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2122 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2123 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2124 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2125 SMESH::SMESH_subMesh_var subMesh
2126 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2128 _mapSubMesh[subMeshId] = mySubMesh;
2129 _mapSubMesh_i[subMeshId] = subMeshServant;
2130 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2132 // register CORBA object for persistence
2133 int nextId = _gen_i->RegisterObject( subMesh );
2134 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2136 // to track changes of GEOM groups
2137 addGeomGroupData( theSubShapeObject, subMesh );
2139 return subMesh._retn();
2142 //=======================================================================
2143 //function : getSubMesh
2145 //=======================================================================
2147 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2149 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2150 if ( it == _mapSubMeshIor.end() )
2151 return SMESH::SMESH_subMesh::_nil();
2153 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2157 //=============================================================================
2161 //=============================================================================
2163 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2164 GEOM::GEOM_Object_ptr theSubShapeObject )
2166 bool isHypChanged = false;
2167 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2168 return isHypChanged;
2170 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2172 CORBA::Long shapeId = theSubMesh->GetId();
2173 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2175 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2178 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2179 isHypChanged = !hyps.empty();
2180 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2181 for ( ; hyp != hyps.end(); ++hyp )
2182 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2189 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2190 isHypChanged = ( aHypList->length() > 0 );
2191 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2192 removeHypothesis( theSubShapeObject, aHypList[i] );
2195 catch( const SALOME::SALOME_Exception& ) {
2196 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2198 removeGeomGroupData( theSubShapeObject );
2200 int subMeshId = theSubMesh->GetId();
2202 _mapSubMesh.erase(subMeshId);
2203 _mapSubMesh_i.erase(subMeshId);
2204 _mapSubMeshIor.erase(subMeshId);
2206 return isHypChanged;
2209 //=============================================================================
2213 //=============================================================================
2215 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2216 const char* theName,
2217 const TopoDS_Shape& theShape,
2218 const SMESH_PredicatePtr& thePredicate )
2220 std::string newName;
2221 if ( !theName || strlen( theName ) == 0 )
2223 std::set< std::string > presentNames;
2224 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2225 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2226 presentNames.insert( i_gr->second->GetName() );
2228 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2229 } while ( !presentNames.insert( newName ).second );
2230 theName = newName.c_str();
2233 SMESH::SMESH_GroupBase_var aGroup;
2234 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2236 SMESH_GroupBase_i* aGroupImpl;
2237 if ( !theShape.IsNull() )
2238 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2239 else if ( thePredicate )
2240 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2242 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2244 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2245 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2247 // register CORBA object for persistence
2248 int nextId = _gen_i->RegisterObject( aGroup );
2249 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2251 // to track changes of GEOM groups
2252 if ( !theShape.IsNull() ) {
2253 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2254 addGeomGroupData( geom, aGroup );
2257 return aGroup._retn();
2260 //=============================================================================
2262 * SMESH_Mesh_i::removeGroup
2264 * Should be called by ~SMESH_Group_i()
2266 //=============================================================================
2268 void SMESH_Mesh_i::removeGroup( const int theId )
2270 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2271 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2272 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2273 _mapGroups.erase( theId );
2274 removeGeomGroupData( group );
2275 if (! _impl->RemoveGroup( theId ))
2277 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2278 RemoveGroup( group );
2283 //=============================================================================
2287 //=============================================================================
2289 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2290 throw(SALOME::SALOME_Exception)
2293 _preMeshInfo->FullLoadFromFile();
2295 SMESH::log_array_var aLog;
2297 list < SMESHDS_Command * >logDS = _impl->GetLog();
2298 aLog = new SMESH::log_array;
2300 int lg = logDS.size();
2303 list < SMESHDS_Command * >::iterator its = logDS.begin();
2304 while(its != logDS.end()){
2305 SMESHDS_Command *com = *its;
2306 int comType = com->GetType();
2308 int lgcom = com->GetNumber();
2310 const list < int >&intList = com->GetIndexes();
2311 int inum = intList.size();
2313 list < int >::const_iterator ii = intList.begin();
2314 const list < double >&coordList = com->GetCoords();
2315 int rnum = coordList.size();
2317 list < double >::const_iterator ir = coordList.begin();
2318 aLog[indexLog].commandType = comType;
2319 aLog[indexLog].number = lgcom;
2320 aLog[indexLog].coords.length(rnum);
2321 aLog[indexLog].indexes.length(inum);
2322 for(int i = 0; i < rnum; i++){
2323 aLog[indexLog].coords[i] = *ir;
2324 //MESSAGE(" "<<i<<" "<<ir.Value());
2327 for(int i = 0; i < inum; i++){
2328 aLog[indexLog].indexes[i] = *ii;
2329 //MESSAGE(" "<<i<<" "<<ii.Value());
2338 catch(SALOME_Exception & S_ex){
2339 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2341 return aLog._retn();
2345 //=============================================================================
2349 //=============================================================================
2351 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2353 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2357 //=============================================================================
2361 //=============================================================================
2363 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2365 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2369 //=============================================================================
2373 //=============================================================================
2375 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2380 //=============================================================================
2383 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2384 // issue 0020918: groups removal is caused by hyp modification
2385 // issue 0021208: to forget not loaded mesh data at hyp modification
2386 struct TCallUp_i : public SMESH_Mesh::TCallUp
2388 SMESH_Mesh_i* _mesh;
2389 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2390 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2391 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2392 virtual void Load () { _mesh->Load(); }
2396 //================================================================================
2398 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2400 //================================================================================
2402 void SMESH_Mesh_i::onHypothesisModified()
2405 _preMeshInfo->ForgetOrLoad();
2408 //=============================================================================
2412 //=============================================================================
2414 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2416 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2419 _impl->SetCallUp( new TCallUp_i(this));
2422 //=============================================================================
2426 //=============================================================================
2428 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2430 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2434 //=============================================================================
2436 * Return mesh editor
2438 //=============================================================================
2440 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2443 _preMeshInfo->FullLoadFromFile();
2445 // Create MeshEditor
2446 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2447 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2449 // Update Python script
2450 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2452 return aMesh._retn();
2455 //=============================================================================
2457 * Return mesh edition previewer
2459 //=============================================================================
2461 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2464 _preMeshInfo->FullLoadFromFile();
2466 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2467 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2468 return aMesh._retn();
2471 //================================================================================
2473 * \brief Return true if the mesh has been edited since a last total re-compute
2474 * and those modifications may prevent successful partial re-compute
2476 //================================================================================
2478 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2480 Unexpect aCatch(SALOME_SalomeException);
2481 return _impl->HasModificationsToDiscard();
2484 //================================================================================
2486 * \brief Returns a random unique color
2488 //================================================================================
2490 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2492 const int MAX_ATTEMPTS = 100;
2494 double tolerance = 0.5;
2495 SALOMEDS::Color col;
2499 // generate random color
2500 double red = (double)rand() / RAND_MAX;
2501 double green = (double)rand() / RAND_MAX;
2502 double blue = (double)rand() / RAND_MAX;
2503 // check existence in the list of the existing colors
2504 bool matched = false;
2505 std::list<SALOMEDS::Color>::const_iterator it;
2506 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2507 SALOMEDS::Color color = *it;
2508 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2509 matched = tol < tolerance;
2511 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2512 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2520 //=============================================================================
2522 * Sets auto-color mode. If it is on, groups get unique random colors
2524 //=============================================================================
2526 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2528 Unexpect aCatch(SALOME_SalomeException);
2529 _impl->SetAutoColor(theAutoColor);
2531 TPythonDump pyDump; // not to dump group->SetColor() from below code
2532 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2534 std::list<SALOMEDS::Color> aReservedColors;
2535 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2536 for ( ; it != _mapGroups.end(); it++ ) {
2537 if ( CORBA::is_nil( it->second )) continue;
2538 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2539 it->second->SetColor( aColor );
2540 aReservedColors.push_back( aColor );
2544 //=============================================================================
2546 * Returns true if auto-color mode is on
2548 //=============================================================================
2550 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2552 Unexpect aCatch(SALOME_SalomeException);
2553 return _impl->GetAutoColor();
2556 //=============================================================================
2558 * Checks if there are groups with equal names
2560 //=============================================================================
2562 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2564 return _impl->HasDuplicatedGroupNamesMED();
2567 //================================================================================
2569 * \brief Care of a file before exporting mesh into it
2571 //================================================================================
2573 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2575 TCollection_AsciiString aFullName ((char*)file);
2576 OSD_Path aPath (aFullName);
2577 OSD_File aFile (aPath);
2578 if (aFile.Exists()) {
2579 // existing filesystem node
2580 if (aFile.KindOfFile() == OSD_FILE) {
2581 if (aFile.IsWriteable()) {
2586 if (aFile.Failed()) {
2587 TCollection_AsciiString msg ("File ");
2588 msg += aFullName + " cannot be replaced.";
2589 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2592 TCollection_AsciiString msg ("File ");
2593 msg += aFullName + " cannot be overwritten.";
2594 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2597 TCollection_AsciiString msg ("Location ");
2598 msg += aFullName + " is not a file.";
2599 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2602 // nonexisting file; check if it can be created
2604 aFile.Build(OSD_WriteOnly, OSD_Protection());
2605 if (aFile.Failed()) {
2606 TCollection_AsciiString msg ("You cannot create the file ");
2607 msg += aFullName + ". Check the directory existance and access rights.";
2608 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2616 //================================================================================
2618 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2619 * \param file - file name
2620 * \param overwrite - to erase the file or not
2621 * \retval string - mesh name
2623 //================================================================================
2625 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2626 CORBA::Boolean overwrite)
2629 PrepareForWriting(file, overwrite);
2630 string aMeshName = "Mesh";
2631 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2632 if ( !aStudy->_is_nil() ) {
2633 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2634 if ( !aMeshSO->_is_nil() ) {
2635 CORBA::String_var name = aMeshSO->GetName();
2637 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2638 if ( !aStudy->GetProperties()->IsLocked() )
2640 SALOMEDS::GenericAttribute_wrap anAttr;
2641 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2642 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2643 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2644 ASSERT(!aFileName->_is_nil());
2645 aFileName->SetValue(file);
2646 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2647 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2648 ASSERT(!aFileType->_is_nil());
2649 aFileType->SetValue("FICHIERMED");
2653 // Update Python script
2654 // set name of mesh before export
2655 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2657 // check names of groups
2663 //================================================================================
2665 * \brief Export to med file
2667 //================================================================================
2669 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2670 CORBA::Boolean auto_groups,
2671 SMESH::MED_VERSION theVersion,
2672 CORBA::Boolean overwrite)
2673 throw(SALOME::SALOME_Exception)
2675 Unexpect aCatch(SALOME_SalomeException);
2677 _preMeshInfo->FullLoadFromFile();
2679 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2680 TPythonDump() << _this() << ".ExportToMEDX( r'"
2681 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2683 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2686 //================================================================================
2688 * \brief Export a mesh to a med file
2690 //================================================================================
2692 void SMESH_Mesh_i::ExportToMED (const char* file,
2693 CORBA::Boolean auto_groups,
2694 SMESH::MED_VERSION theVersion)
2695 throw(SALOME::SALOME_Exception)
2697 ExportToMEDX(file,auto_groups,theVersion,true);
2700 //================================================================================
2702 * \brief Export a mesh to a med file
2704 //================================================================================
2706 void SMESH_Mesh_i::ExportMED (const char* file,
2707 CORBA::Boolean auto_groups)
2708 throw(SALOME::SALOME_Exception)
2710 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2713 //================================================================================
2715 * \brief Export a mesh to a SAUV file
2717 //================================================================================
2719 void SMESH_Mesh_i::ExportSAUV (const char* file,
2720 CORBA::Boolean auto_groups)
2721 throw(SALOME::SALOME_Exception)
2723 Unexpect aCatch(SALOME_SalomeException);
2725 _preMeshInfo->FullLoadFromFile();
2727 string aMeshName = prepareMeshNameAndGroups(file, true);
2728 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2729 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2733 //================================================================================
2735 * \brief Export a mesh to a DAT file
2737 //================================================================================
2739 void SMESH_Mesh_i::ExportDAT (const char *file)
2740 throw(SALOME::SALOME_Exception)
2742 Unexpect aCatch(SALOME_SalomeException);
2744 _preMeshInfo->FullLoadFromFile();
2746 // Update Python script
2747 // check names of groups
2749 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2752 PrepareForWriting(file);
2753 _impl->ExportDAT(file);
2756 //================================================================================
2758 * \brief Export a mesh to an UNV file
2760 //================================================================================
2762 void SMESH_Mesh_i::ExportUNV (const char *file)
2763 throw(SALOME::SALOME_Exception)
2765 Unexpect aCatch(SALOME_SalomeException);
2767 _preMeshInfo->FullLoadFromFile();
2769 // Update Python script
2770 // check names of groups
2772 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2775 PrepareForWriting(file);
2776 _impl->ExportUNV(file);
2779 //================================================================================
2781 * \brief Export a mesh to an STL file
2783 //================================================================================
2785 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2786 throw(SALOME::SALOME_Exception)
2788 Unexpect aCatch(SALOME_SalomeException);
2790 _preMeshInfo->FullLoadFromFile();
2792 // Update Python script
2793 // check names of groups
2795 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2798 PrepareForWriting(file);
2799 _impl->ExportSTL(file, isascii);
2802 //================================================================================
2804 * \brief Export a part of mesh to a med file
2806 //================================================================================
2808 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2810 CORBA::Boolean auto_groups,
2811 ::SMESH::MED_VERSION version,
2812 ::CORBA::Boolean overwrite)
2813 throw (SALOME::SALOME_Exception)
2815 Unexpect aCatch(SALOME_SalomeException);
2817 _preMeshInfo->FullLoadFromFile();
2819 PrepareForWriting(file, overwrite);
2821 string aMeshName = "Mesh";
2822 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2823 if ( !aStudy->_is_nil() ) {
2824 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2825 if ( !SO->_is_nil() ) {
2826 CORBA::String_var name = SO->GetName();
2830 SMESH_MeshPartDS partDS( meshPart );
2831 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2833 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2834 << auto_groups << ", " << version << ", " << overwrite << " )";
2837 //================================================================================
2839 * \brief Export a part of mesh to a DAT file
2841 //================================================================================
2843 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2845 throw (SALOME::SALOME_Exception)
2847 Unexpect aCatch(SALOME_SalomeException);
2849 _preMeshInfo->FullLoadFromFile();
2851 PrepareForWriting(file);
2853 SMESH_MeshPartDS partDS( meshPart );
2854 _impl->ExportDAT(file,&partDS);
2856 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2858 //================================================================================
2860 * \brief Export a part of mesh to an UNV file
2862 //================================================================================
2864 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2866 throw (SALOME::SALOME_Exception)
2868 Unexpect aCatch(SALOME_SalomeException);
2870 _preMeshInfo->FullLoadFromFile();
2872 PrepareForWriting(file);
2874 SMESH_MeshPartDS partDS( meshPart );
2875 _impl->ExportUNV(file, &partDS);
2877 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2879 //================================================================================
2881 * \brief Export a part of mesh to an STL file
2883 //================================================================================
2885 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2887 ::CORBA::Boolean isascii)
2888 throw (SALOME::SALOME_Exception)
2890 Unexpect aCatch(SALOME_SalomeException);
2892 _preMeshInfo->FullLoadFromFile();
2894 PrepareForWriting(file);
2896 SMESH_MeshPartDS partDS( meshPart );
2897 _impl->ExportSTL(file, isascii, &partDS);
2899 TPythonDump() << _this() << ".ExportPartToSTL( "
2900 << meshPart<< ", r'" << file << "', " << isascii << ")";
2903 //================================================================================
2905 * \brief Export a part of mesh to an STL file
2907 //================================================================================
2909 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2911 CORBA::Boolean overwrite)
2912 throw (SALOME::SALOME_Exception)
2915 Unexpect aCatch(SALOME_SalomeException);
2917 _preMeshInfo->FullLoadFromFile();
2919 PrepareForWriting(file,overwrite);
2921 SMESH_MeshPartDS partDS( meshPart );
2922 _impl->ExportCGNS(file, &partDS);
2924 TPythonDump() << _this() << ".ExportCGNS( "
2925 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2927 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2931 //================================================================================
2933 * \brief Export a part of mesh to a GMF file
2935 //================================================================================
2937 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2939 bool withRequiredGroups)
2940 throw (SALOME::SALOME_Exception)
2942 Unexpect aCatch(SALOME_SalomeException);
2944 _preMeshInfo->FullLoadFromFile();
2946 PrepareForWriting(file,/*overwrite=*/true);
2948 SMESH_MeshPartDS partDS( meshPart );
2949 _impl->ExportGMF(file, &partDS, withRequiredGroups);
2951 TPythonDump() << _this() << ".ExportGMF( "
2952 << meshPart<< ", r'"
2954 << withRequiredGroups << ")";
2957 //=============================================================================
2959 * Return implementation of SALOME_MED::MESH interfaces
2961 //=============================================================================
2963 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
2965 Unexpect aCatch(SALOME_SalomeException);
2967 _preMeshInfo->FullLoadFromFile();
2969 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
2970 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
2971 return aMesh._retn();
2974 //=============================================================================
2976 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
2978 Unexpect aCatch(SALOME_SalomeException);
2980 return _preMeshInfo->NbNodes();
2982 return _impl->NbNodes();
2985 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
2987 Unexpect aCatch(SALOME_SalomeException);
2989 return _preMeshInfo->NbElements();
2991 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
2994 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
2996 Unexpect aCatch(SALOME_SalomeException);
2998 return _preMeshInfo->Nb0DElements();
3000 return _impl->Nb0DElements();
3003 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3005 Unexpect aCatch(SALOME_SalomeException);
3007 return _preMeshInfo->NbBalls();
3009 return _impl->NbBalls();
3012 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3014 Unexpect aCatch(SALOME_SalomeException);
3016 return _preMeshInfo->NbEdges();
3018 return _impl->NbEdges();
3021 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3022 throw(SALOME::SALOME_Exception)
3024 Unexpect aCatch(SALOME_SalomeException);
3026 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3028 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3031 //=============================================================================
3033 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3035 Unexpect aCatch(SALOME_SalomeException);
3037 return _preMeshInfo->NbFaces();
3039 return _impl->NbFaces();
3042 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3044 Unexpect aCatch(SALOME_SalomeException);
3046 return _preMeshInfo->NbTriangles();
3048 return _impl->NbTriangles();
3051 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3053 Unexpect aCatch(SALOME_SalomeException);
3055 return _preMeshInfo->NbQuadrangles();
3057 return _impl->NbQuadrangles();
3060 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3062 Unexpect aCatch(SALOME_SalomeException);
3064 return _preMeshInfo->NbBiQuadQuadrangles();
3066 return _impl->NbBiQuadQuadrangles();
3069 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3071 Unexpect aCatch(SALOME_SalomeException);
3073 return _preMeshInfo->NbPolygons();
3075 return _impl->NbPolygons();
3078 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3079 throw(SALOME::SALOME_Exception)
3081 Unexpect aCatch(SALOME_SalomeException);
3083 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3085 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3088 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3089 throw(SALOME::SALOME_Exception)
3091 Unexpect aCatch(SALOME_SalomeException);
3093 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3095 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3098 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3099 throw(SALOME::SALOME_Exception)
3101 Unexpect aCatch(SALOME_SalomeException);
3103 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3105 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3108 //=============================================================================
3110 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3112 Unexpect aCatch(SALOME_SalomeException);
3114 return _preMeshInfo->NbVolumes();
3116 return _impl->NbVolumes();
3119 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3121 Unexpect aCatch(SALOME_SalomeException);
3123 return _preMeshInfo->NbTetras();
3125 return _impl->NbTetras();
3128 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3130 Unexpect aCatch(SALOME_SalomeException);
3132 return _preMeshInfo->NbHexas();
3134 return _impl->NbHexas();
3137 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3139 Unexpect aCatch(SALOME_SalomeException);
3141 return _preMeshInfo->NbTriQuadHexas();
3143 return _impl->NbTriQuadraticHexas();
3146 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3148 Unexpect aCatch(SALOME_SalomeException);
3150 return _preMeshInfo->NbPyramids();
3152 return _impl->NbPyramids();
3155 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3157 Unexpect aCatch(SALOME_SalomeException);
3159 return _preMeshInfo->NbPrisms();
3161 return _impl->NbPrisms();
3164 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3166 Unexpect aCatch(SALOME_SalomeException);
3168 return _preMeshInfo->NbHexPrisms();
3170 return _impl->NbHexagonalPrisms();
3173 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3175 Unexpect aCatch(SALOME_SalomeException);
3177 return _preMeshInfo->NbPolyhedrons();
3179 return _impl->NbPolyhedrons();
3182 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3183 throw(SALOME::SALOME_Exception)
3185 Unexpect aCatch(SALOME_SalomeException);
3187 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3189 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3192 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3193 throw(SALOME::SALOME_Exception)
3195 Unexpect aCatch(SALOME_SalomeException);
3197 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3199 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3202 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3203 throw(SALOME::SALOME_Exception)
3205 Unexpect aCatch(SALOME_SalomeException);
3207 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3209 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3212 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3213 throw(SALOME::SALOME_Exception)
3215 Unexpect aCatch(SALOME_SalomeException);
3217 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3219 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3222 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3223 throw(SALOME::SALOME_Exception)
3225 Unexpect aCatch(SALOME_SalomeException);
3227 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3229 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3232 //=============================================================================
3234 * Returns nb of published sub-meshes
3236 //=============================================================================
3238 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3240 Unexpect aCatch(SALOME_SalomeException);
3241 return _mapSubMesh_i.size();
3244 //=============================================================================
3246 * Dumps mesh into a string
3248 //=============================================================================
3250 char* SMESH_Mesh_i::Dump()
3254 return CORBA::string_dup( os.str().c_str() );
3257 //=============================================================================
3259 * Method of SMESH_IDSource interface
3261 //=============================================================================
3263 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3265 return GetElementsId();
3268 //=============================================================================
3270 * Returns ids of all elements
3272 //=============================================================================
3274 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3275 throw (SALOME::SALOME_Exception)
3277 Unexpect aCatch(SALOME_SalomeException);
3279 _preMeshInfo->FullLoadFromFile();
3281 SMESH::long_array_var aResult = new SMESH::long_array();
3282 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3284 if ( aSMESHDS_Mesh == NULL )
3285 return aResult._retn();
3287 long nbElements = NbElements();
3288 aResult->length( nbElements );
3289 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3290 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3291 aResult[i] = anIt->next()->GetID();
3293 return aResult._retn();
3297 //=============================================================================
3299 * Returns ids of all elements of given type
3301 //=============================================================================
3303 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3304 throw (SALOME::SALOME_Exception)
3306 Unexpect aCatch(SALOME_SalomeException);
3308 _preMeshInfo->FullLoadFromFile();
3310 SMESH::long_array_var aResult = new SMESH::long_array();
3311 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3313 if ( aSMESHDS_Mesh == NULL )
3314 return aResult._retn();
3316 long nbElements = NbElements();
3318 // No sense in returning ids of elements along with ids of nodes:
3319 // when theElemType == SMESH::ALL, return node ids only if
3320 // there are no elements
3321 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3322 return GetNodesId();
3324 aResult->length( nbElements );
3328 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3329 while ( i < nbElements && anIt->more() ) {
3330 const SMDS_MeshElement* anElem = anIt->next();
3331 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3332 aResult[i++] = anElem->GetID();
3335 aResult->length( i );
3337 return aResult._retn();
3340 //=============================================================================
3342 * Returns ids of all nodes
3344 //=============================================================================
3346 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3347 throw (SALOME::SALOME_Exception)
3349 Unexpect aCatch(SALOME_SalomeException);
3351 _preMeshInfo->FullLoadFromFile();
3353 SMESH::long_array_var aResult = new SMESH::long_array();
3354 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3356 if ( aSMESHDS_Mesh == NULL )
3357 return aResult._retn();
3359 long nbNodes = NbNodes();
3360 aResult->length( nbNodes );
3361 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3362 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3363 aResult[i] = anIt->next()->GetID();
3365 return aResult._retn();
3368 //=============================================================================
3372 //=============================================================================
3374 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3375 throw (SALOME::SALOME_Exception)
3378 _preMeshInfo->FullLoadFromFile();
3380 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3383 //=============================================================================
3387 //=============================================================================
3389 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3390 throw (SALOME::SALOME_Exception)
3393 _preMeshInfo->FullLoadFromFile();
3395 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3397 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3399 return ( SMESH::EntityType ) e->GetEntityType();
3402 //=============================================================================
3404 * Returns ID of elements for given submesh
3406 //=============================================================================
3407 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3408 throw (SALOME::SALOME_Exception)
3411 _preMeshInfo->FullLoadFromFile();
3413 SMESH::long_array_var aResult = new SMESH::long_array();
3415 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3416 if(!SM) return aResult._retn();
3418 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3419 if(!SDSM) return aResult._retn();
3421 aResult->length(SDSM->NbElements());
3423 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3425 while ( eIt->more() ) {
3426 aResult[i++] = eIt->next()->GetID();
3429 return aResult._retn();
3433 //=============================================================================
3435 * Returns ID of nodes for given submesh
3436 * If param all==true - returns all nodes, else -
3437 * returns only nodes on shapes.
3439 //=============================================================================
3440 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3442 throw (SALOME::SALOME_Exception)
3445 _preMeshInfo->FullLoadFromFile();
3447 SMESH::long_array_var aResult = new SMESH::long_array();
3449 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3450 if(!SM) return aResult._retn();
3452 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3453 if(!SDSM) return aResult._retn();
3456 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3457 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3458 while ( nIt->more() ) {
3459 const SMDS_MeshNode* elem = nIt->next();
3460 theElems.insert( elem->GetID() );
3463 else { // all nodes of submesh elements
3464 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3465 while ( eIt->more() ) {
3466 const SMDS_MeshElement* anElem = eIt->next();
3467 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3468 while ( nIt->more() ) {
3469 const SMDS_MeshElement* elem = nIt->next();
3470 theElems.insert( elem->GetID() );
3475 aResult->length(theElems.size());
3476 set<int>::iterator itElem;
3478 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3479 aResult[i++] = *itElem;
3481 return aResult._retn();
3484 //=============================================================================
3486 * Returns type of elements for given submesh
3488 //=============================================================================
3490 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3491 throw (SALOME::SALOME_Exception)
3494 _preMeshInfo->FullLoadFromFile();
3496 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3497 if(!SM) return SMESH::ALL;
3499 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3500 if(!SDSM) return SMESH::ALL;
3502 if(SDSM->NbElements()==0)
3503 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3505 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3506 const SMDS_MeshElement* anElem = eIt->next();
3507 return ( SMESH::ElementType ) anElem->GetType();
3511 //=============================================================================
3513 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3515 //=============================================================================
3517 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3520 _preMeshInfo->FullLoadFromFile();
3522 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3524 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3529 //=============================================================================
3531 * Get XYZ coordinates of node as list of double
3532 * If there is not node for given ID - returns empty list
3534 //=============================================================================
3536 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3539 _preMeshInfo->FullLoadFromFile();
3541 SMESH::double_array_var aResult = new SMESH::double_array();
3542 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3543 if ( aSMESHDS_Mesh == NULL )
3544 return aResult._retn();
3547 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3549 return aResult._retn();
3553 aResult[0] = aNode->X();
3554 aResult[1] = aNode->Y();
3555 aResult[2] = aNode->Z();
3556 return aResult._retn();
3560 //=============================================================================
3562 * For given node returns list of IDs of inverse elements
3563 * If there is not node for given ID - returns empty list
3565 //=============================================================================
3567 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3570 _preMeshInfo->FullLoadFromFile();
3572 SMESH::long_array_var aResult = new SMESH::long_array();
3573 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3574 if ( aSMESHDS_Mesh == NULL )
3575 return aResult._retn();
3578 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3580 return aResult._retn();
3582 // find inverse elements
3583 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3584 TColStd_SequenceOfInteger IDs;
3585 while(eIt->more()) {
3586 const SMDS_MeshElement* elem = eIt->next();
3587 IDs.Append(elem->GetID());
3589 if(IDs.Length()>0) {
3590 aResult->length(IDs.Length());
3592 for(; i<=IDs.Length(); i++) {
3593 aResult[i-1] = IDs.Value(i);
3596 return aResult._retn();
3599 //=============================================================================
3601 * \brief Return position of a node on shape
3603 //=============================================================================
3605 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3608 _preMeshInfo->FullLoadFromFile();
3610 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3611 aNodePosition->shapeID = 0;
3612 aNodePosition->shapeType = GEOM::SHAPE;
3614 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3615 if ( !mesh ) return aNodePosition;
3617 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3619 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3621 aNodePosition->shapeID = aNode->getshapeId();
3622 switch ( pos->GetTypeOfPosition() ) {
3624 aNodePosition->shapeType = GEOM::EDGE;
3625 aNodePosition->params.length(1);
3626 aNodePosition->params[0] =
3627 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3630 aNodePosition->shapeType = GEOM::FACE;
3631 aNodePosition->params.length(2);
3632 aNodePosition->params[0] =
3633 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3634 aNodePosition->params[1] =
3635 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3637 case SMDS_TOP_VERTEX:
3638 aNodePosition->shapeType = GEOM::VERTEX;
3640 case SMDS_TOP_3DSPACE:
3641 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3642 aNodePosition->shapeType = GEOM::SOLID;
3643 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3644 aNodePosition->shapeType = GEOM::SHELL;
3650 return aNodePosition;
3653 //=============================================================================
3655 * If given element is node returns IDs of shape from position
3656 * If there is not node for given ID - returns -1
3658 //=============================================================================
3660 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3663 _preMeshInfo->FullLoadFromFile();
3665 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3666 if ( aSMESHDS_Mesh == NULL )
3670 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3672 return aNode->getshapeId();
3679 //=============================================================================
3681 * For given element returns ID of result shape after
3682 * ::FindShape() from SMESH_MeshEditor
3683 * If there is not element for given ID - returns -1
3685 //=============================================================================
3687 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3690 _preMeshInfo->FullLoadFromFile();
3692 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3693 if ( aSMESHDS_Mesh == NULL )
3696 // try to find element
3697 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3701 ::SMESH_MeshEditor aMeshEditor(_impl);
3702 int index = aMeshEditor.FindShape( elem );
3710 //=============================================================================
3712 * Returns number of nodes for given element
3713 * If there is not element for given ID - returns -1
3715 //=============================================================================
3717 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3720 _preMeshInfo->FullLoadFromFile();
3722 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3723 if ( aSMESHDS_Mesh == NULL ) return -1;
3724 // try to find element
3725 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3726 if(!elem) return -1;
3727 return elem->NbNodes();
3731 //=============================================================================
3733 * Returns ID of node by given index for given element
3734 * If there is not element for given ID - returns -1
3735 * If there is not node for given index - returns -2
3737 //=============================================================================
3739 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3742 _preMeshInfo->FullLoadFromFile();
3744 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3745 if ( aSMESHDS_Mesh == NULL ) return -1;
3746 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3747 if(!elem) return -1;
3748 if( index>=elem->NbNodes() || index<0 ) return -1;
3749 return elem->GetNode(index)->GetID();
3752 //=============================================================================
3754 * Returns IDs of nodes of given element
3756 //=============================================================================
3758 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3761 _preMeshInfo->FullLoadFromFile();
3763 SMESH::long_array_var aResult = new SMESH::long_array();
3764 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3766 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3768 aResult->length( elem->NbNodes() );
3769 for ( int i = 0; i < elem->NbNodes(); ++i )
3770 aResult[ i ] = elem->GetNode( i )->GetID();
3773 return aResult._retn();
3776 //=============================================================================
3778 * Returns true if given node is medium node
3779 * in given quadratic element
3781 //=============================================================================
3783 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3786 _preMeshInfo->FullLoadFromFile();
3788 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3789 if ( aSMESHDS_Mesh == NULL ) return false;
3791 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3792 if(!aNode) return false;
3793 // try to find element
3794 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3795 if(!elem) return false;
3797 return elem->IsMediumNode(aNode);
3801 //=============================================================================
3803 * Returns true if given node is medium node
3804 * in one of quadratic elements
3806 //=============================================================================
3808 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3809 SMESH::ElementType theElemType)
3812 _preMeshInfo->FullLoadFromFile();
3814 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3815 if ( aSMESHDS_Mesh == NULL ) return false;
3818 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3819 if(!aNode) return false;
3821 SMESH_MesherHelper aHelper( *(_impl) );
3823 SMDSAbs_ElementType aType;
3824 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3825 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3826 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3827 else aType = SMDSAbs_All;
3829 return aHelper.IsMedium(aNode,aType);
3833 //=============================================================================
3835 * Returns number of edges for given element
3837 //=============================================================================
3839 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3842 _preMeshInfo->FullLoadFromFile();
3844 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3845 if ( aSMESHDS_Mesh == NULL ) return -1;
3846 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3847 if(!elem) return -1;
3848 return elem->NbEdges();
3852 //=============================================================================
3854 * Returns number of faces for given element
3856 //=============================================================================
3858 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3861 _preMeshInfo->FullLoadFromFile();
3863 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3864 if ( aSMESHDS_Mesh == NULL ) return -1;
3865 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3866 if(!elem) return -1;
3867 return elem->NbFaces();
3870 //=======================================================================
3871 //function : GetElemFaceNodes
3872 //purpose : Returns nodes of given face (counted from zero) for given element.
3873 //=======================================================================
3875 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3876 CORBA::Short faceIndex)
3879 _preMeshInfo->FullLoadFromFile();
3881 SMESH::long_array_var aResult = new SMESH::long_array();
3882 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3884 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3886 SMDS_VolumeTool vtool( elem );
3887 if ( faceIndex < vtool.NbFaces() )
3889 aResult->length( vtool.NbFaceNodes( faceIndex ));
3890 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3891 for ( int i = 0; i < aResult->length(); ++i )
3892 aResult[ i ] = nn[ i ]->GetID();
3896 return aResult._retn();
3899 //=======================================================================
3900 //function : FindElementByNodes
3901 //purpose : Returns an element based on all given nodes.
3902 //=======================================================================
3904 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3907 _preMeshInfo->FullLoadFromFile();
3909 CORBA::Long elemID(0);
3910 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3912 vector< const SMDS_MeshNode * > nn( nodes.length() );
3913 for ( int i = 0; i < nodes.length(); ++i )
3914 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3917 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3918 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
3919 _impl->NbFaces ( ORDER_QUADRATIC ) ||
3920 _impl->NbVolumes( ORDER_QUADRATIC )))
3921 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3923 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3928 //=============================================================================
3930 * Returns true if given element is polygon
3932 //=============================================================================
3934 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3937 _preMeshInfo->FullLoadFromFile();
3939 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3940 if ( aSMESHDS_Mesh == NULL ) return false;
3941 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3942 if(!elem) return false;
3943 return elem->IsPoly();
3947 //=============================================================================
3949 * Returns true if given element is quadratic
3951 //=============================================================================
3953 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
3956 _preMeshInfo->FullLoadFromFile();
3958 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3959 if ( aSMESHDS_Mesh == NULL ) return false;
3960 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3961 if(!elem) return false;
3962 return elem->IsQuadratic();
3965 //=============================================================================
3967 * Returns diameter of ball discrete element or zero in case of an invalid \a id
3969 //=============================================================================
3971 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
3974 _preMeshInfo->FullLoadFromFile();
3976 if ( const SMDS_BallElement* ball =
3977 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
3978 return ball->GetDiameter();
3983 //=============================================================================
3985 * Returns bary center for given element
3987 //=============================================================================
3989 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
3992 _preMeshInfo->FullLoadFromFile();
3994 SMESH::double_array_var aResult = new SMESH::double_array();
3995 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3996 if ( aSMESHDS_Mesh == NULL )
3997 return aResult._retn();
3999 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4001 return aResult._retn();
4003 if(elem->GetType()==SMDSAbs_Volume) {
4004 SMDS_VolumeTool aTool;
4005 if(aTool.Set(elem)) {
4007 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4012 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4014 double x=0., y=0., z=0.;
4015 for(; anIt->more(); ) {
4017 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4031 return aResult._retn();
4035 //=============================================================================
4037 * Create and publish group servants if any groups were imported or created anyhow
4039 //=============================================================================
4041 void SMESH_Mesh_i::CreateGroupServants()
4043 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4046 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4047 while ( groupIt->more() )
4049 ::SMESH_Group* group = groupIt->next();
4050 int anId = group->GetGroupDS()->GetID();
4052 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4053 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4055 addedIDs.insert( anId );
4057 SMESH_GroupBase_i* aGroupImpl;
4059 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4060 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4062 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4063 shape = groupOnGeom->GetShape();
4066 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4069 SMESH::SMESH_GroupBase_var groupVar =
4070 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4071 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4073 // register CORBA object for persistence
4074 int nextId = _gen_i->RegisterObject( groupVar );
4075 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4077 // publishing the groups in the study
4078 if ( !aStudy->_is_nil() ) {
4079 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4080 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4083 if ( !addedIDs.empty() )
4086 set<int>::iterator id = addedIDs.begin();
4087 for ( ; id != addedIDs.end(); ++id )
4089 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4090 int i = std::distance( _mapGroups.begin(), it );
4091 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4096 //=============================================================================
4098 * \brief Return groups cantained in _mapGroups by their IDs
4100 //=============================================================================
4102 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4104 int nbGroups = groupIDs.size();
4105 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4106 aList->length( nbGroups );
4108 list<int>::const_iterator ids = groupIDs.begin();
4109 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4111 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4112 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4113 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4115 aList->length( nbGroups );
4116 return aList._retn();
4119 //=============================================================================
4121 * \brief Return information about imported file
4123 //=============================================================================
4125 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4127 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4128 if ( !res.operator->() ) {
4129 res = new SALOME_MED::MedFileInfo;
4131 res->fileSize = res->major = res->minor = res->release = -1;
4136 //=============================================================================
4138 * \brief Pass names of mesh groups from study to mesh DS
4140 //=============================================================================
4142 void SMESH_Mesh_i::checkGroupNames()
4144 int nbGrp = NbGroups();
4148 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4149 if ( aStudy->_is_nil() )
4150 return; // nothing to do
4152 SMESH::ListOfGroups* grpList = 0;
4153 // avoid dump of "GetGroups"
4155 // store python dump into a local variable inside local scope
4156 SMESH::TPythonDump pDump; // do not delete this line of code
4157 grpList = GetGroups();
4160 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4161 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4164 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4165 if ( aGrpSO->_is_nil() )
4167 // correct name of the mesh group if necessary
4168 const char* guiName = aGrpSO->GetName();
4169 if ( strcmp(guiName, aGrp->GetName()) )
4170 aGrp->SetName( guiName );
4174 //=============================================================================
4176 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4178 //=============================================================================
4179 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4181 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4182 // CORBA::string_dup(theParameters));
4183 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4186 //=============================================================================
4188 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4190 //=============================================================================
4191 char* SMESH_Mesh_i::GetParameters()
4193 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4194 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4197 //=============================================================================
4199 * \brief Returns list of notebook variables used for last Mesh operation
4201 //=============================================================================
4202 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4204 SMESH::string_array_var aResult = new SMESH::string_array();
4205 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4207 char *aParameters = GetParameters();
4208 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4209 if(!aStudy->_is_nil()) {
4210 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4211 if(aSections->length() > 0) {
4212 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4213 aResult->length(aVars.length());
4214 for(int i = 0;i < aVars.length();i++)
4215 aResult[i] = CORBA::string_dup( aVars[i]);
4219 return aResult._retn();
4222 //=======================================================================
4223 //function : GetTypes
4224 //purpose : Returns types of elements it contains
4225 //=======================================================================
4227 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4230 return _preMeshInfo->GetTypes();
4232 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4236 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4237 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4238 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4239 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4240 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4241 types->length( nbTypes );
4243 return types._retn();
4246 //=======================================================================
4247 //function : GetMesh
4248 //purpose : Returns self
4249 //=======================================================================
4251 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4253 return SMESH::SMESH_Mesh::_duplicate( _this() );
4256 //=======================================================================
4257 //function : IsMeshInfoCorrect
4258 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4259 // * happen if mesh data is not yet fully loaded from the file of study.
4260 //=======================================================================
4262 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4264 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4267 //=============================================================================
4269 * \brief Returns statistic of mesh elements
4271 //=============================================================================
4273 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4276 return _preMeshInfo->GetMeshInfo();
4278 SMESH::long_array_var aRes = new SMESH::long_array();
4279 aRes->length(SMESH::Entity_Last);
4280 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4282 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4284 return aRes._retn();
4285 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4286 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4287 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4288 return aRes._retn();
4291 //=============================================================================
4293 * \brief Collect statistic of mesh elements given by iterator
4295 //=============================================================================
4297 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4298 SMESH::long_array& theInfo)
4300 if (!theItr) return;
4301 while (theItr->more())
4302 theInfo[ theItr->next()->GetEntityType() ]++;
4305 //=============================================================================
4306 namespace // Finding concurrent hypotheses
4307 //=============================================================================
4311 * \brief mapping of mesh dimension into shape type
4313 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4315 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4317 case 0: aType = TopAbs_VERTEX; break;
4318 case 1: aType = TopAbs_EDGE; break;
4319 case 2: aType = TopAbs_FACE; break;
4321 default:aType = TopAbs_SOLID; break;
4326 //-----------------------------------------------------------------------------
4328 * \brief Internal structure used to find concurent submeshes
4330 * It represents a pair < submesh, concurent dimension >, where
4331 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4332 * with another submesh. In other words, it is dimension of a hypothesis assigned
4339 int _dim; //!< a dimension the algo can build (concurrent dimension)
4340 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4341 TopTools_MapOfShape _shapeMap;
4342 SMESH_subMesh* _subMesh;
4343 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4345 //-----------------------------------------------------------------------------
4346 // Return the algorithm
4347 const SMESH_Algo* GetAlgo() const
4348 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4350 //-----------------------------------------------------------------------------
4352 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4354 const TopoDS_Shape& theShape)
4356 _subMesh = (SMESH_subMesh*)theSubMesh;
4357 SetShape( theDim, theShape );
4360 //-----------------------------------------------------------------------------
4362 void SetShape(const int theDim,
4363 const TopoDS_Shape& theShape)
4366 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4367 if (_dim >= _ownDim)
4368 _shapeMap.Add( theShape );
4370 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4371 for( ; anExp.More(); anExp.Next() )
4372 _shapeMap.Add( anExp.Current() );
4376 //-----------------------------------------------------------------------------
4377 //! Check sharing of sub-shapes
4378 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4379 const TopTools_MapOfShape& theToFind,
4380 const TopAbs_ShapeEnum theType)
4382 bool isShared = false;
4383 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4384 for (; !isShared && anItr.More(); anItr.Next() )
4386 const TopoDS_Shape aSubSh = anItr.Key();
4387 // check for case when concurrent dimensions are same
4388 isShared = theToFind.Contains( aSubSh );
4389 // check for sub-shape with concurrent dimension
4390 TopExp_Explorer anExp( aSubSh, theType );
4391 for ( ; !isShared && anExp.More(); anExp.Next() )
4392 isShared = theToFind.Contains( anExp.Current() );
4397 //-----------------------------------------------------------------------------
4398 //! check algorithms
4399 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4400 const SMESHDS_Hypothesis* theA2)
4402 if ( !theA1 || !theA2 ||
4403 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4404 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4405 return false; // one of the hypothesis is not algorithm
4406 // check algorithm names (should be equal)
4407 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4411 //-----------------------------------------------------------------------------
4412 //! Check if sub-shape hypotheses are concurrent
4413 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4415 if ( _subMesh == theOther->_subMesh )
4416 return false; // same sub-shape - should not be
4418 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4419 // any of the two submeshes is not on COMPOUND shape )
4420 // -> no concurrency
4421 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4422 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4423 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4424 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4425 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4428 // bool checkSubShape = ( _dim >= theOther->_dim )
4429 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4430 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4431 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4432 if ( !checkSubShape )
4435 // check algorithms to be same
4436 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4437 return true; // different algorithms -> concurrency !
4439 // check hypothesises for concurrence (skip first as algorithm)
4441 // pointers should be same, because it is referened from mesh hypothesis partition
4442 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4443 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4444 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4445 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4447 // the submeshes are concurrent if their algorithms has different parameters
4448 return nbSame != theOther->_hypotheses.size() - 1;
4451 // Return true if algorithm of this SMESH_DimHyp is used if no
4452 // sub-mesh order is imposed by the user
4453 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4455 // NeedDiscreteBoundary() algo has a higher priority
4456 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4457 theOther->GetAlgo()->NeedDiscreteBoundary() )
4458 return !this->GetAlgo()->NeedDiscreteBoundary();
4460 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4463 }; // end of SMESH_DimHyp
4464 //-----------------------------------------------------------------------------
4466 typedef list<const SMESH_DimHyp*> TDimHypList;
4468 //-----------------------------------------------------------------------------
4470 void addDimHypInstance(const int theDim,
4471 const TopoDS_Shape& theShape,
4472 const SMESH_Algo* theAlgo,
4473 const SMESH_subMesh* theSubMesh,
4474 const list <const SMESHDS_Hypothesis*>& theHypList,
4475 TDimHypList* theDimHypListArr )
4477 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4478 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4479 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4480 dimHyp->_hypotheses.push_front(theAlgo);
4481 listOfdimHyp.push_back( dimHyp );
4484 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4485 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4486 theHypList.begin(), theHypList.end() );
4489 //-----------------------------------------------------------------------------
4490 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4491 TDimHypList& theListOfConcurr)
4493 if ( theListOfConcurr.empty() )
4495 theListOfConcurr.push_back( theDimHyp );
4499 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4500 while ( hypIt != theListOfConcurr.end() &&
4501 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4503 theListOfConcurr.insert( hypIt, theDimHyp );
4507 //-----------------------------------------------------------------------------
4508 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4509 const TDimHypList& theListOfDimHyp,
4510 TDimHypList& theListOfConcurrHyp,
4511 set<int>& theSetOfConcurrId )
4513 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4514 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4516 const SMESH_DimHyp* curDimHyp = *rIt;
4517 if ( curDimHyp == theDimHyp )
4518 break; // meet own dimHyp pointer in same dimension
4520 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4521 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4523 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4528 //-----------------------------------------------------------------------------
4529 void unionLists(TListOfInt& theListOfId,
4530 TListOfListOfInt& theListOfListOfId,
4533 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4534 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4536 continue; //skip already treated lists
4537 // check if other list has any same submesh object
4538 TListOfInt& otherListOfId = *it;
4539 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4540 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4543 // union two lists (from source into target)
4544 TListOfInt::iterator it2 = otherListOfId.begin();
4545 for ( ; it2 != otherListOfId.end(); it2++ ) {
4546 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4547 theListOfId.push_back(*it2);
4549 // clear source list
4550 otherListOfId.clear();
4553 //-----------------------------------------------------------------------------
4555 //! free memory allocated for dimension-hypothesis objects
4556 void removeDimHyps( TDimHypList* theArrOfList )
4558 for (int i = 0; i < 4; i++ ) {
4559 TDimHypList& listOfdimHyp = theArrOfList[i];
4560 TDimHypList::const_iterator it = listOfdimHyp.begin();
4561 for ( ; it != listOfdimHyp.end(); it++ )
4566 //-----------------------------------------------------------------------------
4568 * \brief find common submeshes with given submesh
4569 * \param theSubMeshList list of already collected submesh to check
4570 * \param theSubMesh given submesh to intersect with other
4571 * \param theCommonSubMeshes collected common submeshes
4573 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4574 const SMESH_subMesh* theSubMesh,
4575 set<const SMESH_subMesh*>& theCommon )
4579 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4580 for ( ; it != theSubMeshList.end(); it++ )
4581 theSubMesh->FindIntersection( *it, theCommon );
4582 theSubMeshList.push_back( theSubMesh );
4583 //theCommon.insert( theSubMesh );
4588 //=============================================================================
4590 * \brief Return submesh objects list in meshing order
4592 //=============================================================================
4594 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4596 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4598 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4600 return aResult._retn();
4602 ::SMESH_Mesh& mesh = GetImpl();
4603 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4604 if ( !anOrder.size() ) {
4606 // collect submeshes and detect concurrent algorithms and hypothesises
4607 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4609 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4610 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4611 ::SMESH_subMesh* sm = (*i_sm).second;
4613 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4615 // list of assigned hypothesises
4616 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4617 // Find out dimensions where the submesh can be concurrent.
4618 // We define the dimensions by algo of each of hypotheses in hypList
4619 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4620 for( ; hypIt != hypList.end(); hypIt++ ) {
4621 SMESH_Algo* anAlgo = 0;
4622 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4623 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4624 // hyp it-self is algo
4625 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4627 // try to find algorithm with help of sub-shapes
4628 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4629 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4630 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4633 continue; // no algorithm assigned to a current submesh
4635 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4636 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4638 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4639 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4640 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4642 } // end iterations on submesh
4644 // iterate on created dimension-hypotheses and check for concurrents
4645 for ( int i = 0; i < 4; i++ ) {
4646 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4647 // check for concurrents in own and other dimensions (step-by-step)
4648 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4649 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4650 const SMESH_DimHyp* dimHyp = *dhIt;
4651 TDimHypList listOfConcurr;
4652 set<int> setOfConcurrIds;
4653 // looking for concurrents and collect into own list
4654 for ( int j = i; j < 4; j++ )
4655 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4656 // check if any concurrents found
4657 if ( listOfConcurr.size() > 0 ) {
4658 // add own submesh to list of concurrent
4659 addInOrderOfPriority( dimHyp, listOfConcurr );
4660 list<int> listOfConcurrIds;
4661 TDimHypList::iterator hypIt = listOfConcurr.begin();
4662 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4663 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4664 anOrder.push_back( listOfConcurrIds );
4669 removeDimHyps(dimHypListArr);
4671 // now, minimise the number of concurrent groups
4672 // Here we assume that lists of submeshes can have same submesh
4673 // in case of multi-dimension algorithms, as result
4674 // list with common submesh has to be united into one list
4676 TListOfListOfInt::iterator listIt = anOrder.begin();
4677 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4678 unionLists( *listIt, anOrder, listIndx + 1 );
4680 // convert submesh ids into interface instances
4681 // and dump command into python
4682 convertMeshOrder( anOrder, aResult, false );
4684 return aResult._retn();
4687 //=============================================================================
4689 * \brief Set submesh object order
4690 * \param theSubMeshArray submesh array order
4692 //=============================================================================
4694 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4697 _preMeshInfo->ForgetOrLoad();
4700 ::SMESH_Mesh& mesh = GetImpl();
4702 TPythonDump aPythonDump; // prevent dump of called methods
4703 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4705 TListOfListOfInt subMeshOrder;
4706 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4708 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4709 TListOfInt subMeshIds;
4710 aPythonDump << "[ ";
4711 // Collect subMeshes which should be clear
4712 // do it list-by-list, because modification of submesh order
4713 // take effect between concurrent submeshes only
4714 set<const SMESH_subMesh*> subMeshToClear;
4715 list<const SMESH_subMesh*> subMeshList;
4716 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4718 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4720 aPythonDump << ", ";
4721 aPythonDump << subMesh;
4722 subMeshIds.push_back( subMesh->GetId() );
4723 // detect common parts of submeshes
4724 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4725 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4727 aPythonDump << " ]";
4728 subMeshOrder.push_back( subMeshIds );
4730 // clear collected submeshes
4731 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4732 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4733 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4734 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4736 aPythonDump << " ])";
4738 mesh.SetMeshOrder( subMeshOrder );
4744 //=============================================================================
4746 * \brief Convert submesh ids into submesh interfaces
4748 //=============================================================================
4750 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4751 SMESH::submesh_array_array& theResOrder,
4752 const bool theIsDump)
4754 int nbSet = theIdsOrder.size();
4755 TPythonDump aPythonDump; // prevent dump of called methods
4757 aPythonDump << "[ ";
4758 theResOrder.length(nbSet);
4759 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4761 for( ; it != theIdsOrder.end(); it++ ) {
4762 // translate submesh identificators into submesh objects
4763 // takeing into account real number of concurrent lists
4764 const TListOfInt& aSubOrder = (*it);
4765 if (!aSubOrder.size())
4768 aPythonDump << "[ ";
4769 // convert shape indeces into interfaces
4770 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4771 aResSubSet->length(aSubOrder.size());
4772 TListOfInt::const_iterator subIt = aSubOrder.begin();
4773 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4774 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4776 SMESH::SMESH_subMesh_var subMesh =
4777 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4780 aPythonDump << ", ";
4781 aPythonDump << subMesh;
4783 aResSubSet[ j++ ] = subMesh;
4786 aPythonDump << " ]";
4787 theResOrder[ listIndx++ ] = aResSubSet;
4789 // correct number of lists
4790 theResOrder.length( listIndx );
4793 // finilise python dump
4794 aPythonDump << " ]";
4795 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4799 //================================================================================
4801 // Implementation of SMESH_MeshPartDS
4803 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4804 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4806 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4807 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4809 _meshDS = mesh_i->GetImpl().GetMeshDS();
4811 SetPersistentId( _meshDS->GetPersistentId() );
4813 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4815 // <meshPart> is the whole mesh
4816 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4818 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4819 myGroupSet = _meshDS->GetGroups();
4824 SMESH::long_array_var anIDs = meshPart->GetIDs();
4825 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4826 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4828 for (int i=0; i < anIDs->length(); i++)
4829 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4830 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4835 for (int i=0; i < anIDs->length(); i++)
4836 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4837 if ( _elements[ e->GetType() ].insert( e ).second )
4840 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4841 while ( nIt->more() )
4843 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4844 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4851 _meshDS = 0; // to enforce iteration on _elements and _nodes
4854 // -------------------------------------------------------------------------------------
4855 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
4856 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
4859 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
4860 for ( ; partIt != meshPart.end(); ++partIt )
4861 if ( const SMDS_MeshElement * e = *partIt )
4862 if ( _elements[ e->GetType() ].insert( e ).second )
4865 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4866 while ( nIt->more() )
4868 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4869 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4875 // -------------------------------------------------------------------------------------
4876 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
4878 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
4880 typedef SMDS_SetIterator
4881 <const SMDS_MeshElement*,
4882 TIDSortedElemSet::const_iterator,
4883 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4884 SMDS_MeshElement::GeomFilter
4887 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
4889 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4890 _elements[type].end(),
4891 SMDS_MeshElement::GeomFilter( geomType )));
4893 // -------------------------------------------------------------------------------------
4894 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
4896 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
4898 typedef SMDS_SetIterator
4899 <const SMDS_MeshElement*,
4900 TIDSortedElemSet::const_iterator,
4901 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4902 SMDS_MeshElement::EntityFilter
4905 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
4907 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4908 _elements[type].end(),
4909 SMDS_MeshElement::EntityFilter( entity )));
4911 // -------------------------------------------------------------------------------------
4912 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4914 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4915 if ( type == SMDSAbs_All && !_meshDS )
4917 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4919 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4920 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4922 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4924 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4925 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4927 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4928 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4930 // -------------------------------------------------------------------------------------
4931 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4932 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4934 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4935 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4936 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4938 // -------------------------------------------------------------------------------------
4939 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4940 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4941 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4942 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4943 #undef _GET_ITER_DEFINE
4945 // END Implementation of SMESH_MeshPartDS
4947 //================================================================================