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_SetIterator.hxx"
35 #include "SMDS_VolumeTool.hxx"
36 #include "SMESHDS_Command.hxx"
37 #include "SMESHDS_CommandType.hxx"
38 #include "SMESHDS_GroupOnGeom.hxx"
39 #include "SMESH_Filter_i.hxx"
40 #include "SMESH_Gen_i.hxx"
41 #include "SMESH_Group.hxx"
42 #include "SMESH_Group_i.hxx"
43 #include "SMESH_MEDMesh_i.hxx"
44 #include "SMESH_MeshEditor.hxx"
45 #include "SMESH_MeshEditor_i.hxx"
46 #include "SMESH_MeshPartDS.hxx"
47 #include "SMESH_MesherHelper.hxx"
48 #include "SMESH_PreMeshInfo.hxx"
49 #include "SMESH_PythonDump.hxx"
50 #include "SMESH_subMesh_i.hxx"
53 #include <SALOMEDS_Attributes_wrap.hxx>
54 #include <SALOMEDS_wrap.hxx>
55 #include <SALOME_NamingService.hxx>
56 #include <Utils_CorbaException.hxx>
57 #include <Utils_ExceptHandlers.hxx>
58 #include <Utils_SINGLETON.hxx>
59 #include <utilities.h>
61 #include <GEOMImpl_Types.hxx>
62 #include <GEOM_GenericObjPtr.h>
65 #include <BRep_Builder.hxx>
66 #include <OSD_Directory.hxx>
67 #include <OSD_File.hxx>
68 #include <OSD_Path.hxx>
69 #include <OSD_Protection.hxx>
70 #include <Standard_OutOfMemory.hxx>
71 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
72 #include <TColStd_MapOfInteger.hxx>
73 #include <TColStd_SequenceOfInteger.hxx>
74 #include <TCollection_AsciiString.hxx>
76 #include <TopExp_Explorer.hxx>
77 #include <TopTools_MapIteratorOfMapOfShape.hxx>
78 #include <TopTools_MapOfShape.hxx>
79 #include <TopoDS_Compound.hxx>
89 static int MYDEBUG = 0;
91 static int MYDEBUG = 0;
95 using SMESH::TPythonDump;
97 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
119 //=============================================================================
123 //=============================================================================
125 SMESH_Mesh_i::~SMESH_Mesh_i()
127 MESSAGE("~SMESH_Mesh_i");
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 // _impl->RemoveGroup() is called by ~SMESH_GroupBase_i() (PAL6331)
135 //_impl->RemoveGroup( aGroup->GetLocalID() );
136 aGroup->myMeshServant = 0;
137 aGroup->UnRegister();
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
148 _mapSubMeshIor.clear();
150 // destroy hypotheses
151 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
152 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ )
153 if ( SMESH_Hypothesis_i* aHypo = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
159 delete _impl; _impl = NULL;
160 delete _preMeshInfo; _preMeshInfo = NULL;
163 //=============================================================================
167 * Associates <this> mesh with <theShape> and puts a reference
168 * to <theShape> into the current study;
169 * the previous shape is substituted by the new one.
171 //=============================================================================
173 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
174 throw (SALOME::SALOME_Exception)
176 Unexpect aCatch(SALOME_SalomeException);
178 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
180 catch(SALOME_Exception & S_ex) {
181 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
183 // to track changes of GEOM groups
184 addGeomGroupData( theShapeObject, _this() );
187 //================================================================================
189 * \brief return true if mesh has a shape to build a shape on
191 //================================================================================
193 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
194 throw (SALOME::SALOME_Exception)
196 Unexpect aCatch(SALOME_SalomeException);
199 res = _impl->HasShapeToMesh();
201 catch(SALOME_Exception & S_ex) {
202 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
207 //=======================================================================
208 //function : GetShapeToMesh
210 //=======================================================================
212 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
213 throw (SALOME::SALOME_Exception)
215 Unexpect aCatch(SALOME_SalomeException);
216 GEOM::GEOM_Object_var aShapeObj;
218 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
220 aShapeObj = _gen_i->ShapeToGeomObject( S );
222 catch(SALOME_Exception & S_ex) {
223 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
225 return aShapeObj._retn();
228 //================================================================================
230 * \brief Return false if the mesh is not yet fully loaded from the study file
232 //================================================================================
234 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
236 Unexpect aCatch(SALOME_SalomeException);
237 return !_preMeshInfo;
240 //================================================================================
242 * \brief Load full mesh data from the study file
244 //================================================================================
246 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
248 Unexpect aCatch(SALOME_SalomeException);
250 _preMeshInfo->FullLoadFromFile();
253 //================================================================================
255 * \brief Remove all nodes and elements
257 //================================================================================
259 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
261 Unexpect aCatch(SALOME_SalomeException);
263 _preMeshInfo->ForgetAllData();
267 CheckGeomGroupModif(); // issue 20145
269 catch(SALOME_Exception & S_ex) {
270 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
272 _impl->GetMeshDS()->Modified();
274 TPythonDump() << _this() << ".Clear()";
277 //================================================================================
279 * \brief Remove all nodes and elements for indicated shape
281 //================================================================================
283 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
284 throw (SALOME::SALOME_Exception)
286 Unexpect aCatch(SALOME_SalomeException);
288 _preMeshInfo->FullLoadFromFile();
291 _impl->ClearSubMesh( ShapeID );
293 catch(SALOME_Exception & S_ex) {
294 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
296 _impl->GetMeshDS()->Modified();
298 TPythonDump() << _this() << ".ClearSubMesh( " << ShapeID << " )";
301 //=============================================================================
303 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
305 //=============================================================================
307 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
309 SMESH::DriverMED_ReadStatus res;
312 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
313 res = SMESH::DRS_OK; break;
314 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
315 res = SMESH::DRS_EMPTY; break;
316 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
317 res = SMESH::DRS_WARN_RENUMBER; break;
318 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
319 res = SMESH::DRS_WARN_SKIP_ELEM; break;
320 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
322 res = SMESH::DRS_FAIL; break;
327 //=============================================================================
329 * Convert ::SMESH_ComputeError to SMESH::ComputeError
331 //=============================================================================
333 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
335 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
336 errVar->subShapeID = -1;
337 errVar->hasBadMesh = false;
339 if ( !errorPtr || errorPtr->IsOK() )
341 errVar->code = SMESH::COMPERR_OK;
345 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
346 errVar->comment = errorPtr->myComment.c_str();
348 return errVar._retn();
351 //=============================================================================
355 * Imports mesh data from MED file
357 //=============================================================================
359 SMESH::DriverMED_ReadStatus
360 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
361 throw ( SALOME::SALOME_Exception )
363 Unexpect aCatch(SALOME_SalomeException);
366 status = _impl->MEDToMesh( theFileName, theMeshName );
368 catch( SALOME_Exception& S_ex ) {
369 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
372 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
375 CreateGroupServants();
377 int major, minor, release;
378 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
379 major = minor = release = -1;
380 _medFileInfo = new SALOME_MED::MedFileInfo();
381 _medFileInfo->fileName = theFileName;
382 _medFileInfo->fileSize = 0;
385 if ( ::_stati64( theFileName, &d ) != -1 )
388 if ( ::stat64( theFileName, &d ) != -1 )
390 _medFileInfo->fileSize = d.st_size;
391 _medFileInfo->major = major;
392 _medFileInfo->minor = minor;
393 _medFileInfo->release = release;
395 return ConvertDriverMEDReadStatus(status);
398 //================================================================================
400 * \brief Imports mesh data from the CGNS file
402 //================================================================================
404 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
405 const int theMeshIndex,
406 std::string& theMeshName )
407 throw ( SALOME::SALOME_Exception )
409 Unexpect aCatch(SALOME_SalomeException);
412 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
414 catch( SALOME_Exception& S_ex ) {
415 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
418 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
421 CreateGroupServants();
423 return ConvertDriverMEDReadStatus(status);
426 //================================================================================
428 * \brief Return string representation of a MED file version comprising nbDigits
430 //================================================================================
432 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
434 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
436 return CORBA::string_dup( ver.c_str() );
439 //=============================================================================
443 * Imports mesh data from MED file
445 //=============================================================================
447 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
448 throw ( SALOME::SALOME_Exception )
450 // Read mesh with name = <theMeshName> into SMESH_Mesh
451 _impl->UNVToMesh( theFileName );
453 CreateGroupServants();
458 //=============================================================================
462 * Imports mesh data from STL file
464 //=============================================================================
465 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
466 throw ( SALOME::SALOME_Exception )
468 // Read mesh with name = <theMeshName> into SMESH_Mesh
469 _impl->STLToMesh( theFileName );
474 //================================================================================
476 * \brief Imports data from a GMF file and returns an error description
478 //================================================================================
480 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
481 bool theMakeRequiredGroups )
482 throw (SALOME::SALOME_Exception)
484 SMESH_ComputeErrorPtr error;
486 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
488 catch ( std::bad_alloc& exc ) {
489 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "std::bad_alloc raised" );
491 catch ( Standard_OutOfMemory& exc ) {
492 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Standard_OutOfMemory raised" );
494 catch (Standard_Failure& ex) {
495 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, ex.DynamicType()->Name() );
496 if ( ex.GetMessageString() && strlen( ex.GetMessageString() ))
497 error->myComment += string(": ") + ex.GetMessageString();
499 catch ( SALOME_Exception& S_ex ) {
500 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, S_ex.what() );
502 catch ( std::exception& exc ) {
503 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, exc.what() );
506 error = SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, "Unknown exception" );
509 CreateGroupServants();
511 return ConvertComputeError( error );
514 //=============================================================================
518 //=============================================================================
520 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
522 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
523 (SMESH_Hypothesis::Hypothesis_Status theStatus)
526 RETURNCASE( HYP_OK );
527 RETURNCASE( HYP_MISSING );
528 RETURNCASE( HYP_CONCURENT );
529 RETURNCASE( HYP_BAD_PARAMETER );
530 RETURNCASE( HYP_HIDDEN_ALGO );
531 RETURNCASE( HYP_HIDING_ALGO );
532 RETURNCASE( HYP_UNKNOWN_FATAL );
533 RETURNCASE( HYP_INCOMPATIBLE );
534 RETURNCASE( HYP_NOTCONFORM );
535 RETURNCASE( HYP_ALREADY_EXIST );
536 RETURNCASE( HYP_BAD_DIM );
537 RETURNCASE( HYP_BAD_SUBSHAPE );
538 RETURNCASE( HYP_BAD_GEOMETRY );
539 RETURNCASE( HYP_NEED_SHAPE );
542 return SMESH::HYP_UNKNOWN_FATAL;
545 //=============================================================================
549 * calls internal addHypothesis() and then adds a reference to <anHyp> under
550 * the SObject actually having a reference to <aSubShape>.
551 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
553 //=============================================================================
555 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
556 SMESH::SMESH_Hypothesis_ptr anHyp)
557 throw(SALOME::SALOME_Exception)
559 Unexpect aCatch(SALOME_SalomeException);
561 _preMeshInfo->ForgetOrLoad();
563 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
565 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
566 _gen_i->AddHypothesisToShape(_gen_i->GetCurrentStudy(), _this(),
567 aSubShapeObject, anHyp );
569 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
571 // Update Python script
572 if(_impl->HasShapeToMesh()) {
573 TPythonDump() << "status = " << _this() << ".AddHypothesis( "
574 << aSubShapeObject << ", " << anHyp << " )";
577 TPythonDump() << "status = " << _this() << ".AddHypothesis( "<< anHyp << " )";
580 return ConvertHypothesisStatus(status);
583 //=============================================================================
587 //=============================================================================
589 SMESH_Hypothesis::Hypothesis_Status
590 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
591 SMESH::SMESH_Hypothesis_ptr anHyp)
593 if(MYDEBUG) MESSAGE("addHypothesis");
595 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
596 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
599 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
600 if (CORBA::is_nil(myHyp))
601 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",
604 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
607 TopoDS_Shape myLocSubShape;
608 //use PseudoShape in case if mesh has no shape
610 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
612 myLocSubShape = _impl->GetShapeToMesh();
614 int hypId = myHyp->GetId();
615 status = _impl->AddHypothesis(myLocSubShape, hypId);
616 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
617 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( myHyp );
618 _mapHypo[hypId]->Register();
619 // assure there is a corresponding submesh
620 if ( !_impl->IsMainShape( myLocSubShape )) {
621 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
622 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
623 createSubMesh( aSubShapeObject );
627 catch(SALOME_Exception & S_ex)
629 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
634 //=============================================================================
638 //=============================================================================
640 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
641 SMESH::SMESH_Hypothesis_ptr anHyp)
642 throw(SALOME::SALOME_Exception)
644 Unexpect aCatch(SALOME_SalomeException);
646 _preMeshInfo->ForgetOrLoad();
648 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
650 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
651 _gen_i->RemoveHypothesisFromShape(_gen_i->GetCurrentStudy(), _this(),
652 aSubShapeObject, anHyp );
654 // Update Python script
655 // Update Python script
656 if(_impl->HasShapeToMesh()) {
657 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
658 << aSubShapeObject << ", " << anHyp << " )";
661 TPythonDump() << "status = " << _this() << ".RemoveHypothesis( "
665 return ConvertHypothesisStatus(status);
668 //=============================================================================
672 //=============================================================================
674 SMESH_Hypothesis::Hypothesis_Status
675 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
676 SMESH::SMESH_Hypothesis_ptr anHyp)
678 if(MYDEBUG) MESSAGE("removeHypothesis()");
679 // **** proposer liste de sub-shape (selection multiple)
681 if (CORBA::is_nil(aSubShapeObject) && HasShapeToMesh())
682 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
684 SMESH::SMESH_Hypothesis_var myHyp = SMESH::SMESH_Hypothesis::_narrow(anHyp);
685 if (CORBA::is_nil(myHyp))
686 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
688 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
691 TopoDS_Shape myLocSubShape;
692 //use PseudoShape in case if mesh has no shape
694 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
696 myLocSubShape = _impl->GetShapeToMesh();
698 int hypId = myHyp->GetId();
699 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
700 // if ( !SMESH_Hypothesis::IsStatusFatal(status) ) EAP: hyp can be used on many sub-shapes
701 // _mapHypo.erase( hypId );
703 catch(SALOME_Exception & S_ex)
705 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
710 //=============================================================================
714 //=============================================================================
716 SMESH::ListOfHypothesis *
717 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
718 throw(SALOME::SALOME_Exception)
720 Unexpect aCatch(SALOME_SalomeException);
721 if (MYDEBUG) MESSAGE("GetHypothesisList");
722 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
723 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
725 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
728 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
729 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
730 myLocSubShape = _impl->GetShapeToMesh();
731 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
732 int i = 0, n = aLocalList.size();
735 for ( list<const SMESHDS_Hypothesis*>::const_iterator anIt = aLocalList.begin(); i < n && anIt != aLocalList.end(); anIt++ ) {
736 SMESHDS_Hypothesis* aHyp = (SMESHDS_Hypothesis*)(*anIt);
737 if ( _mapHypo.find( aHyp->GetID() ) != _mapHypo.end() )
738 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( _mapHypo[aHyp->GetID()] );
743 catch(SALOME_Exception & S_ex) {
744 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
747 return aList._retn();
750 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
752 Unexpect aCatch(SALOME_SalomeException);
753 if (MYDEBUG) MESSAGE("GetSubMeshes");
755 SMESH::submesh_array_var aList = new SMESH::submesh_array();
758 TPythonDump aPythonDump;
759 if ( !_mapSubMeshIor.empty() )
763 aList->length( _mapSubMeshIor.size() );
765 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
766 for ( ; it != _mapSubMeshIor.end(); it++ ) {
767 if ( CORBA::is_nil( it->second )) continue;
768 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
770 if (i > 1) aPythonDump << ", ";
771 aPythonDump << it->second;
775 catch(SALOME_Exception & S_ex) {
776 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
779 // Update Python script
780 if ( !_mapSubMeshIor.empty() )
781 aPythonDump << " ] = " << _this() << ".GetSubMeshes()";
783 return aList._retn();
786 //=============================================================================
790 //=============================================================================
791 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
792 const char* theName )
793 throw(SALOME::SALOME_Exception)
795 Unexpect aCatch(SALOME_SalomeException);
796 MESSAGE("SMESH_Mesh_i::GetSubMesh");
797 if (CORBA::is_nil(aSubShapeObject))
798 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",
801 SMESH::SMESH_subMesh_var subMesh;
802 SMESH::SMESH_Mesh_var aMesh = SMESH::SMESH_Mesh::_narrow(_this());
804 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
806 //Get or Create the SMESH_subMesh object implementation
808 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
810 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
812 TopoDS_Iterator it( myLocSubShape );
814 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
816 subMesh = getSubMesh( subMeshId );
818 // create a new subMesh object servant if there is none for the shape
819 if ( subMesh->_is_nil() )
820 subMesh = createSubMesh( aSubShapeObject );
821 if ( _gen_i->CanPublishInStudy( subMesh )) {
822 SALOMEDS::SObject_wrap aSO =
823 _gen_i->PublishSubMesh(_gen_i->GetCurrentStudy(), aMesh,
824 subMesh, aSubShapeObject, theName );
825 if ( !aSO->_is_nil()) {
826 // Update Python script
827 TPythonDump() << aSO << " = " << _this() << ".GetSubMesh( "
828 << aSubShapeObject << ", '" << theName << "' )";
832 catch(SALOME_Exception & S_ex) {
833 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
835 return subMesh._retn();
838 //=============================================================================
842 //=============================================================================
844 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
845 throw (SALOME::SALOME_Exception)
847 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::RemoveSubMesh");
848 if ( theSubMesh->_is_nil() )
851 GEOM::GEOM_Object_var aSubShapeObject;
852 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
853 if ( !aStudy->_is_nil() ) {
854 // Remove submesh's SObject
855 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
856 if ( !anSO->_is_nil() ) {
857 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
858 SALOMEDS::SObject_wrap anObj, aRef;
859 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
860 anObj->ReferencedObject( aRef.inout() ))
862 CORBA::Object_var obj = aRef->GetObject();
863 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
865 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
866 // aSubShapeObject = theSubMesh->GetSubShape();
868 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
869 builder->RemoveObjectWithChildren( anSO );
871 // Update Python script
872 TPythonDump() << _this() << ".RemoveSubMesh( " << anSO << " )";
876 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
878 _preMeshInfo->ForgetOrLoad();
881 //=============================================================================
885 //=============================================================================
887 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
888 const char* theName )
889 throw(SALOME::SALOME_Exception)
891 Unexpect aCatch(SALOME_SalomeException);
893 _preMeshInfo->FullLoadFromFile();
895 SMESH::SMESH_Group_var aNewGroup =
896 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
898 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
899 SALOMEDS::SObject_wrap aSO =
900 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
901 aNewGroup, GEOM::GEOM_Object::_nil(), theName);
902 if ( !aSO->_is_nil()) {
903 // Update Python script
904 TPythonDump() << aSO << " = " << _this() << ".CreateGroup( "
905 << theElemType << ", '" << theName << "' )";
908 return aNewGroup._retn();
912 //=============================================================================
916 //=============================================================================
917 SMESH::SMESH_GroupOnGeom_ptr
918 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
920 GEOM::GEOM_Object_ptr theGeomObj)
921 throw(SALOME::SALOME_Exception)
923 Unexpect aCatch(SALOME_SalomeException);
925 _preMeshInfo->FullLoadFromFile();
927 SMESH::SMESH_GroupOnGeom_var aNewGroup;
929 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
930 if ( !aShape.IsNull() )
932 aNewGroup = SMESH::SMESH_GroupOnGeom::_narrow
933 ( createGroup( theElemType, theName, aShape ));
935 if ( _gen_i->CanPublishInStudy( aNewGroup ) ) {
936 SALOMEDS::SObject_wrap aSO =
937 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(),
938 aNewGroup, theGeomObj, theName);
939 if ( !aSO->_is_nil()) {
940 // Update Python script
941 TPythonDump() << aSO << " = " << _this() << ".CreateGroupFromGEOM("
942 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
947 return aNewGroup._retn();
950 //================================================================================
952 * \brief Creates a group whose contents is defined by filter
953 * \param theElemType - group type
954 * \param theName - group name
955 * \param theFilter - the filter
956 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
958 //================================================================================
960 SMESH::SMESH_GroupOnFilter_ptr
961 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
963 SMESH::Filter_ptr theFilter )
964 throw (SALOME::SALOME_Exception)
966 Unexpect aCatch(SALOME_SalomeException);
968 _preMeshInfo->FullLoadFromFile();
970 if ( CORBA::is_nil( theFilter ))
971 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
973 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
975 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
977 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
978 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
981 if ( !aNewGroup->_is_nil() )
982 aNewGroup->SetFilter( theFilter );
984 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
986 SALOMEDS::SObject_wrap aSO =
987 _gen_i->PublishGroup(_gen_i->GetCurrentStudy(), _this(), aNewGroup,
988 GEOM::GEOM_Object::_nil(), theName);
989 if ( !aSO->_is_nil()) {
990 // Update Python script
991 pd << aSO << " = " << _this() << ".CreateGroupFromFilter("
992 << theElemType << ", '" << theName << "', " << theFilter << " )";
996 return aNewGroup._retn();
999 //=============================================================================
1003 //=============================================================================
1005 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1006 throw (SALOME::SALOME_Exception)
1008 if ( theGroup->_is_nil() )
1011 SMESH_GroupBase_i* aGroup =
1012 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1016 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1017 if ( !aStudy->_is_nil() ) {
1018 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1020 if ( !aGroupSO->_is_nil() ) {
1021 // Update Python script
1022 TPythonDump() << _this() << ".RemoveGroup( " << aGroupSO << " )";
1024 // Remove group's SObject
1025 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1026 builder->RemoveObjectWithChildren( aGroupSO );
1030 // Remove the group from SMESH data structures
1031 removeGroup( aGroup->GetLocalID() );
1034 //=============================================================================
1036 * Remove group with its contents
1038 //=============================================================================
1040 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1041 throw (SALOME::SALOME_Exception)
1044 _preMeshInfo->FullLoadFromFile();
1046 if ( theGroup->_is_nil() )
1049 SMESH_GroupBase_i* aGroup =
1050 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
1054 SMESH::long_array_var anIds = aGroup->GetListOfID();
1055 SMESH::SMESH_MeshEditor_var aMeshEditor = SMESH_Mesh_i::GetMeshEditor();
1057 TPythonDump pyDump; // Supress dump from RemoveNodes/Elements() and RemoveGroup()
1060 if ( aGroup->GetType() == SMESH::NODE )
1061 aMeshEditor->RemoveNodes( anIds );
1063 aMeshEditor->RemoveElements( anIds );
1065 // Update Python script (theGroup must be alive for this)
1066 pyDump << _this() << ".RemoveGroupWithContents( " << theGroup << " )";
1069 RemoveGroup( theGroup );
1072 //================================================================================
1074 * \brief Get the list of groups existing in the mesh
1075 * \retval SMESH::ListOfGroups * - list of groups
1077 //================================================================================
1079 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1081 Unexpect aCatch(SALOME_SalomeException);
1082 if (MYDEBUG) MESSAGE("GetGroups");
1084 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1087 TPythonDump aPythonDump;
1088 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1089 aPythonDump << "[ ";
1092 aList->length( _mapGroups.size() );
1094 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1095 for ( ; it != _mapGroups.end(); it++ ) {
1096 if ( CORBA::is_nil( it->second )) continue;
1097 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1099 if (i > 1) aPythonDump << ", ";
1100 aPythonDump << it->second;
1104 catch(SALOME_Exception & S_ex) {
1105 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1108 // Update Python script
1109 if ( !_mapGroups.empty() ) // (IMP13463) avoid "SyntaxError: can't assign to []"
1110 aPythonDump << " ] = " << _this() << ".GetGroups()";
1112 return aList._retn();
1115 //=============================================================================
1117 * Get number of groups existing in the mesh
1119 //=============================================================================
1121 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1123 Unexpect aCatch(SALOME_SalomeException);
1124 return _mapGroups.size();
1127 //=============================================================================
1129 * New group is created. All mesh elements that are
1130 * present in initial groups are added to the new one
1132 //=============================================================================
1133 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1134 SMESH::SMESH_GroupBase_ptr theGroup2,
1135 const char* theName )
1136 throw (SALOME::SALOME_Exception)
1139 _preMeshInfo->FullLoadFromFile();
1143 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1144 theGroup1->GetType() != theGroup2->GetType() )
1145 return SMESH::SMESH_Group::_nil();
1150 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1151 if ( aResGrp->_is_nil() )
1152 return SMESH::SMESH_Group::_nil();
1154 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1155 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1157 TColStd_MapOfInteger aResMap;
1159 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1160 aResMap.Add( anIds1[ i1 ] );
1162 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1163 aResMap.Add( anIds2[ i2 ] );
1165 SMESH::long_array_var aResIds = new SMESH::long_array;
1166 aResIds->length( aResMap.Extent() );
1169 TColStd_MapIteratorOfMapOfInteger anIter( aResMap );
1170 for( ; anIter.More(); anIter.Next() )
1171 aResIds[ resI++ ] = anIter.Key();
1173 aResGrp->Add( aResIds );
1175 // Update Python script
1176 pyDump << aResGrp << " = " << _this() << ".UnionGroups( "
1177 << theGroup1 << ", " << theGroup2 << ", '"
1178 << theName << "' )";
1180 return aResGrp._retn();
1184 return SMESH::SMESH_Group::_nil();
1188 //=============================================================================
1190 \brief Union list of groups. New group is created. All mesh elements that are
1191 present in initial groups are added to the new one.
1192 \param theGroups list of groups
1193 \param theName name of group to be created
1194 \return pointer on the group
1196 //=============================================================================
1197 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1198 const char* theName )
1199 throw (SALOME::SALOME_Exception)
1202 _preMeshInfo->FullLoadFromFile();
1205 return SMESH::SMESH_Group::_nil();
1209 vector< int > anIds;
1210 SMESH::ElementType aType = SMESH::ALL;
1211 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1213 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1214 if ( CORBA::is_nil( aGrp ) )
1218 SMESH::ElementType aCurrType = aGrp->GetType();
1219 if ( aType == SMESH::ALL )
1223 if ( aType != aCurrType )
1224 return SMESH::SMESH_Group::_nil();
1228 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1229 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1231 int aCurrId = aCurrIds[ i ];
1232 anIds.push_back( aCurrId );
1239 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1240 if ( aResGrp->_is_nil() )
1241 return SMESH::SMESH_Group::_nil();
1243 // Create array of identifiers
1244 SMESH::long_array_var aResIds = new SMESH::long_array;
1245 aResIds->length( anIds.size() );
1247 for ( size_t i = 0; i<anIds.size(); i++ )
1248 aResIds[ i ] = anIds[i];
1249 aResGrp->Add( aResIds );
1251 // Update Python script
1252 pyDump << aResGrp << " = " << _this() << ".UnionListOfGroups( "
1253 << &theGroups << ", '" << theName << "' )";
1255 return aResGrp._retn();
1259 return SMESH::SMESH_Group::_nil();
1263 //=============================================================================
1265 * New group is created. All mesh elements that are
1266 * present in both initial groups are added to the new one.
1268 //=============================================================================
1269 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1270 SMESH::SMESH_GroupBase_ptr theGroup2,
1271 const char* theName )
1272 throw (SALOME::SALOME_Exception)
1275 _preMeshInfo->FullLoadFromFile();
1277 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1278 theGroup1->GetType() != theGroup2->GetType() )
1279 return SMESH::SMESH_Group::_nil();
1283 // Create Intersection
1284 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1285 if ( aResGrp->_is_nil() )
1288 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1289 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1291 TColStd_MapOfInteger aMap1;
1293 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1294 aMap1.Add( anIds1[ i1 ] );
1296 TColStd_SequenceOfInteger aSeq;
1297 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1298 if ( aMap1.Contains( anIds2[ i2 ] ) )
1299 aSeq.Append( anIds2[ i2 ] );
1301 SMESH::long_array_var aResIds = new SMESH::long_array;
1302 aResIds->length( aSeq.Length() );
1303 for ( size_t resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1304 aResIds[ resI ] = aSeq( resI + 1 );
1305 aResGrp->Add( aResIds );
1307 // Update Python script
1308 pyDump << aResGrp << " = " << _this() << ".IntersectGroups( "
1309 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1311 return aResGrp._retn();
1314 //=============================================================================
1316 \brief Intersect list of groups. New group is created. All mesh elements that
1317 are present in all initial groups simultaneously are added to the new one.
1318 \param theGroups list of groups
1319 \param theName name of group to be created
1320 \return pointer on the group
1322 //=============================================================================
1323 SMESH::SMESH_Group_ptr
1324 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1325 const char* theName )
1326 throw (SALOME::SALOME_Exception)
1329 _preMeshInfo->FullLoadFromFile();
1332 return SMESH::SMESH_Group::_nil();
1336 NCollection_DataMap< int, int > anIdToCount;
1337 SMESH::ElementType aType = SMESH::ALL;
1338 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1340 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1341 if ( CORBA::is_nil( aGrp ) )
1345 SMESH::ElementType aCurrType = aGrp->GetType();
1346 if ( aType == SMESH::ALL )
1350 if ( aType != aCurrType )
1351 return SMESH::SMESH_Group::_nil();
1354 // calculates number of occurance ids in groups
1355 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1356 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1358 int aCurrId = aCurrIds[ i ];
1359 if ( !anIdToCount.IsBound( aCurrId ) )
1360 anIdToCount.Bind( aCurrId, 1 );
1362 anIdToCount( aCurrId ) = anIdToCount( aCurrId ) + 1;
1366 // create map of ids
1367 int nbGrp = theGroups.length();
1368 vector< int > anIds;
1369 NCollection_DataMap< int, int >::Iterator anIter( anIdToCount );
1370 for ( ; anIter.More(); anIter.Next() )
1372 int aCurrId = anIter.Key();
1373 int aCurrNb = anIter.Value();
1374 if ( aCurrNb == nbGrp )
1375 anIds.push_back( aCurrId );
1381 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1382 if ( aResGrp->_is_nil() )
1383 return SMESH::SMESH_Group::_nil();
1385 // Create array of identifiers
1386 SMESH::long_array_var aResIds = new SMESH::long_array;
1387 aResIds->length( anIds.size() );
1389 for ( size_t i = 0; i<anIds.size(); i++ )
1390 aResIds[ i ] = anIds[i];
1391 aResGrp->Add( aResIds );
1393 // Update Python script
1394 pyDump << aResGrp << " = " << _this() << ".IntersectListOfGroups( "
1395 << &theGroups << ", '" << theName << "' )";
1397 return aResGrp._retn();
1401 return SMESH::SMESH_Group::_nil();
1405 //=============================================================================
1407 * New group is created. All mesh elements that are present in
1408 * main group but do not present in tool group are added to the new one
1410 //=============================================================================
1411 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1412 SMESH::SMESH_GroupBase_ptr theGroup2,
1413 const char* theName )
1414 throw (SALOME::SALOME_Exception)
1417 _preMeshInfo->FullLoadFromFile();
1419 if ( theGroup1->_is_nil() || theGroup2->_is_nil() ||
1420 theGroup1->GetType() != theGroup2->GetType() )
1421 return SMESH::SMESH_Group::_nil();
1426 SMESH::SMESH_Group_var aResGrp = CreateGroup( theGroup1->GetType(), theName );
1427 if ( aResGrp->_is_nil() )
1430 SMESH::long_array_var anIds1 = theGroup1->GetListOfID();
1431 SMESH::long_array_var anIds2 = theGroup2->GetListOfID();
1433 TColStd_MapOfInteger aMap2;
1435 for ( int i2 = 0, n2 = anIds2->length(); i2 < n2; i2++ )
1436 aMap2.Add( anIds2[ i2 ] );
1438 TColStd_SequenceOfInteger aSeq;
1439 for ( int i1 = 0, n1 = anIds1->length(); i1 < n1; i1++ )
1440 if ( !aMap2.Contains( anIds1[ i1 ] ) )
1441 aSeq.Append( anIds1[ i1 ] );
1443 SMESH::long_array_var aResIds = new SMESH::long_array;
1444 aResIds->length( aSeq.Length() );
1446 for ( int resI = 0, resN = aSeq.Length(); resI < resN; resI++ )
1447 aResIds[ resI ] = aSeq( resI + 1 );
1448 aResGrp->Add( aResIds );
1450 // Update Python script
1451 pyDump << aResGrp << " = " << _this() << ".CutGroups( "
1452 << theGroup1 << ", " << theGroup2 << ", '"
1453 << theName << "' )";
1455 return aResGrp._retn();
1458 //=============================================================================
1460 \brief Cut lists of groups. New group is created. All mesh elements that are
1461 present in main groups but do not present in tool groups are added to the new one
1462 \param theMainGroups list of main groups
1463 \param theToolGroups list of tool groups
1464 \param theName name of group to be created
1465 \return pointer on the group
1467 //=============================================================================
1468 SMESH::SMESH_Group_ptr
1469 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1470 const SMESH::ListOfGroups& theToolGroups,
1471 const char* theName )
1472 throw (SALOME::SALOME_Exception)
1475 _preMeshInfo->FullLoadFromFile();
1478 return SMESH::SMESH_Group::_nil();
1482 set< int > aToolIds;
1483 SMESH::ElementType aType = SMESH::ALL;
1485 // iterate through tool groups
1486 for ( g = 0, n = theToolGroups.length(); g < n; g++ )
1488 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1489 if ( CORBA::is_nil( aGrp ) )
1493 SMESH::ElementType aCurrType = aGrp->GetType();
1494 if ( aType == SMESH::ALL )
1498 if ( aType != aCurrType )
1499 return SMESH::SMESH_Group::_nil();
1503 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1504 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1506 int aCurrId = aCurrIds[ i ];
1507 aToolIds.insert( aCurrId );
1511 vector< int > anIds; // result
1513 // Iterate through main group
1514 for ( g = 0, n = theMainGroups.length(); g < n; g++ )
1516 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1517 if ( CORBA::is_nil( aGrp ) )
1521 SMESH::ElementType aCurrType = aGrp->GetType();
1522 if ( aType == SMESH::ALL )
1526 if ( aType != aCurrType )
1527 return SMESH::SMESH_Group::_nil();
1531 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1532 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1534 int aCurrId = aCurrIds[ i ];
1535 if ( !aToolIds.count( aCurrId ) )
1536 anIds.push_back( aCurrId );
1543 SMESH::SMESH_Group_var aResGrp = CreateGroup( aType, theName );
1544 if ( aResGrp->_is_nil() )
1545 return SMESH::SMESH_Group::_nil();
1547 // Create array of identifiers
1548 SMESH::long_array_var aResIds = new SMESH::long_array;
1549 aResIds->length( anIds.size() );
1551 for (int i=0; i<anIds.size(); i++ )
1552 aResIds[ i ] = anIds[i];
1553 aResGrp->Add( aResIds );
1555 // Update Python script
1556 pyDump << aResGrp << " = " << _this() << ".CutListOfGroups( "
1557 << &theMainGroups << ", " << &theToolGroups << ", '"
1558 << theName << "' )";
1560 return aResGrp._retn();
1564 return SMESH::SMESH_Group::_nil();
1568 //=============================================================================
1570 \brief Create groups of entities from existing groups of superior dimensions
1572 1) extract all nodes from each group,
1573 2) combine all elements of specified dimension laying on these nodes.
1574 \param theGroups list of source groups
1575 \param theElemType dimension of elements
1576 \param theName name of new group
1577 \return pointer on new group
1579 //=============================================================================
1580 SMESH::SMESH_Group_ptr
1581 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1582 SMESH::ElementType theElemType,
1583 const char* theName )
1584 throw (SALOME::SALOME_Exception)
1587 _preMeshInfo->FullLoadFromFile();
1589 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1591 if ( !theName || !aMeshDS )
1592 return SMESH::SMESH_Group::_nil();
1594 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1598 // Create map of nodes from all groups
1600 set< int > aNodeMap;
1602 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1604 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1605 if ( CORBA::is_nil( aGrp ) )
1608 SMESH::ElementType aType = aGrp->GetType();
1609 if ( aType == SMESH::ALL )
1611 else if ( aType == SMESH::NODE )
1613 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1614 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1616 int aCurrId = aCurrIds[ i ];
1617 const SMDS_MeshNode* aNode = aMeshDS->FindNode( aCurrId );
1619 aNodeMap.insert( aNode->GetID() );
1624 SMESH::long_array_var aCurrIds = aGrp->GetListOfID();
1625 for ( int i = 0, n = aCurrIds->length(); i < n; i++ )
1627 int aCurrId = aCurrIds[ i ];
1628 const SMDS_MeshElement* anElem = aMeshDS->FindElement( aCurrId );
1631 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1632 while( aNodeIter->more() )
1634 const SMDS_MeshNode* aNode =
1635 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1637 aNodeMap.insert( aNode->GetID() );
1643 // Get result identifiers
1645 vector< int > aResultIds;
1646 if ( theElemType == SMESH::NODE )
1648 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1649 set<int>::iterator iter = aNodeMap.begin();
1650 for ( ; iter != aNodeMap.end(); iter++ )
1651 aResultIds.push_back( *iter);
1655 // Create list of elements of given dimension constructed on the nodes
1656 vector< int > anElemList;
1657 //NCollection_Map< int >::Iterator aNodeIter( aNodeMap );
1658 //for ( ; aNodeIter.More(); aNodeIter.Next() )
1659 set<int>::iterator iter = aNodeMap.begin();
1660 for ( ; iter != aNodeMap.end(); iter++ )
1662 const SMDS_MeshElement* aNode =
1663 dynamic_cast<const SMDS_MeshElement*>( aMeshDS->FindNode( *iter ) );
1667 SMDS_ElemIteratorPtr anElemIter = aNode->elementsIterator( anElemType );
1668 while( anElemIter->more() )
1670 const SMDS_MeshElement* anElem =
1671 dynamic_cast<const SMDS_MeshElement*>( anElemIter->next() );
1672 if ( anElem && anElem->GetType() == anElemType )
1673 anElemList.push_back( anElem->GetID() );
1677 // check whether all nodes of elements are present in nodes map
1678 for (int i=0; i< anElemList.size(); i++)
1680 const SMDS_MeshElement* anElem = aMeshDS->FindElement( anElemList[i] );
1685 SMDS_ElemIteratorPtr aNodeIter = anElem->nodesIterator();
1686 while( aNodeIter->more() )
1688 const SMDS_MeshNode* aNode =
1689 dynamic_cast<const SMDS_MeshNode*>( aNodeIter->next() );
1690 if ( !aNode || !aNodeMap.count( aNode->GetID() ) )
1697 aResultIds.push_back( anElem->GetID() );
1705 SMESH::SMESH_Group_var aResGrp = CreateGroup( theElemType, theName );
1706 if ( aResGrp->_is_nil() )
1707 return SMESH::SMESH_Group::_nil();
1709 // Create array of identifiers
1710 SMESH::long_array_var aResIds = new SMESH::long_array;
1711 aResIds->length( aResultIds.size() );
1713 for (int i=0; i< aResultIds.size(); i++)
1714 aResIds[ i ] = aResultIds[i];
1715 aResGrp->Add( aResIds );
1717 // Update Python script
1718 pyDump << aResGrp << " = " << _this() << ".CreateDimGroup( "
1719 << &theGroups << ", " << theElemType << ", '" << theName << "' )";
1721 return aResGrp._retn();
1725 return SMESH::SMESH_Group::_nil();
1729 //================================================================================
1731 * \brief Remember GEOM group data
1733 //================================================================================
1735 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1736 CORBA::Object_ptr theSmeshObj)
1738 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1741 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1742 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1743 if ( groupSO->_is_nil() )
1746 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1747 GEOM::GEOM_IGroupOperations_wrap groupOp =
1748 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1749 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1752 _geomGroupData.push_back( TGeomGroupData() );
1753 TGeomGroupData & groupData = _geomGroupData.back();
1755 CORBA::String_var entry = groupSO->GetID();
1756 groupData._groupEntry = entry.in();
1758 for ( int i = 0; i < ids->length(); ++i )
1759 groupData._indices.insert( ids[i] );
1761 groupData._smeshObject = theSmeshObj;
1764 //================================================================================
1766 * Remove GEOM group data relating to removed smesh object
1768 //================================================================================
1770 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1772 list<TGeomGroupData>::iterator
1773 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1774 for ( ; data != dataEnd; ++data ) {
1775 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1776 _geomGroupData.erase( data );
1782 //================================================================================
1784 * \brief Return new group contents if it has been changed and update group data
1786 //================================================================================
1788 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1790 TopoDS_Shape newShape;
1793 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1794 if ( study->_is_nil() ) return newShape; // means "not changed"
1795 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1796 if ( !groupSO->_is_nil() )
1798 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1799 if ( CORBA::is_nil( groupObj )) return newShape;
1800 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1802 // get indices of group items
1803 set<int> curIndices;
1804 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1805 GEOM::GEOM_IGroupOperations_wrap groupOp =
1806 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1807 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1808 for ( int i = 0; i < ids->length(); ++i )
1809 curIndices.insert( ids[i] );
1811 if ( groupData._indices == curIndices )
1812 return newShape; // group not changed
1815 groupData._indices = curIndices;
1817 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1818 if ( !geomClient ) return newShape;
1819 TCollection_AsciiString groupIOR = geomGen->GetStringFromIOR( geomGroup );
1820 geomClient->RemoveShapeFromBuffer( groupIOR );
1821 newShape = _gen_i->GeomObjectToShape( geomGroup );
1824 if ( newShape.IsNull() ) {
1825 // geom group becomes empty - return empty compound
1826 TopoDS_Compound compound;
1827 BRep_Builder().MakeCompound(compound);
1828 newShape = compound;
1835 //=============================================================================
1837 * \brief Storage of shape and index used in CheckGeomGroupModif()
1839 //=============================================================================
1840 struct TIndexedShape
1843 TopoDS_Shape _shape;
1844 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1847 //=============================================================================
1849 * \brief Update objects depending on changed geom groups
1851 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1852 * issue 0020210: Update of a smesh group after modification of the associated geom group
1854 //=============================================================================
1856 void SMESH_Mesh_i::CheckGeomGroupModif()
1858 if ( !_impl->HasShapeToMesh() ) return;
1860 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1861 if ( study->_is_nil() ) return;
1863 CORBA::Long nbEntities = NbNodes() + NbElements();
1865 // Check if group contents changed
1867 typedef map< string, TopoDS_Shape > TEntry2Geom;
1868 TEntry2Geom newGroupContents;
1870 list<TGeomGroupData>::iterator
1871 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1872 for ( ; data != dataEnd; ++data )
1874 pair< TEntry2Geom::iterator, bool > it_new =
1875 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1876 bool processedGroup = !it_new.second;
1877 TopoDS_Shape& newShape = it_new.first->second;
1878 if ( !processedGroup )
1879 newShape = newGroupShape( *data );
1880 if ( newShape.IsNull() )
1881 continue; // no changes
1884 _preMeshInfo->ForgetOrLoad();
1886 if ( processedGroup ) { // update group indices
1887 list<TGeomGroupData>::iterator data2 = data;
1888 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1889 data->_indices = data2->_indices;
1892 // Update SMESH objects according to new GEOM group contents
1894 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1895 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1897 int oldID = submesh->GetId();
1898 if ( _mapSubMeshIor.find( oldID ) == _mapSubMeshIor.end() )
1900 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1902 // update hypotheses
1903 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1904 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1905 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1907 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1908 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1910 // care of submeshes
1911 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1912 int newID = newSubmesh->GetId();
1913 if ( newID != oldID ) {
1914 _mapSubMesh [ newID ] = newSubmesh;
1915 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1916 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1917 _mapSubMesh. erase(oldID);
1918 _mapSubMesh_i. erase(oldID);
1919 _mapSubMeshIor.erase(oldID);
1920 _mapSubMesh_i [ newID ]->changeLocalId( newID );
1925 SMESH::SMESH_GroupOnGeom_var smeshGroup =
1926 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
1927 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
1929 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
1931 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
1932 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
1933 ds->SetShape( newShape );
1938 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
1939 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
1941 // Remove groups and submeshes basing on removed sub-shapes
1943 TopTools_MapOfShape newShapeMap;
1944 TopoDS_Iterator shapeIt( newShape );
1945 for ( ; shapeIt.More(); shapeIt.Next() )
1946 newShapeMap.Add( shapeIt.Value() );
1948 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1949 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
1951 if ( newShapeMap.Contains( shapeIt.Value() ))
1953 TopTools_IndexedMapOfShape oldShapeMap;
1954 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
1955 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
1957 const TopoDS_Shape& oldShape = oldShapeMap(i);
1958 int oldInd = meshDS->ShapeToIndex( oldShape );
1960 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
1961 if ( i_smIor != _mapSubMeshIor.end() ) {
1962 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
1965 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
1966 for ( ; i_grp != _mapGroups.end(); ++i_grp )
1968 // check if a group bases on oldInd shape
1969 SMESHDS_GroupOnGeom* grpOnGeom = 0;
1970 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
1971 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
1972 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
1974 RemoveGroup( i_grp->second ); // several groups can base on same shape
1975 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
1980 // Reassign hypotheses and update groups after setting the new shape to mesh
1982 // collect anassigned hypotheses
1983 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
1984 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
1985 TShapeHypList assignedHyps;
1986 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
1988 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
1989 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
1990 if ( !hyps.empty() ) {
1991 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
1992 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1993 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1996 // collect shapes supporting groups
1997 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
1998 TShapeTypeList groupData;
1999 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2000 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2001 for ( ; grIt != groups.end(); ++grIt )
2003 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2005 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2007 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2008 _impl->ShapeToMesh( newShape );
2010 // reassign hypotheses
2011 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2012 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2014 TIndexedShape& geom = indS_hyps->first;
2015 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2016 int oldID = geom._index;
2017 int newID = meshDS->ShapeToIndex( geom._shape );
2020 if ( oldID == 1 ) { // main shape
2022 geom._shape = newShape;
2024 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2025 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2026 // care of submeshes
2027 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2028 if ( newID != oldID ) {
2029 _mapSubMesh [ newID ] = newSubmesh;
2030 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2031 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2032 _mapSubMesh. erase(oldID);
2033 _mapSubMesh_i. erase(oldID);
2034 _mapSubMeshIor.erase(oldID);
2035 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2039 TShapeTypeList::iterator geomType = groupData.begin();
2040 for ( ; geomType != groupData.end(); ++geomType )
2042 const TIndexedShape& geom = geomType->first;
2043 int oldID = geom._index;
2044 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2047 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2048 CORBA::String_var name = groupSO->GetName();
2050 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2052 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2053 group_i->changeLocalId( newID );
2056 break; // everything has been updated
2059 } // loop on group data
2063 CORBA::Long newNbEntities = NbNodes() + NbElements();
2064 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2065 if ( newNbEntities != nbEntities )
2067 // Add all SObjects with icons to soToUpdateIcons
2068 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2070 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2071 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2072 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2074 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2075 i_gr != _mapGroups.end(); ++i_gr ) // groups
2076 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2079 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2080 for ( ; so != soToUpdateIcons.end(); ++so )
2081 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2084 //=============================================================================
2086 * \brief Create standalone group from a group on geometry or filter
2088 //=============================================================================
2090 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2093 _preMeshInfo->FullLoadFromFile();
2095 SMESH::SMESH_Group_var aGroup;
2096 if ( theGroup->_is_nil() )
2097 return aGroup._retn();
2099 Unexpect aCatch(SALOME_SalomeException);
2101 SMESH_GroupBase_i* aGroupToRem =
2102 dynamic_cast<SMESH_GroupBase_i*>( SMESH_Gen_i::GetServant( theGroup ).in() );
2104 return aGroup._retn();
2106 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2108 int anId = aGroupToRem->GetLocalID();
2109 if ( !_impl->ConvertToStandalone( anId ) )
2110 return aGroup._retn();
2111 removeGeomGroupData( theGroup );
2113 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2115 // remove old instance of group from own map
2116 _mapGroups.erase( anId );
2118 SALOMEDS::StudyBuilder_var builder;
2119 SALOMEDS::SObject_wrap aGroupSO;
2120 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2121 if ( !aStudy->_is_nil() ) {
2122 builder = aStudy->NewBuilder();
2123 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2124 if ( !aGroupSO->_is_nil() )
2126 // remove reference to geometry
2127 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2128 for ( ; chItr->More(); chItr->Next() )
2129 // Remove group's child SObject
2130 builder->RemoveObject( chItr->Value() );
2132 // Update Python script
2133 TPythonDump() << aGroupSO << " = " << _this() << ".ConvertToStandalone( "
2134 << aGroupSO << " )";
2136 // change icon of Group on Filter
2139 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2140 const int isEmpty = ( elemTypes->length() == 0 );
2143 SALOMEDS::GenericAttribute_wrap anAttr =
2144 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2145 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2146 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2152 // remember new group in own map
2153 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2154 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2156 // register CORBA object for persistence
2157 _gen_i->RegisterObject( aGroup );
2159 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2160 builder->SetIOR( aGroupSO, ior.in() );
2162 return aGroup._retn();
2165 //=============================================================================
2169 //=============================================================================
2171 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2173 if(MYDEBUG) MESSAGE( "createSubMesh" );
2174 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2176 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2177 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
2178 SMESH_subMesh_i *subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2179 SMESH::SMESH_subMesh_var subMesh
2180 = SMESH::SMESH_subMesh::_narrow(subMeshServant->_this());
2182 _mapSubMesh[subMeshId] = mySubMesh;
2183 _mapSubMesh_i[subMeshId] = subMeshServant;
2184 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate(subMesh);
2186 // register CORBA object for persistence
2187 int nextId = _gen_i->RegisterObject( subMesh );
2188 if(MYDEBUG) MESSAGE( "Add submesh to map with id = "<< nextId);
2190 // to track changes of GEOM groups
2191 addGeomGroupData( theSubShapeObject, subMesh );
2193 return subMesh._retn();
2196 //=======================================================================
2197 //function : getSubMesh
2199 //=======================================================================
2201 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2203 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2204 if ( it == _mapSubMeshIor.end() )
2205 return SMESH::SMESH_subMesh::_nil();
2207 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2211 //=============================================================================
2215 //=============================================================================
2217 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2218 GEOM::GEOM_Object_ptr theSubShapeObject )
2220 bool isHypChanged = false;
2221 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2222 return isHypChanged;
2224 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2226 CORBA::Long shapeId = theSubMesh->GetId();
2227 if ( _mapSubMesh.find( shapeId ) != _mapSubMesh.end())
2229 TopoDS_Shape S = _mapSubMesh[ shapeId ]->GetSubShape();
2232 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2233 isHypChanged = !hyps.empty();
2234 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2235 for ( ; hyp != hyps.end(); ++hyp )
2236 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2243 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2244 isHypChanged = ( aHypList->length() > 0 );
2245 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2246 removeHypothesis( theSubShapeObject, aHypList[i] );
2249 catch( const SALOME::SALOME_Exception& ) {
2250 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2252 removeGeomGroupData( theSubShapeObject );
2254 int subMeshId = theSubMesh->GetId();
2256 _mapSubMesh.erase(subMeshId);
2257 _mapSubMesh_i.erase(subMeshId);
2258 _mapSubMeshIor.erase(subMeshId);
2260 return isHypChanged;
2263 //=============================================================================
2267 //=============================================================================
2269 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2270 const char* theName,
2271 const TopoDS_Shape& theShape,
2272 const SMESH_PredicatePtr& thePredicate )
2274 std::string newName;
2275 if ( !theName || strlen( theName ) == 0 )
2277 std::set< std::string > presentNames;
2278 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2279 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2280 presentNames.insert( i_gr->second->GetName() );
2282 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2283 } while ( !presentNames.insert( newName ).second );
2284 theName = newName.c_str();
2287 SMESH::SMESH_GroupBase_var aGroup;
2288 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2290 SMESH_GroupBase_i* aGroupImpl;
2291 if ( !theShape.IsNull() )
2292 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2293 else if ( thePredicate )
2294 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2296 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2298 aGroup = SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
2299 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2301 // register CORBA object for persistence
2302 int nextId = _gen_i->RegisterObject( aGroup );
2303 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
2305 // to track changes of GEOM groups
2306 if ( !theShape.IsNull() ) {
2307 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2308 addGeomGroupData( geom, aGroup );
2311 return aGroup._retn();
2314 //=============================================================================
2316 * SMESH_Mesh_i::removeGroup
2318 * Should be called by ~SMESH_Group_i()
2320 //=============================================================================
2322 void SMESH_Mesh_i::removeGroup( const int theId )
2324 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2325 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2326 SMESH::SMESH_GroupBase_ptr group = _mapGroups[theId];
2327 _mapGroups.erase( theId );
2328 removeGeomGroupData( group );
2329 if (! _impl->RemoveGroup( theId ))
2331 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2332 RemoveGroup( group );
2337 //=============================================================================
2341 //=============================================================================
2343 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2344 throw(SALOME::SALOME_Exception)
2347 _preMeshInfo->FullLoadFromFile();
2349 SMESH::log_array_var aLog;
2351 list < SMESHDS_Command * >logDS = _impl->GetLog();
2352 aLog = new SMESH::log_array;
2354 int lg = logDS.size();
2357 list < SMESHDS_Command * >::iterator its = logDS.begin();
2358 while(its != logDS.end()){
2359 SMESHDS_Command *com = *its;
2360 int comType = com->GetType();
2362 int lgcom = com->GetNumber();
2364 const list < int >&intList = com->GetIndexes();
2365 int inum = intList.size();
2367 list < int >::const_iterator ii = intList.begin();
2368 const list < double >&coordList = com->GetCoords();
2369 int rnum = coordList.size();
2371 list < double >::const_iterator ir = coordList.begin();
2372 aLog[indexLog].commandType = comType;
2373 aLog[indexLog].number = lgcom;
2374 aLog[indexLog].coords.length(rnum);
2375 aLog[indexLog].indexes.length(inum);
2376 for(int i = 0; i < rnum; i++){
2377 aLog[indexLog].coords[i] = *ir;
2378 //MESSAGE(" "<<i<<" "<<ir.Value());
2381 for(int i = 0; i < inum; i++){
2382 aLog[indexLog].indexes[i] = *ii;
2383 //MESSAGE(" "<<i<<" "<<ii.Value());
2392 catch(SALOME_Exception & S_ex){
2393 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
2395 return aLog._retn();
2399 //=============================================================================
2403 //=============================================================================
2405 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2407 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::ClearLog");
2411 //=============================================================================
2415 //=============================================================================
2417 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2419 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetId");
2423 //=============================================================================
2427 //=============================================================================
2429 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2434 //=============================================================================
2437 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2438 // issue 0020918: groups removal is caused by hyp modification
2439 // issue 0021208: to forget not loaded mesh data at hyp modification
2440 struct TCallUp_i : public SMESH_Mesh::TCallUp
2442 SMESH_Mesh_i* _mesh;
2443 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2444 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2445 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2446 virtual void Load () { _mesh->Load(); }
2450 //================================================================================
2452 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2454 //================================================================================
2456 void SMESH_Mesh_i::onHypothesisModified()
2459 _preMeshInfo->ForgetOrLoad();
2462 //=============================================================================
2466 //=============================================================================
2468 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2470 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2473 _impl->SetCallUp( new TCallUp_i(this));
2476 //=============================================================================
2480 //=============================================================================
2482 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2484 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2488 //=============================================================================
2490 * Return mesh editor
2492 //=============================================================================
2494 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2497 _preMeshInfo->FullLoadFromFile();
2499 // Create MeshEditor
2500 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, false );
2501 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2503 // Update Python script
2504 TPythonDump() << aMeshEditor << " = " << _this() << ".GetMeshEditor()";
2506 return aMesh._retn();
2509 //=============================================================================
2511 * Return mesh edition previewer
2513 //=============================================================================
2515 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2518 _preMeshInfo->FullLoadFromFile();
2520 SMESH_MeshEditor_i *aMeshEditor = new SMESH_MeshEditor_i( this, true );
2521 SMESH::SMESH_MeshEditor_var aMesh = aMeshEditor->_this();
2522 return aMesh._retn();
2525 //================================================================================
2527 * \brief Return true if the mesh has been edited since a last total re-compute
2528 * and those modifications may prevent successful partial re-compute
2530 //================================================================================
2532 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2534 Unexpect aCatch(SALOME_SalomeException);
2535 return _impl->HasModificationsToDiscard();
2538 //================================================================================
2540 * \brief Returns a random unique color
2542 //================================================================================
2544 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2546 const int MAX_ATTEMPTS = 100;
2548 double tolerance = 0.5;
2549 SALOMEDS::Color col;
2553 // generate random color
2554 double red = (double)rand() / RAND_MAX;
2555 double green = (double)rand() / RAND_MAX;
2556 double blue = (double)rand() / RAND_MAX;
2557 // check existence in the list of the existing colors
2558 bool matched = false;
2559 std::list<SALOMEDS::Color>::const_iterator it;
2560 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2561 SALOMEDS::Color color = *it;
2562 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2563 matched = tol < tolerance;
2565 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2566 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2574 //=============================================================================
2576 * Sets auto-color mode. If it is on, groups get unique random colors
2578 //=============================================================================
2580 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2582 Unexpect aCatch(SALOME_SalomeException);
2583 _impl->SetAutoColor(theAutoColor);
2585 TPythonDump pyDump; // not to dump group->SetColor() from below code
2586 pyDump<<_this()<<".SetAutoColor( "<<theAutoColor<<" )";
2588 std::list<SALOMEDS::Color> aReservedColors;
2589 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2590 for ( ; it != _mapGroups.end(); it++ ) {
2591 if ( CORBA::is_nil( it->second )) continue;
2592 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2593 it->second->SetColor( aColor );
2594 aReservedColors.push_back( aColor );
2598 //=============================================================================
2600 * Returns true if auto-color mode is on
2602 //=============================================================================
2604 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2606 Unexpect aCatch(SALOME_SalomeException);
2607 return _impl->GetAutoColor();
2610 //=============================================================================
2612 * Checks if there are groups with equal names
2614 //=============================================================================
2616 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2618 return _impl->HasDuplicatedGroupNamesMED();
2621 //================================================================================
2623 * \brief Care of a file before exporting mesh into it
2625 //================================================================================
2627 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2629 TCollection_AsciiString aFullName ((char*)file);
2630 OSD_Path aPath (aFullName);
2631 OSD_File aFile (aPath);
2632 if (aFile.Exists()) {
2633 // existing filesystem node
2634 if (aFile.KindOfFile() == OSD_FILE) {
2635 if (aFile.IsWriteable()) {
2640 if (aFile.Failed()) {
2641 TCollection_AsciiString msg ("File ");
2642 msg += aFullName + " cannot be replaced.";
2643 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2646 TCollection_AsciiString msg ("File ");
2647 msg += aFullName + " cannot be overwritten.";
2648 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2651 TCollection_AsciiString msg ("Location ");
2652 msg += aFullName + " is not a file.";
2653 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2656 // nonexisting file; check if it can be created
2658 aFile.Build(OSD_WriteOnly, OSD_Protection());
2659 if (aFile.Failed()) {
2660 TCollection_AsciiString msg ("You cannot create the file ");
2661 msg += aFullName + ". Check the directory existance and access rights.";
2662 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2670 //================================================================================
2672 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2673 * \param file - file name
2674 * \param overwrite - to erase the file or not
2675 * \retval string - mesh name
2677 //================================================================================
2679 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2680 CORBA::Boolean overwrite)
2683 PrepareForWriting(file, overwrite);
2684 string aMeshName = "Mesh";
2685 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2686 if ( !aStudy->_is_nil() ) {
2687 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2688 if ( !aMeshSO->_is_nil() ) {
2689 CORBA::String_var name = aMeshSO->GetName();
2691 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2692 if ( !aStudy->GetProperties()->IsLocked() )
2694 SALOMEDS::GenericAttribute_wrap anAttr;
2695 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2696 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2697 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2698 ASSERT(!aFileName->_is_nil());
2699 aFileName->SetValue(file);
2700 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2701 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2702 ASSERT(!aFileType->_is_nil());
2703 aFileType->SetValue("FICHIERMED");
2707 // Update Python script
2708 // set name of mesh before export
2709 TPythonDump() << _gen_i << ".SetName(" << _this() << ", '" << aMeshName.c_str() << "')";
2711 // check names of groups
2717 //================================================================================
2719 * \brief Export to med file
2721 //================================================================================
2723 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2724 CORBA::Boolean auto_groups,
2725 SMESH::MED_VERSION theVersion,
2726 CORBA::Boolean overwrite)
2727 throw(SALOME::SALOME_Exception)
2729 Unexpect aCatch(SALOME_SalomeException);
2731 _preMeshInfo->FullLoadFromFile();
2733 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2734 TPythonDump() << _this() << ".ExportToMEDX( r'"
2735 << file << "', " << auto_groups << ", " << theVersion << ", " << overwrite << " )";
2737 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion );
2740 //================================================================================
2742 * \brief Export a mesh to a med file
2744 //================================================================================
2746 void SMESH_Mesh_i::ExportToMED (const char* file,
2747 CORBA::Boolean auto_groups,
2748 SMESH::MED_VERSION theVersion)
2749 throw(SALOME::SALOME_Exception)
2751 ExportToMEDX(file,auto_groups,theVersion,true);
2754 //================================================================================
2756 * \brief Export a mesh to a med file
2758 //================================================================================
2760 void SMESH_Mesh_i::ExportMED (const char* file,
2761 CORBA::Boolean auto_groups)
2762 throw(SALOME::SALOME_Exception)
2764 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2767 //================================================================================
2769 * \brief Export a mesh to a SAUV file
2771 //================================================================================
2773 void SMESH_Mesh_i::ExportSAUV (const char* file,
2774 CORBA::Boolean auto_groups)
2775 throw(SALOME::SALOME_Exception)
2777 Unexpect aCatch(SALOME_SalomeException);
2779 _preMeshInfo->FullLoadFromFile();
2781 string aMeshName = prepareMeshNameAndGroups(file, true);
2782 TPythonDump() << _this() << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2783 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2787 //================================================================================
2789 * \brief Export a mesh to a DAT file
2791 //================================================================================
2793 void SMESH_Mesh_i::ExportDAT (const char *file)
2794 throw(SALOME::SALOME_Exception)
2796 Unexpect aCatch(SALOME_SalomeException);
2798 _preMeshInfo->FullLoadFromFile();
2800 // Update Python script
2801 // check names of groups
2803 TPythonDump() << _this() << ".ExportDAT( r'" << file << "' )";
2806 PrepareForWriting(file);
2807 _impl->ExportDAT(file);
2810 //================================================================================
2812 * \brief Export a mesh to an UNV file
2814 //================================================================================
2816 void SMESH_Mesh_i::ExportUNV (const char *file)
2817 throw(SALOME::SALOME_Exception)
2819 Unexpect aCatch(SALOME_SalomeException);
2821 _preMeshInfo->FullLoadFromFile();
2823 // Update Python script
2824 // check names of groups
2826 TPythonDump() << _this() << ".ExportUNV( r'" << file << "' )";
2829 PrepareForWriting(file);
2830 _impl->ExportUNV(file);
2833 //================================================================================
2835 * \brief Export a mesh to an STL file
2837 //================================================================================
2839 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2840 throw(SALOME::SALOME_Exception)
2842 Unexpect aCatch(SALOME_SalomeException);
2844 _preMeshInfo->FullLoadFromFile();
2846 // Update Python script
2847 // check names of groups
2849 TPythonDump() << _this() << ".ExportSTL( r'" << file << "', " << isascii << " )";
2852 PrepareForWriting(file);
2853 _impl->ExportSTL(file, isascii);
2856 //================================================================================
2858 * \brief Export a part of mesh to a med file
2860 //================================================================================
2862 void SMESH_Mesh_i::ExportPartToMED(::SMESH::SMESH_IDSource_ptr meshPart,
2864 CORBA::Boolean auto_groups,
2865 ::SMESH::MED_VERSION version,
2866 ::CORBA::Boolean overwrite)
2867 throw (SALOME::SALOME_Exception)
2869 Unexpect aCatch(SALOME_SalomeException);
2871 _preMeshInfo->FullLoadFromFile();
2873 PrepareForWriting(file, overwrite);
2875 string aMeshName = "Mesh";
2876 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2877 if ( !aStudy->_is_nil() ) {
2878 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
2879 if ( !SO->_is_nil() ) {
2880 CORBA::String_var name = SO->GetName();
2884 SMESH_MeshPartDS partDS( meshPart );
2885 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, &partDS );
2887 TPythonDump() << _this() << ".ExportPartToMED( " << meshPart << ", r'" << file << "', "
2888 << auto_groups << ", " << version << ", " << overwrite << " )";
2891 //================================================================================
2893 * \brief Export a part of mesh to a DAT file
2895 //================================================================================
2897 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
2899 throw (SALOME::SALOME_Exception)
2901 Unexpect aCatch(SALOME_SalomeException);
2903 _preMeshInfo->FullLoadFromFile();
2905 PrepareForWriting(file);
2907 SMESH_MeshPartDS partDS( meshPart );
2908 _impl->ExportDAT(file,&partDS);
2910 TPythonDump() << _this() << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
2912 //================================================================================
2914 * \brief Export a part of mesh to an UNV file
2916 //================================================================================
2918 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
2920 throw (SALOME::SALOME_Exception)
2922 Unexpect aCatch(SALOME_SalomeException);
2924 _preMeshInfo->FullLoadFromFile();
2926 PrepareForWriting(file);
2928 SMESH_MeshPartDS partDS( meshPart );
2929 _impl->ExportUNV(file, &partDS);
2931 TPythonDump() << _this() << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
2933 //================================================================================
2935 * \brief Export a part of mesh to an STL file
2937 //================================================================================
2939 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
2941 ::CORBA::Boolean isascii)
2942 throw (SALOME::SALOME_Exception)
2944 Unexpect aCatch(SALOME_SalomeException);
2946 _preMeshInfo->FullLoadFromFile();
2948 PrepareForWriting(file);
2950 SMESH_MeshPartDS partDS( meshPart );
2951 _impl->ExportSTL(file, isascii, &partDS);
2953 TPythonDump() << _this() << ".ExportPartToSTL( "
2954 << meshPart<< ", r'" << file << "', " << isascii << ")";
2957 //================================================================================
2959 * \brief Export a part of mesh to an STL file
2961 //================================================================================
2963 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
2965 CORBA::Boolean overwrite)
2966 throw (SALOME::SALOME_Exception)
2969 Unexpect aCatch(SALOME_SalomeException);
2971 _preMeshInfo->FullLoadFromFile();
2973 PrepareForWriting(file,overwrite);
2975 SMESH_MeshPartDS partDS( meshPart );
2976 _impl->ExportCGNS(file, &partDS);
2978 TPythonDump() << _this() << ".ExportCGNS( "
2979 << meshPart<< ", r'" << file << "', " << overwrite << ")";
2981 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
2985 //================================================================================
2987 * \brief Export a part of mesh to a GMF file
2989 //================================================================================
2991 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
2993 bool withRequiredGroups)
2994 throw (SALOME::SALOME_Exception)
2996 Unexpect aCatch(SALOME_SalomeException);
2998 _preMeshInfo->FullLoadFromFile();
3000 PrepareForWriting(file,/*overwrite=*/true);
3002 SMESH_MeshPartDS partDS( meshPart );
3003 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3005 TPythonDump() << _this() << ".ExportGMF( "
3006 << meshPart<< ", r'"
3008 << withRequiredGroups << ")";
3011 //=============================================================================
3013 * Return implementation of SALOME_MED::MESH interfaces
3015 //=============================================================================
3017 SALOME_MED::MESH_ptr SMESH_Mesh_i::GetMEDMesh()throw(SALOME::SALOME_Exception)
3019 Unexpect aCatch(SALOME_SalomeException);
3021 _preMeshInfo->FullLoadFromFile();
3023 SMESH_MEDMesh_i *aMedMesh = new SMESH_MEDMesh_i(this);
3024 SALOME_MED::MESH_var aMesh = aMedMesh->_this();
3025 return aMesh._retn();
3028 //=============================================================================
3030 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3032 Unexpect aCatch(SALOME_SalomeException);
3034 return _preMeshInfo->NbNodes();
3036 return _impl->NbNodes();
3039 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3041 Unexpect aCatch(SALOME_SalomeException);
3043 return _preMeshInfo->NbElements();
3045 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3048 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3050 Unexpect aCatch(SALOME_SalomeException);
3052 return _preMeshInfo->Nb0DElements();
3054 return _impl->Nb0DElements();
3057 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3059 Unexpect aCatch(SALOME_SalomeException);
3061 return _preMeshInfo->NbBalls();
3063 return _impl->NbBalls();
3066 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3068 Unexpect aCatch(SALOME_SalomeException);
3070 return _preMeshInfo->NbEdges();
3072 return _impl->NbEdges();
3075 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3076 throw(SALOME::SALOME_Exception)
3078 Unexpect aCatch(SALOME_SalomeException);
3080 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3082 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3085 //=============================================================================
3087 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3089 Unexpect aCatch(SALOME_SalomeException);
3091 return _preMeshInfo->NbFaces();
3093 return _impl->NbFaces();
3096 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3098 Unexpect aCatch(SALOME_SalomeException);
3100 return _preMeshInfo->NbTriangles();
3102 return _impl->NbTriangles();
3105 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3107 Unexpect aCatch(SALOME_SalomeException);
3109 return _preMeshInfo->NbQuadrangles();
3111 return _impl->NbQuadrangles();
3114 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3116 Unexpect aCatch(SALOME_SalomeException);
3118 return _preMeshInfo->NbBiQuadQuadrangles();
3120 return _impl->NbBiQuadQuadrangles();
3123 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3125 Unexpect aCatch(SALOME_SalomeException);
3127 return _preMeshInfo->NbPolygons();
3129 return _impl->NbPolygons();
3132 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3133 throw(SALOME::SALOME_Exception)
3135 Unexpect aCatch(SALOME_SalomeException);
3137 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3139 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3142 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3143 throw(SALOME::SALOME_Exception)
3145 Unexpect aCatch(SALOME_SalomeException);
3147 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3149 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3152 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3153 throw(SALOME::SALOME_Exception)
3155 Unexpect aCatch(SALOME_SalomeException);
3157 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3159 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3162 //=============================================================================
3164 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3166 Unexpect aCatch(SALOME_SalomeException);
3168 return _preMeshInfo->NbVolumes();
3170 return _impl->NbVolumes();
3173 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3175 Unexpect aCatch(SALOME_SalomeException);
3177 return _preMeshInfo->NbTetras();
3179 return _impl->NbTetras();
3182 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3184 Unexpect aCatch(SALOME_SalomeException);
3186 return _preMeshInfo->NbHexas();
3188 return _impl->NbHexas();
3191 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3193 Unexpect aCatch(SALOME_SalomeException);
3195 return _preMeshInfo->NbTriQuadHexas();
3197 return _impl->NbTriQuadraticHexas();
3200 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3202 Unexpect aCatch(SALOME_SalomeException);
3204 return _preMeshInfo->NbPyramids();
3206 return _impl->NbPyramids();
3209 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3211 Unexpect aCatch(SALOME_SalomeException);
3213 return _preMeshInfo->NbPrisms();
3215 return _impl->NbPrisms();
3218 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3220 Unexpect aCatch(SALOME_SalomeException);
3222 return _preMeshInfo->NbHexPrisms();
3224 return _impl->NbHexagonalPrisms();
3227 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3229 Unexpect aCatch(SALOME_SalomeException);
3231 return _preMeshInfo->NbPolyhedrons();
3233 return _impl->NbPolyhedrons();
3236 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3237 throw(SALOME::SALOME_Exception)
3239 Unexpect aCatch(SALOME_SalomeException);
3241 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3243 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3246 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3247 throw(SALOME::SALOME_Exception)
3249 Unexpect aCatch(SALOME_SalomeException);
3251 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3253 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3256 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3257 throw(SALOME::SALOME_Exception)
3259 Unexpect aCatch(SALOME_SalomeException);
3261 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3263 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3266 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3267 throw(SALOME::SALOME_Exception)
3269 Unexpect aCatch(SALOME_SalomeException);
3271 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3273 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3276 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3277 throw(SALOME::SALOME_Exception)
3279 Unexpect aCatch(SALOME_SalomeException);
3281 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3283 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3286 //=============================================================================
3288 * Returns nb of published sub-meshes
3290 //=============================================================================
3292 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3294 Unexpect aCatch(SALOME_SalomeException);
3295 return _mapSubMesh_i.size();
3298 //=============================================================================
3300 * Dumps mesh into a string
3302 //=============================================================================
3304 char* SMESH_Mesh_i::Dump()
3308 return CORBA::string_dup( os.str().c_str() );
3311 //=============================================================================
3313 * Method of SMESH_IDSource interface
3315 //=============================================================================
3317 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3319 return GetElementsId();
3322 //=============================================================================
3324 * Returns ids of all elements
3326 //=============================================================================
3328 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3329 throw (SALOME::SALOME_Exception)
3331 Unexpect aCatch(SALOME_SalomeException);
3333 _preMeshInfo->FullLoadFromFile();
3335 SMESH::long_array_var aResult = new SMESH::long_array();
3336 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3338 if ( aSMESHDS_Mesh == NULL )
3339 return aResult._retn();
3341 long nbElements = NbElements();
3342 aResult->length( nbElements );
3343 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3344 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3345 aResult[i] = anIt->next()->GetID();
3347 return aResult._retn();
3351 //=============================================================================
3353 * Returns ids of all elements of given type
3355 //=============================================================================
3357 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3358 throw (SALOME::SALOME_Exception)
3360 Unexpect aCatch(SALOME_SalomeException);
3362 _preMeshInfo->FullLoadFromFile();
3364 SMESH::long_array_var aResult = new SMESH::long_array();
3365 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3367 if ( aSMESHDS_Mesh == NULL )
3368 return aResult._retn();
3370 long nbElements = NbElements();
3372 // No sense in returning ids of elements along with ids of nodes:
3373 // when theElemType == SMESH::ALL, return node ids only if
3374 // there are no elements
3375 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3376 return GetNodesId();
3378 aResult->length( nbElements );
3382 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3383 while ( i < nbElements && anIt->more() ) {
3384 const SMDS_MeshElement* anElem = anIt->next();
3385 if ( theElemType == SMESH::ALL || anElem->GetType() == (SMDSAbs_ElementType)theElemType )
3386 aResult[i++] = anElem->GetID();
3389 aResult->length( i );
3391 return aResult._retn();
3394 //=============================================================================
3396 * Returns ids of all nodes
3398 //=============================================================================
3400 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3401 throw (SALOME::SALOME_Exception)
3403 Unexpect aCatch(SALOME_SalomeException);
3405 _preMeshInfo->FullLoadFromFile();
3407 SMESH::long_array_var aResult = new SMESH::long_array();
3408 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3410 if ( aSMESHDS_Mesh == NULL )
3411 return aResult._retn();
3413 long nbNodes = NbNodes();
3414 aResult->length( nbNodes );
3415 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3416 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3417 aResult[i] = anIt->next()->GetID();
3419 return aResult._retn();
3422 //=============================================================================
3426 //=============================================================================
3428 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3429 throw (SALOME::SALOME_Exception)
3432 _preMeshInfo->FullLoadFromFile();
3434 return ( SMESH::ElementType )_impl->GetElementType( id, iselem );
3437 //=============================================================================
3441 //=============================================================================
3443 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3444 throw (SALOME::SALOME_Exception)
3447 _preMeshInfo->FullLoadFromFile();
3449 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3451 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3453 return ( SMESH::EntityType ) e->GetEntityType();
3456 //=============================================================================
3458 * Returns ID of elements for given submesh
3460 //=============================================================================
3461 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3462 throw (SALOME::SALOME_Exception)
3465 _preMeshInfo->FullLoadFromFile();
3467 SMESH::long_array_var aResult = new SMESH::long_array();
3469 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3470 if(!SM) return aResult._retn();
3472 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3473 if(!SDSM) return aResult._retn();
3475 aResult->length(SDSM->NbElements());
3477 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3479 while ( eIt->more() ) {
3480 aResult[i++] = eIt->next()->GetID();
3483 return aResult._retn();
3487 //=============================================================================
3489 * Returns ID of nodes for given submesh
3490 * If param all==true - returns all nodes, else -
3491 * returns only nodes on shapes.
3493 //=============================================================================
3494 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3496 throw (SALOME::SALOME_Exception)
3499 _preMeshInfo->FullLoadFromFile();
3501 SMESH::long_array_var aResult = new SMESH::long_array();
3503 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3504 if(!SM) return aResult._retn();
3506 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3507 if(!SDSM) return aResult._retn();
3510 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
3511 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
3512 while ( nIt->more() ) {
3513 const SMDS_MeshNode* elem = nIt->next();
3514 theElems.insert( elem->GetID() );
3517 else { // all nodes of submesh elements
3518 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3519 while ( eIt->more() ) {
3520 const SMDS_MeshElement* anElem = eIt->next();
3521 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
3522 while ( nIt->more() ) {
3523 const SMDS_MeshElement* elem = nIt->next();
3524 theElems.insert( elem->GetID() );
3529 aResult->length(theElems.size());
3530 set<int>::iterator itElem;
3532 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
3533 aResult[i++] = *itElem;
3535 return aResult._retn();
3538 //=============================================================================
3540 * Returns type of elements for given submesh
3542 //=============================================================================
3544 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
3545 throw (SALOME::SALOME_Exception)
3548 _preMeshInfo->FullLoadFromFile();
3550 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3551 if(!SM) return SMESH::ALL;
3553 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3554 if(!SDSM) return SMESH::ALL;
3556 if(SDSM->NbElements()==0)
3557 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
3559 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3560 const SMDS_MeshElement* anElem = eIt->next();
3561 return ( SMESH::ElementType ) anElem->GetType();
3565 //=============================================================================
3567 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
3569 //=============================================================================
3571 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
3574 _preMeshInfo->FullLoadFromFile();
3576 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
3578 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
3583 //=============================================================================
3585 * Get XYZ coordinates of node as list of double
3586 * If there is not node for given ID - returns empty list
3588 //=============================================================================
3590 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
3593 _preMeshInfo->FullLoadFromFile();
3595 SMESH::double_array_var aResult = new SMESH::double_array();
3596 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3597 if ( aSMESHDS_Mesh == NULL )
3598 return aResult._retn();
3601 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3603 return aResult._retn();
3607 aResult[0] = aNode->X();
3608 aResult[1] = aNode->Y();
3609 aResult[2] = aNode->Z();
3610 return aResult._retn();
3614 //=============================================================================
3616 * For given node returns list of IDs of inverse elements
3617 * If there is not node for given ID - returns empty list
3619 //=============================================================================
3621 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
3624 _preMeshInfo->FullLoadFromFile();
3626 SMESH::long_array_var aResult = new SMESH::long_array();
3627 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3628 if ( aSMESHDS_Mesh == NULL )
3629 return aResult._retn();
3632 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3634 return aResult._retn();
3636 // find inverse elements
3637 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
3638 TColStd_SequenceOfInteger IDs;
3639 while(eIt->more()) {
3640 const SMDS_MeshElement* elem = eIt->next();
3641 IDs.Append(elem->GetID());
3643 if(IDs.Length()>0) {
3644 aResult->length(IDs.Length());
3646 for(; i<=IDs.Length(); i++) {
3647 aResult[i-1] = IDs.Value(i);
3650 return aResult._retn();
3653 //=============================================================================
3655 * \brief Return position of a node on shape
3657 //=============================================================================
3659 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
3662 _preMeshInfo->FullLoadFromFile();
3664 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
3665 aNodePosition->shapeID = 0;
3666 aNodePosition->shapeType = GEOM::SHAPE;
3668 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
3669 if ( !mesh ) return aNodePosition;
3671 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
3673 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
3675 aNodePosition->shapeID = aNode->getshapeId();
3676 switch ( pos->GetTypeOfPosition() ) {
3678 aNodePosition->shapeType = GEOM::EDGE;
3679 aNodePosition->params.length(1);
3680 aNodePosition->params[0] =
3681 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
3684 aNodePosition->shapeType = GEOM::FACE;
3685 aNodePosition->params.length(2);
3686 aNodePosition->params[0] =
3687 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
3688 aNodePosition->params[1] =
3689 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
3691 case SMDS_TOP_VERTEX:
3692 aNodePosition->shapeType = GEOM::VERTEX;
3694 case SMDS_TOP_3DSPACE:
3695 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
3696 aNodePosition->shapeType = GEOM::SOLID;
3697 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
3698 aNodePosition->shapeType = GEOM::SHELL;
3704 return aNodePosition;
3707 //=============================================================================
3709 * If given element is node returns IDs of shape from position
3710 * If there is not node for given ID - returns -1
3712 //=============================================================================
3714 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
3717 _preMeshInfo->FullLoadFromFile();
3719 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3720 if ( aSMESHDS_Mesh == NULL )
3724 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
3726 return aNode->getshapeId();
3733 //=============================================================================
3735 * For given element returns ID of result shape after
3736 * ::FindShape() from SMESH_MeshEditor
3737 * If there is not element for given ID - returns -1
3739 //=============================================================================
3741 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
3744 _preMeshInfo->FullLoadFromFile();
3746 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3747 if ( aSMESHDS_Mesh == NULL )
3750 // try to find element
3751 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3755 ::SMESH_MeshEditor aMeshEditor(_impl);
3756 int index = aMeshEditor.FindShape( elem );
3764 //=============================================================================
3766 * Returns number of nodes for given element
3767 * If there is not element for given ID - returns -1
3769 //=============================================================================
3771 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
3774 _preMeshInfo->FullLoadFromFile();
3776 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3777 if ( aSMESHDS_Mesh == NULL ) return -1;
3778 // try to find element
3779 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3780 if(!elem) return -1;
3781 return elem->NbNodes();
3785 //=============================================================================
3787 * Returns ID of node by given index for given element
3788 * If there is not element for given ID - returns -1
3789 * If there is not node for given index - returns -2
3791 //=============================================================================
3793 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
3796 _preMeshInfo->FullLoadFromFile();
3798 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3799 if ( aSMESHDS_Mesh == NULL ) return -1;
3800 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3801 if(!elem) return -1;
3802 if( index>=elem->NbNodes() || index<0 ) return -1;
3803 return elem->GetNode(index)->GetID();
3806 //=============================================================================
3808 * Returns IDs of nodes of given element
3810 //=============================================================================
3812 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
3815 _preMeshInfo->FullLoadFromFile();
3817 SMESH::long_array_var aResult = new SMESH::long_array();
3818 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3820 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
3822 aResult->length( elem->NbNodes() );
3823 for ( int i = 0; i < elem->NbNodes(); ++i )
3824 aResult[ i ] = elem->GetNode( i )->GetID();
3827 return aResult._retn();
3830 //=============================================================================
3832 * Returns true if given node is medium node
3833 * in given quadratic element
3835 //=============================================================================
3837 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
3840 _preMeshInfo->FullLoadFromFile();
3842 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3843 if ( aSMESHDS_Mesh == NULL ) return false;
3845 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3846 if(!aNode) return false;
3847 // try to find element
3848 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
3849 if(!elem) return false;
3851 return elem->IsMediumNode(aNode);
3855 //=============================================================================
3857 * Returns true if given node is medium node
3858 * in one of quadratic elements
3860 //=============================================================================
3862 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
3863 SMESH::ElementType theElemType)
3866 _preMeshInfo->FullLoadFromFile();
3868 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3869 if ( aSMESHDS_Mesh == NULL ) return false;
3872 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
3873 if(!aNode) return false;
3875 SMESH_MesherHelper aHelper( *(_impl) );
3877 SMDSAbs_ElementType aType;
3878 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
3879 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
3880 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
3881 else aType = SMDSAbs_All;
3883 return aHelper.IsMedium(aNode,aType);
3887 //=============================================================================
3889 * Returns number of edges for given element
3891 //=============================================================================
3893 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
3896 _preMeshInfo->FullLoadFromFile();
3898 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3899 if ( aSMESHDS_Mesh == NULL ) return -1;
3900 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3901 if(!elem) return -1;
3902 return elem->NbEdges();
3906 //=============================================================================
3908 * Returns number of faces for given element
3910 //=============================================================================
3912 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
3915 _preMeshInfo->FullLoadFromFile();
3917 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3918 if ( aSMESHDS_Mesh == NULL ) return -1;
3919 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3920 if(!elem) return -1;
3921 return elem->NbFaces();
3924 //=======================================================================
3925 //function : GetElemFaceNodes
3926 //purpose : Returns nodes of given face (counted from zero) for given element.
3927 //=======================================================================
3929 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
3930 CORBA::Short faceIndex)
3933 _preMeshInfo->FullLoadFromFile();
3935 SMESH::long_array_var aResult = new SMESH::long_array();
3936 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
3938 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
3940 SMDS_VolumeTool vtool( elem );
3941 if ( faceIndex < vtool.NbFaces() )
3943 aResult->length( vtool.NbFaceNodes( faceIndex ));
3944 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
3945 for ( int i = 0; i < aResult->length(); ++i )
3946 aResult[ i ] = nn[ i ]->GetID();
3950 return aResult._retn();
3953 //=======================================================================
3954 //function : FindElementByNodes
3955 //purpose : Returns an element based on all given nodes.
3956 //=======================================================================
3958 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
3961 _preMeshInfo->FullLoadFromFile();
3963 CORBA::Long elemID(0);
3964 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
3966 vector< const SMDS_MeshNode * > nn( nodes.length() );
3967 for ( int i = 0; i < nodes.length(); ++i )
3968 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
3971 const SMDS_MeshElement* elem = mesh->FindElement( nn );
3972 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
3973 _impl->NbFaces ( ORDER_QUADRATIC ) ||
3974 _impl->NbVolumes( ORDER_QUADRATIC )))
3975 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
3977 if ( elem ) elemID = CORBA::Long( elem->GetID() );
3982 //=============================================================================
3984 * Returns true if given element is polygon
3986 //=============================================================================
3988 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
3991 _preMeshInfo->FullLoadFromFile();
3993 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3994 if ( aSMESHDS_Mesh == NULL ) return false;
3995 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
3996 if(!elem) return false;
3997 return elem->IsPoly();
4001 //=============================================================================
4003 * Returns true if given element is quadratic
4005 //=============================================================================
4007 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4010 _preMeshInfo->FullLoadFromFile();
4012 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4013 if ( aSMESHDS_Mesh == NULL ) return false;
4014 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4015 if(!elem) return false;
4016 return elem->IsQuadratic();
4019 //=============================================================================
4021 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4023 //=============================================================================
4025 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4028 _preMeshInfo->FullLoadFromFile();
4030 if ( const SMDS_BallElement* ball =
4031 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4032 return ball->GetDiameter();
4037 //=============================================================================
4039 * Returns bary center for given element
4041 //=============================================================================
4043 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4046 _preMeshInfo->FullLoadFromFile();
4048 SMESH::double_array_var aResult = new SMESH::double_array();
4049 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4050 if ( aSMESHDS_Mesh == NULL )
4051 return aResult._retn();
4053 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4055 return aResult._retn();
4057 if(elem->GetType()==SMDSAbs_Volume) {
4058 SMDS_VolumeTool aTool;
4059 if(aTool.Set(elem)) {
4061 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4066 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4068 double x=0., y=0., z=0.;
4069 for(; anIt->more(); ) {
4071 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4085 return aResult._retn();
4089 //=============================================================================
4091 * Create and publish group servants if any groups were imported or created anyhow
4093 //=============================================================================
4095 void SMESH_Mesh_i::CreateGroupServants()
4097 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4100 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4101 while ( groupIt->more() )
4103 ::SMESH_Group* group = groupIt->next();
4104 int anId = group->GetGroupDS()->GetID();
4106 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4107 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4109 addedIDs.insert( anId );
4111 SMESH_GroupBase_i* aGroupImpl;
4113 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4114 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4116 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4117 shape = groupOnGeom->GetShape();
4120 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4123 SMESH::SMESH_GroupBase_var groupVar =
4124 SMESH::SMESH_GroupBase::_narrow( aGroupImpl->_this() );
4125 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4127 // register CORBA object for persistence
4128 int nextId = _gen_i->RegisterObject( groupVar );
4129 if(MYDEBUG) MESSAGE( "Add group to map with id = "<< nextId);
4131 // publishing the groups in the study
4132 if ( !aStudy->_is_nil() ) {
4133 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4134 _gen_i->PublishGroup( aStudy, _this(), groupVar, shapeVar, groupVar->GetName());
4137 if ( !addedIDs.empty() )
4140 set<int>::iterator id = addedIDs.begin();
4141 for ( ; id != addedIDs.end(); ++id )
4143 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4144 int i = std::distance( _mapGroups.begin(), it );
4145 TPythonDump() << it->second << " = " << _this() << ".GetGroups()[ "<< i << " ]";
4150 //=============================================================================
4152 * \brief Return groups cantained in _mapGroups by their IDs
4154 //=============================================================================
4156 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4158 int nbGroups = groupIDs.size();
4159 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4160 aList->length( nbGroups );
4162 list<int>::const_iterator ids = groupIDs.begin();
4163 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4165 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4166 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4167 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4169 aList->length( nbGroups );
4170 return aList._retn();
4173 //=============================================================================
4175 * \brief Return information about imported file
4177 //=============================================================================
4179 SALOME_MED::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4181 SALOME_MED::MedFileInfo_var res( _medFileInfo );
4182 if ( !res.operator->() ) {
4183 res = new SALOME_MED::MedFileInfo;
4185 res->fileSize = res->major = res->minor = res->release = -1;
4190 //=============================================================================
4192 * \brief Pass names of mesh groups from study to mesh DS
4194 //=============================================================================
4196 void SMESH_Mesh_i::checkGroupNames()
4198 int nbGrp = NbGroups();
4202 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4203 if ( aStudy->_is_nil() )
4204 return; // nothing to do
4206 SMESH::ListOfGroups* grpList = 0;
4207 // avoid dump of "GetGroups"
4209 // store python dump into a local variable inside local scope
4210 SMESH::TPythonDump pDump; // do not delete this line of code
4211 grpList = GetGroups();
4214 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4215 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4218 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4219 if ( aGrpSO->_is_nil() )
4221 // correct name of the mesh group if necessary
4222 const char* guiName = aGrpSO->GetName();
4223 if ( strcmp(guiName, aGrp->GetName()) )
4224 aGrp->SetName( guiName );
4228 //=============================================================================
4230 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4232 //=============================================================================
4233 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4235 // SMESH_Gen_i::GetSMESHGen()->UpdateParameters(SMESH::SMESH_Mesh::_narrow(_this()),
4236 // CORBA::string_dup(theParameters));
4237 SMESH_Gen_i::GetSMESHGen()->UpdateParameters(theParameters);
4240 //=============================================================================
4242 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4244 //=============================================================================
4245 char* SMESH_Mesh_i::GetParameters()
4247 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4248 return CORBA::string_dup(gen->GetParameters(SMESH::SMESH_Mesh::_narrow(_this())));
4251 //=============================================================================
4253 * \brief Returns list of notebook variables used for last Mesh operation
4255 //=============================================================================
4256 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4258 SMESH::string_array_var aResult = new SMESH::string_array();
4259 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4261 char *aParameters = GetParameters();
4262 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4263 if(!aStudy->_is_nil()) {
4264 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4265 if(aSections->length() > 0) {
4266 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4267 aResult->length(aVars.length());
4268 for(int i = 0;i < aVars.length();i++)
4269 aResult[i] = CORBA::string_dup( aVars[i]);
4273 return aResult._retn();
4276 //=======================================================================
4277 //function : GetTypes
4278 //purpose : Returns types of elements it contains
4279 //=======================================================================
4281 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4284 return _preMeshInfo->GetTypes();
4286 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4290 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4291 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4292 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4293 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4294 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4295 types->length( nbTypes );
4297 return types._retn();
4300 //=======================================================================
4301 //function : GetMesh
4302 //purpose : Returns self
4303 //=======================================================================
4305 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4307 return SMESH::SMESH_Mesh::_duplicate( _this() );
4310 //=======================================================================
4311 //function : IsMeshInfoCorrect
4312 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4313 // * happen if mesh data is not yet fully loaded from the file of study.
4314 //=======================================================================
4316 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4318 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4321 //=============================================================================
4323 * \brief Returns statistic of mesh elements
4325 //=============================================================================
4327 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4330 return _preMeshInfo->GetMeshInfo();
4332 SMESH::long_array_var aRes = new SMESH::long_array();
4333 aRes->length(SMESH::Entity_Last);
4334 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4336 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4338 return aRes._retn();
4339 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
4340 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
4341 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
4342 return aRes._retn();
4345 //=============================================================================
4347 * \brief Collect statistic of mesh elements given by iterator
4349 //=============================================================================
4351 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
4352 SMESH::long_array& theInfo)
4354 if (!theItr) return;
4355 while (theItr->more())
4356 theInfo[ theItr->next()->GetEntityType() ]++;
4359 //=============================================================================
4360 namespace // Finding concurrent hypotheses
4361 //=============================================================================
4365 * \brief mapping of mesh dimension into shape type
4367 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
4369 TopAbs_ShapeEnum aType = TopAbs_SOLID;
4371 case 0: aType = TopAbs_VERTEX; break;
4372 case 1: aType = TopAbs_EDGE; break;
4373 case 2: aType = TopAbs_FACE; break;
4375 default:aType = TopAbs_SOLID; break;
4380 //-----------------------------------------------------------------------------
4382 * \brief Internal structure used to find concurent submeshes
4384 * It represents a pair < submesh, concurent dimension >, where
4385 * 'concurrent dimension' is dimension of shape where the submesh can concurent
4386 * with another submesh. In other words, it is dimension of a hypothesis assigned
4393 int _dim; //!< a dimension the algo can build (concurrent dimension)
4394 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
4395 TopTools_MapOfShape _shapeMap;
4396 SMESH_subMesh* _subMesh;
4397 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
4399 //-----------------------------------------------------------------------------
4400 // Return the algorithm
4401 const SMESH_Algo* GetAlgo() const
4402 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
4404 //-----------------------------------------------------------------------------
4406 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
4408 const TopoDS_Shape& theShape)
4410 _subMesh = (SMESH_subMesh*)theSubMesh;
4411 SetShape( theDim, theShape );
4414 //-----------------------------------------------------------------------------
4416 void SetShape(const int theDim,
4417 const TopoDS_Shape& theShape)
4420 _ownDim = (int)SMESH_Gen::GetShapeDim(theShape);
4421 if (_dim >= _ownDim)
4422 _shapeMap.Add( theShape );
4424 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
4425 for( ; anExp.More(); anExp.Next() )
4426 _shapeMap.Add( anExp.Current() );
4430 //-----------------------------------------------------------------------------
4431 //! Check sharing of sub-shapes
4432 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
4433 const TopTools_MapOfShape& theToFind,
4434 const TopAbs_ShapeEnum theType)
4436 bool isShared = false;
4437 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
4438 for (; !isShared && anItr.More(); anItr.Next() )
4440 const TopoDS_Shape aSubSh = anItr.Key();
4441 // check for case when concurrent dimensions are same
4442 isShared = theToFind.Contains( aSubSh );
4443 // check for sub-shape with concurrent dimension
4444 TopExp_Explorer anExp( aSubSh, theType );
4445 for ( ; !isShared && anExp.More(); anExp.Next() )
4446 isShared = theToFind.Contains( anExp.Current() );
4451 //-----------------------------------------------------------------------------
4452 //! check algorithms
4453 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
4454 const SMESHDS_Hypothesis* theA2)
4456 if ( !theA1 || !theA2 ||
4457 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
4458 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
4459 return false; // one of the hypothesis is not algorithm
4460 // check algorithm names (should be equal)
4461 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
4465 //-----------------------------------------------------------------------------
4466 //! Check if sub-shape hypotheses are concurrent
4467 bool IsConcurrent(const SMESH_DimHyp* theOther) const
4469 if ( _subMesh == theOther->_subMesh )
4470 return false; // same sub-shape - should not be
4472 // if ( <own dim of either of submeshes> == <concurrent dim> &&
4473 // any of the two submeshes is not on COMPOUND shape )
4474 // -> no concurrency
4475 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
4476 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
4477 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
4478 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
4479 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
4482 // bool checkSubShape = ( _dim >= theOther->_dim )
4483 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
4484 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
4485 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
4486 if ( !checkSubShape )
4489 // check algorithms to be same
4490 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
4491 return true; // different algorithms -> concurrency !
4493 // check hypothesises for concurrence (skip first as algorithm)
4495 // pointers should be same, because it is referened from mesh hypothesis partition
4496 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
4497 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
4498 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
4499 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
4501 // the submeshes are concurrent if their algorithms has different parameters
4502 return nbSame != theOther->_hypotheses.size() - 1;
4505 // Return true if algorithm of this SMESH_DimHyp is used if no
4506 // sub-mesh order is imposed by the user
4507 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
4509 // NeedDiscreteBoundary() algo has a higher priority
4510 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
4511 theOther->GetAlgo()->NeedDiscreteBoundary() )
4512 return !this->GetAlgo()->NeedDiscreteBoundary();
4514 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
4517 }; // end of SMESH_DimHyp
4518 //-----------------------------------------------------------------------------
4520 typedef list<const SMESH_DimHyp*> TDimHypList;
4522 //-----------------------------------------------------------------------------
4524 void addDimHypInstance(const int theDim,
4525 const TopoDS_Shape& theShape,
4526 const SMESH_Algo* theAlgo,
4527 const SMESH_subMesh* theSubMesh,
4528 const list <const SMESHDS_Hypothesis*>& theHypList,
4529 TDimHypList* theDimHypListArr )
4531 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
4532 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
4533 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
4534 dimHyp->_hypotheses.push_front(theAlgo);
4535 listOfdimHyp.push_back( dimHyp );
4538 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
4539 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
4540 theHypList.begin(), theHypList.end() );
4543 //-----------------------------------------------------------------------------
4544 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
4545 TDimHypList& theListOfConcurr)
4547 if ( theListOfConcurr.empty() )
4549 theListOfConcurr.push_back( theDimHyp );
4553 TDimHypList::iterator hypIt = theListOfConcurr.begin();
4554 while ( hypIt != theListOfConcurr.end() &&
4555 !theDimHyp->IsHigherPriorityThan( *hypIt ))
4557 theListOfConcurr.insert( hypIt, theDimHyp );
4561 //-----------------------------------------------------------------------------
4562 void findConcurrents(const SMESH_DimHyp* theDimHyp,
4563 const TDimHypList& theListOfDimHyp,
4564 TDimHypList& theListOfConcurrHyp,
4565 set<int>& theSetOfConcurrId )
4567 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
4568 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
4570 const SMESH_DimHyp* curDimHyp = *rIt;
4571 if ( curDimHyp == theDimHyp )
4572 break; // meet own dimHyp pointer in same dimension
4574 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
4575 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
4577 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
4582 //-----------------------------------------------------------------------------
4583 void unionLists(TListOfInt& theListOfId,
4584 TListOfListOfInt& theListOfListOfId,
4587 TListOfListOfInt::iterator it = theListOfListOfId.begin();
4588 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
4590 continue; //skip already treated lists
4591 // check if other list has any same submesh object
4592 TListOfInt& otherListOfId = *it;
4593 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
4594 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
4597 // union two lists (from source into target)
4598 TListOfInt::iterator it2 = otherListOfId.begin();
4599 for ( ; it2 != otherListOfId.end(); it2++ ) {
4600 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
4601 theListOfId.push_back(*it2);
4603 // clear source list
4604 otherListOfId.clear();
4607 //-----------------------------------------------------------------------------
4609 //! free memory allocated for dimension-hypothesis objects
4610 void removeDimHyps( TDimHypList* theArrOfList )
4612 for (int i = 0; i < 4; i++ ) {
4613 TDimHypList& listOfdimHyp = theArrOfList[i];
4614 TDimHypList::const_iterator it = listOfdimHyp.begin();
4615 for ( ; it != listOfdimHyp.end(); it++ )
4620 //-----------------------------------------------------------------------------
4622 * \brief find common submeshes with given submesh
4623 * \param theSubMeshList list of already collected submesh to check
4624 * \param theSubMesh given submesh to intersect with other
4625 * \param theCommonSubMeshes collected common submeshes
4627 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
4628 const SMESH_subMesh* theSubMesh,
4629 set<const SMESH_subMesh*>& theCommon )
4633 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
4634 for ( ; it != theSubMeshList.end(); it++ )
4635 theSubMesh->FindIntersection( *it, theCommon );
4636 theSubMeshList.push_back( theSubMesh );
4637 //theCommon.insert( theSubMesh );
4642 //=============================================================================
4644 * \brief Return submesh objects list in meshing order
4646 //=============================================================================
4648 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
4650 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
4652 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4654 return aResult._retn();
4656 ::SMESH_Mesh& mesh = GetImpl();
4657 TListOfListOfInt anOrder = mesh.GetMeshOrder(); // is there already defined order?
4658 if ( !anOrder.size() ) {
4660 // collect submeshes and detect concurrent algorithms and hypothesises
4661 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
4663 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
4664 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
4665 ::SMESH_subMesh* sm = (*i_sm).second;
4667 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
4669 // list of assigned hypothesises
4670 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
4671 // Find out dimensions where the submesh can be concurrent.
4672 // We define the dimensions by algo of each of hypotheses in hypList
4673 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
4674 for( ; hypIt != hypList.end(); hypIt++ ) {
4675 SMESH_Algo* anAlgo = 0;
4676 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
4677 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
4678 // hyp it-self is algo
4679 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
4681 // try to find algorithm with help of sub-shapes
4682 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
4683 for ( ; !anAlgo && anExp.More(); anExp.Next() )
4684 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
4687 continue; // no algorithm assigned to a current submesh
4689 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
4690 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
4692 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
4693 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
4694 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
4696 } // end iterations on submesh
4698 // iterate on created dimension-hypotheses and check for concurrents
4699 for ( int i = 0; i < 4; i++ ) {
4700 const TDimHypList& listOfDimHyp = dimHypListArr[i];
4701 // check for concurrents in own and other dimensions (step-by-step)
4702 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
4703 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
4704 const SMESH_DimHyp* dimHyp = *dhIt;
4705 TDimHypList listOfConcurr;
4706 set<int> setOfConcurrIds;
4707 // looking for concurrents and collect into own list
4708 for ( int j = i; j < 4; j++ )
4709 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
4710 // check if any concurrents found
4711 if ( listOfConcurr.size() > 0 ) {
4712 // add own submesh to list of concurrent
4713 addInOrderOfPriority( dimHyp, listOfConcurr );
4714 list<int> listOfConcurrIds;
4715 TDimHypList::iterator hypIt = listOfConcurr.begin();
4716 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
4717 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
4718 anOrder.push_back( listOfConcurrIds );
4723 removeDimHyps(dimHypListArr);
4725 // now, minimise the number of concurrent groups
4726 // Here we assume that lists of submeshes can have same submesh
4727 // in case of multi-dimension algorithms, as result
4728 // list with common submesh has to be united into one list
4730 TListOfListOfInt::iterator listIt = anOrder.begin();
4731 for(; listIt != anOrder.end(); listIt++, listIndx++ )
4732 unionLists( *listIt, anOrder, listIndx + 1 );
4734 // convert submesh ids into interface instances
4735 // and dump command into python
4736 convertMeshOrder( anOrder, aResult, false );
4738 return aResult._retn();
4741 //=============================================================================
4743 * \brief Set submesh object order
4744 * \param theSubMeshArray submesh array order
4746 //=============================================================================
4748 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
4751 _preMeshInfo->ForgetOrLoad();
4754 ::SMESH_Mesh& mesh = GetImpl();
4756 TPythonDump aPythonDump; // prevent dump of called methods
4757 aPythonDump << "isDone = " << _this() << ".SetMeshOrder( [ ";
4759 TListOfListOfInt subMeshOrder;
4760 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
4762 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
4763 TListOfInt subMeshIds;
4764 aPythonDump << "[ ";
4765 // Collect subMeshes which should be clear
4766 // do it list-by-list, because modification of submesh order
4767 // take effect between concurrent submeshes only
4768 set<const SMESH_subMesh*> subMeshToClear;
4769 list<const SMESH_subMesh*> subMeshList;
4770 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
4772 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
4774 aPythonDump << ", ";
4775 aPythonDump << subMesh;
4776 subMeshIds.push_back( subMesh->GetId() );
4777 // detect common parts of submeshes
4778 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
4779 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
4781 aPythonDump << " ]";
4782 subMeshOrder.push_back( subMeshIds );
4784 // clear collected submeshes
4785 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
4786 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
4787 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
4788 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
4790 aPythonDump << " ])";
4792 mesh.SetMeshOrder( subMeshOrder );
4798 //=============================================================================
4800 * \brief Convert submesh ids into submesh interfaces
4802 //=============================================================================
4804 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
4805 SMESH::submesh_array_array& theResOrder,
4806 const bool theIsDump)
4808 int nbSet = theIdsOrder.size();
4809 TPythonDump aPythonDump; // prevent dump of called methods
4811 aPythonDump << "[ ";
4812 theResOrder.length(nbSet);
4813 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
4815 for( ; it != theIdsOrder.end(); it++ ) {
4816 // translate submesh identificators into submesh objects
4817 // takeing into account real number of concurrent lists
4818 const TListOfInt& aSubOrder = (*it);
4819 if (!aSubOrder.size())
4822 aPythonDump << "[ ";
4823 // convert shape indeces into interfaces
4824 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
4825 aResSubSet->length(aSubOrder.size());
4826 TListOfInt::const_iterator subIt = aSubOrder.begin();
4827 for( int j = 0; subIt != aSubOrder.end(); subIt++ ) {
4828 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
4830 SMESH::SMESH_subMesh_var subMesh =
4831 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
4834 aPythonDump << ", ";
4835 aPythonDump << subMesh;
4837 aResSubSet[ j++ ] = subMesh;
4840 aPythonDump << " ]";
4841 theResOrder[ listIndx++ ] = aResSubSet;
4843 // correct number of lists
4844 theResOrder.length( listIndx );
4847 // finilise python dump
4848 aPythonDump << " ]";
4849 aPythonDump << " = " << _this() << ".GetMeshOrder()";
4853 //================================================================================
4855 // Implementation of SMESH_MeshPartDS
4857 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
4858 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
4860 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
4861 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
4863 _meshDS = mesh_i->GetImpl().GetMeshDS();
4865 SetPersistentId( _meshDS->GetPersistentId() );
4867 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
4869 // <meshPart> is the whole mesh
4870 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
4872 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
4873 myGroupSet = _meshDS->GetGroups();
4878 SMESH::long_array_var anIDs = meshPart->GetIDs();
4879 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
4880 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
4882 for (int i=0; i < anIDs->length(); i++)
4883 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
4884 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4889 for (int i=0; i < anIDs->length(); i++)
4890 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
4891 if ( _elements[ e->GetType() ].insert( e ).second )
4894 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4895 while ( nIt->more() )
4897 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4898 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4905 _meshDS = 0; // to enforce iteration on _elements and _nodes
4908 // -------------------------------------------------------------------------------------
4909 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
4910 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
4913 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
4914 for ( ; partIt != meshPart.end(); ++partIt )
4915 if ( const SMDS_MeshElement * e = *partIt )
4916 if ( _elements[ e->GetType() ].insert( e ).second )
4919 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
4920 while ( nIt->more() )
4922 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
4923 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
4929 // -------------------------------------------------------------------------------------
4930 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
4932 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
4934 typedef SMDS_SetIterator
4935 <const SMDS_MeshElement*,
4936 TIDSortedElemSet::const_iterator,
4937 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4938 SMDS_MeshElement::GeomFilter
4941 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
4943 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4944 _elements[type].end(),
4945 SMDS_MeshElement::GeomFilter( geomType )));
4947 // -------------------------------------------------------------------------------------
4948 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
4950 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
4952 typedef SMDS_SetIterator
4953 <const SMDS_MeshElement*,
4954 TIDSortedElemSet::const_iterator,
4955 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
4956 SMDS_MeshElement::EntityFilter
4959 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
4961 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
4962 _elements[type].end(),
4963 SMDS_MeshElement::EntityFilter( entity )));
4965 // -------------------------------------------------------------------------------------
4966 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
4968 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
4969 if ( type == SMDSAbs_All && !_meshDS )
4971 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
4973 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4974 if ( !_elements[i].empty() && i != SMDSAbs_Node )
4976 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
4978 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
4979 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
4981 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
4982 ( new TIter( _elements[type].begin(), _elements[type].end() ));
4984 // -------------------------------------------------------------------------------------
4985 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
4986 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
4988 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
4989 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
4990 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
4992 // -------------------------------------------------------------------------------------
4993 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
4994 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
4995 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
4996 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
4997 #undef _GET_ITER_DEFINE
4999 // END Implementation of SMESH_MeshPartDS
5001 //================================================================================