1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 : SALOME::GenericObj_i( thePOA )
114 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cached shapes if no more meshes remain; (the cache is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
243 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
244 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
250 catch(SALOME_Exception & S_ex) {
251 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
253 return aShapeObj._retn();
256 //================================================================================
258 * \brief Return false if the mesh is not yet fully loaded from the study file
260 //================================================================================
262 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
265 return !_preMeshInfo;
268 //================================================================================
270 * \brief Load full mesh data from the study file
272 //================================================================================
274 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->FullLoadFromFile();
281 //================================================================================
283 * \brief Remove all nodes and elements
285 //================================================================================
287 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
295 //CheckGeomGroupModif(); // issue 20145
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
301 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
303 SMESH::SMESH_Mesh_var mesh = _this();
304 _gen_i->UpdateIcons( mesh );
307 //================================================================================
309 * \brief Remove all nodes and elements for indicated shape
311 //================================================================================
313 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
314 throw (SALOME::SALOME_Exception)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Imports mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
393 throw ( SALOME::SALOME_Exception )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 major = minor = release = 0;
411 MED::GetMEDVersion(theFileName, major, minor, release);
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Imports mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
432 throw ( SALOME::SALOME_Exception )
434 Unexpect aCatch(SALOME_SalomeException);
437 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
439 catch( SALOME_Exception& S_ex ) {
440 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
446 CreateGroupServants();
448 return ConvertDriverMEDReadStatus(status);
451 //================================================================================
453 * \brief Return string representation of a MED file version comprising nbDigits
455 //================================================================================
457 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
459 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
461 return CORBA::string_dup( ver.c_str() );
464 //=============================================================================
468 * Imports mesh data from MED file
470 //=============================================================================
472 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
473 throw ( SALOME::SALOME_Exception )
477 // Read mesh with name = <theMeshName> into SMESH_Mesh
478 _impl->UNVToMesh( theFileName );
480 CreateGroupServants();
482 SMESH_CATCH( SMESH::throwCorbaException );
487 //=============================================================================
491 * Imports mesh data from STL file
493 //=============================================================================
494 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
495 throw ( SALOME::SALOME_Exception )
499 // Read mesh with name = <theMeshName> into SMESH_Mesh
500 std::string name = _impl->STLToMesh( theFileName );
503 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
504 _gen_i->SetName( meshSO, name.c_str() );
507 SMESH_CATCH( SMESH::throwCorbaException );
512 //================================================================================
514 * \brief Function used in SMESH_CATCH by ImportGMFFile()
516 //================================================================================
520 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
522 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
526 //================================================================================
528 * \brief Imports data from a GMF file and returns an error description
530 //================================================================================
532 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
533 bool theMakeRequiredGroups )
534 throw (SALOME::SALOME_Exception)
536 SMESH_ComputeErrorPtr error;
539 #define SMESH_CAUGHT error =
542 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
544 SMESH_CATCH( exceptionToComputeError );
548 CreateGroupServants();
550 return ConvertComputeError( error );
553 //=============================================================================
557 //=============================================================================
559 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
561 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
562 (SMESH_Hypothesis::Hypothesis_Status theStatus)
565 RETURNCASE( HYP_OK );
566 RETURNCASE( HYP_MISSING );
567 RETURNCASE( HYP_CONCURRENT );
568 RETURNCASE( HYP_BAD_PARAMETER );
569 RETURNCASE( HYP_HIDDEN_ALGO );
570 RETURNCASE( HYP_HIDING_ALGO );
571 RETURNCASE( HYP_UNKNOWN_FATAL );
572 RETURNCASE( HYP_INCOMPATIBLE );
573 RETURNCASE( HYP_NOTCONFORM );
574 RETURNCASE( HYP_ALREADY_EXIST );
575 RETURNCASE( HYP_BAD_DIM );
576 RETURNCASE( HYP_BAD_SUBSHAPE );
577 RETURNCASE( HYP_BAD_GEOMETRY );
578 RETURNCASE( HYP_NEED_SHAPE );
579 RETURNCASE( HYP_INCOMPAT_HYPS );
582 return SMESH::HYP_UNKNOWN_FATAL;
585 //=============================================================================
589 * calls internal addHypothesis() and then adds a reference to <anHyp> under
590 * the SObject actually having a reference to <aSubShape>.
591 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
593 //=============================================================================
595 SMESH::Hypothesis_Status
596 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
597 SMESH::SMESH_Hypothesis_ptr anHyp,
598 CORBA::String_out anErrorText)
599 throw(SALOME::SALOME_Exception)
601 Unexpect aCatch(SALOME_SalomeException);
603 _preMeshInfo->ForgetOrLoad();
606 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
607 anErrorText = error.c_str();
609 SMESH::SMESH_Mesh_var mesh( _this() );
610 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
612 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
613 _gen_i->UpdateIcons( mesh );
615 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
617 // Update Python script
618 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
619 << aSubShape << ", " << anHyp << " )";
621 return ConvertHypothesisStatus(status);
624 //=============================================================================
628 //=============================================================================
630 SMESH_Hypothesis::Hypothesis_Status
631 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
632 SMESH::SMESH_Hypothesis_ptr anHyp,
633 std::string* anErrorText)
635 if(MYDEBUG) MESSAGE("addHypothesis");
637 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
638 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
640 if (CORBA::is_nil( anHyp ))
641 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
643 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
646 TopoDS_Shape myLocSubShape;
647 //use PseudoShape in case if mesh has no shape
649 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
651 myLocSubShape = _impl->GetShapeToMesh();
653 const int hypId = anHyp->GetId();
655 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
656 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
658 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
660 // assure there is a corresponding submesh
661 if ( !_impl->IsMainShape( myLocSubShape )) {
662 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
663 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
664 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
667 else if ( anErrorText )
669 *anErrorText = error;
672 catch(SALOME_Exception & S_ex)
674 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
679 //=============================================================================
683 //=============================================================================
685 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
686 SMESH::SMESH_Hypothesis_ptr anHyp)
687 throw(SALOME::SALOME_Exception)
689 Unexpect aCatch(SALOME_SalomeException);
691 _preMeshInfo->ForgetOrLoad();
693 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
694 SMESH::SMESH_Mesh_var mesh = _this();
696 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
698 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
699 _gen_i->UpdateIcons( mesh );
701 // Update Python script
702 if(_impl->HasShapeToMesh())
703 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
704 << aSubShape << ", " << anHyp << " )";
706 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
709 return ConvertHypothesisStatus(status);
712 //=============================================================================
716 //=============================================================================
718 SMESH_Hypothesis::Hypothesis_Status
719 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
720 SMESH::SMESH_Hypothesis_ptr anHyp)
722 if(MYDEBUG) MESSAGE("removeHypothesis()");
724 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
725 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
727 if (CORBA::is_nil( anHyp ))
728 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
730 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
733 TopoDS_Shape myLocSubShape;
734 //use PseudoShape in case if mesh has no shape
735 if( _impl->HasShapeToMesh() )
736 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
738 myLocSubShape = _impl->GetShapeToMesh();
740 const int hypId = anHyp->GetId();
741 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
742 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
744 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
748 catch(SALOME_Exception & S_ex)
750 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
755 //=============================================================================
759 //=============================================================================
761 SMESH::ListOfHypothesis *
762 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
763 throw(SALOME::SALOME_Exception)
765 Unexpect aCatch(SALOME_SalomeException);
766 if (MYDEBUG) MESSAGE("GetHypothesisList");
767 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
768 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
770 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
773 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
774 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
775 myLocSubShape = _impl->GetShapeToMesh();
776 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
777 int i = 0, n = aLocalList.size();
780 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
781 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
782 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
784 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
785 if ( id_hypptr != _mapHypo.end() )
786 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
790 catch(SALOME_Exception & S_ex) {
791 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
794 return aList._retn();
797 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
799 Unexpect aCatch(SALOME_SalomeException);
800 if (MYDEBUG) MESSAGE("GetSubMeshes");
802 SMESH::submesh_array_var aList = new SMESH::submesh_array();
805 TPythonDump aPythonDump;
806 if ( !_mapSubMeshIor.empty() )
810 aList->length( _mapSubMeshIor.size() );
812 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
813 for ( ; it != _mapSubMeshIor.end(); it++ ) {
814 if ( CORBA::is_nil( it->second )) continue;
815 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
817 if (i > 1) aPythonDump << ", ";
818 aPythonDump << it->second;
822 catch(SALOME_Exception & S_ex) {
823 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
826 // Update Python script
827 if ( !_mapSubMeshIor.empty() )
828 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
830 return aList._retn();
833 //=============================================================================
837 //=============================================================================
839 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
840 const char* theName )
841 throw(SALOME::SALOME_Exception)
843 Unexpect aCatch(SALOME_SalomeException);
844 if (CORBA::is_nil(aSubShape))
845 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
847 SMESH::SMESH_subMesh_var subMesh;
848 SMESH::SMESH_Mesh_var aMesh = _this();
850 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
852 //Get or Create the SMESH_subMesh object implementation
854 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
856 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
858 TopoDS_Iterator it( myLocSubShape );
860 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
862 subMesh = getSubMesh( subMeshId );
864 // create a new subMesh object servant if there is none for the shape
865 if ( subMesh->_is_nil() )
866 subMesh = createSubMesh( aSubShape );
867 if ( _gen_i->CanPublishInStudy( subMesh ))
869 SALOMEDS::SObject_wrap aSO =
870 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
871 if ( !aSO->_is_nil()) {
872 // Update Python script
873 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
874 << aSubShape << ", '" << theName << "' )";
878 catch(SALOME_Exception & S_ex) {
879 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
881 return subMesh._retn();
884 //=============================================================================
888 //=============================================================================
890 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
891 throw (SALOME::SALOME_Exception)
895 if ( theSubMesh->_is_nil() )
898 GEOM::GEOM_Object_var aSubShape;
899 // Remove submesh's SObject
900 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
901 if ( !anSO->_is_nil() ) {
902 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
903 SALOMEDS::SObject_wrap anObj, aRef;
904 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
905 anObj->ReferencedObject( aRef.inout() ))
907 CORBA::Object_var obj = aRef->GetObject();
908 aSubShape = GEOM::GEOM_Object::_narrow( obj );
910 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
911 // aSubShape = theSubMesh->GetSubShape();
913 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
914 builder->RemoveObjectWithChildren( anSO );
916 // Update Python script
917 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
920 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
922 _preMeshInfo->ForgetOrLoad();
924 SMESH_CATCH( SMESH::throwCorbaException );
927 //=============================================================================
931 //=============================================================================
933 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
934 const char* theName )
935 throw(SALOME::SALOME_Exception)
937 Unexpect aCatch(SALOME_SalomeException);
939 _preMeshInfo->FullLoadFromFile();
941 SMESH::SMESH_Group_var aNewGroup =
942 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
944 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
946 SMESH::SMESH_Mesh_var mesh = _this();
947 SALOMEDS::SObject_wrap aSO =
948 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
949 if ( !aSO->_is_nil())
950 // Update Python script
951 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
952 << theElemType << ", '" << theName << "' )";
954 return aNewGroup._retn();
957 //=============================================================================
961 //=============================================================================
962 SMESH::SMESH_GroupOnGeom_ptr
963 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
965 GEOM::GEOM_Object_ptr theGeomObj)
966 throw(SALOME::SALOME_Exception)
968 Unexpect aCatch(SALOME_SalomeException);
970 _preMeshInfo->FullLoadFromFile();
972 SMESH::SMESH_GroupOnGeom_var aNewGroup;
974 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
975 if ( !aShape.IsNull() )
978 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
980 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
982 SMESH::SMESH_Mesh_var mesh = _this();
983 SALOMEDS::SObject_wrap aSO =
984 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
985 if ( !aSO->_is_nil())
986 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
987 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
991 return aNewGroup._retn();
994 //================================================================================
996 * \brief Creates a group whose contents is defined by filter
997 * \param theElemType - group type
998 * \param theName - group name
999 * \param theFilter - the filter
1000 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1002 //================================================================================
1004 SMESH::SMESH_GroupOnFilter_ptr
1005 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1006 const char* theName,
1007 SMESH::Filter_ptr theFilter )
1008 throw (SALOME::SALOME_Exception)
1010 Unexpect aCatch(SALOME_SalomeException);
1012 _preMeshInfo->FullLoadFromFile();
1014 if ( CORBA::is_nil( theFilter ))
1015 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1017 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1019 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1021 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1022 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1025 if ( !aNewGroup->_is_nil() )
1026 aNewGroup->SetFilter( theFilter );
1028 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1030 SMESH::SMESH_Mesh_var mesh = _this();
1031 SALOMEDS::SObject_wrap aSO =
1032 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1034 if ( !aSO->_is_nil())
1035 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1036 << theElemType << ", '" << theName << "', " << theFilter << " )";
1038 return aNewGroup._retn();
1041 //=============================================================================
1045 //=============================================================================
1047 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1048 throw (SALOME::SALOME_Exception)
1050 if ( theGroup->_is_nil() )
1055 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1059 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1060 if ( !aGroupSO->_is_nil() )
1062 // Update Python script
1063 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1065 // Remove group's SObject
1066 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1067 builder->RemoveObjectWithChildren( aGroupSO );
1069 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1071 // Remove the group from SMESH data structures
1072 removeGroup( aGroup->GetLocalID() );
1074 SMESH_CATCH( SMESH::throwCorbaException );
1077 //=============================================================================
1079 * Remove group with its contents
1081 //=============================================================================
1083 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1084 throw (SALOME::SALOME_Exception)
1088 _preMeshInfo->FullLoadFromFile();
1090 if ( theGroup->_is_nil() )
1093 vector<int> nodeIds; // to remove nodes becoming free
1094 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1095 if ( !isNodal && !theGroup->IsEmpty() )
1097 CORBA::Long elemID = theGroup->GetID( 1 );
1098 int nbElemNodes = GetElemNbNodes( elemID );
1099 if ( nbElemNodes > 0 )
1100 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1103 // Retrieve contents
1104 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1105 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1106 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1107 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1108 elems.assign( elemBeg, elemEnd );
1110 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1113 RemoveGroup( theGroup );
1116 for ( size_t i = 0; i < elems.size(); ++i )
1118 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1122 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1123 nodeIds.push_back( nIt->next()->GetID() );
1125 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1129 _impl->GetMeshDS()->RemoveElement( elems[i] );
1133 // Remove free nodes
1134 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1135 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1136 if ( n->NbInverseElements() == 0 )
1137 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1139 // Update Python script (theGroup must be alive for this)
1140 pyDump << SMESH::SMESH_Mesh_var(_this())
1141 << ".RemoveGroupWithContents( " << theGroup << " )";
1143 SMESH_CATCH( SMESH::throwCorbaException );
1146 //================================================================================
1148 * \brief Get the list of groups existing in the mesh
1149 * \retval SMESH::ListOfGroups * - list of groups
1151 //================================================================================
1153 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1155 Unexpect aCatch(SALOME_SalomeException);
1156 if (MYDEBUG) MESSAGE("GetGroups");
1158 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1161 TPythonDump aPythonDump;
1162 if ( !_mapGroups.empty() )
1164 aPythonDump << "[ ";
1166 aList->length( _mapGroups.size() );
1168 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1169 for ( ; it != _mapGroups.end(); it++ ) {
1170 if ( CORBA::is_nil( it->second )) continue;
1171 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1173 if (i > 1) aPythonDump << ", ";
1174 aPythonDump << it->second;
1178 catch(SALOME_Exception & S_ex) {
1179 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1181 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1183 return aList._retn();
1186 //=============================================================================
1188 * Get number of groups existing in the mesh
1190 //=============================================================================
1192 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1194 Unexpect aCatch(SALOME_SalomeException);
1195 return _mapGroups.size();
1198 //=============================================================================
1200 * New group including all mesh elements present in initial groups is created.
1202 //=============================================================================
1204 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1205 SMESH::SMESH_GroupBase_ptr theGroup2,
1206 const char* theName )
1207 throw (SALOME::SALOME_Exception)
1209 SMESH::SMESH_Group_var aResGrp;
1213 _preMeshInfo->FullLoadFromFile();
1215 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1216 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1218 if ( theGroup1->GetType() != theGroup2->GetType() )
1219 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1224 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1225 if ( aResGrp->_is_nil() )
1226 return SMESH::SMESH_Group::_nil();
1228 aResGrp->AddFrom( theGroup1 );
1229 aResGrp->AddFrom( theGroup2 );
1231 // Update Python script
1232 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1233 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1235 SMESH_CATCH( SMESH::throwCorbaException );
1237 return aResGrp._retn();
1240 //=============================================================================
1242 * \brief New group including all mesh elements present in initial groups is created.
1243 * \param theGroups list of groups
1244 * \param theName name of group to be created
1245 * \return pointer to the new group
1247 //=============================================================================
1249 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1250 const char* theName )
1251 throw (SALOME::SALOME_Exception)
1253 SMESH::SMESH_Group_var aResGrp;
1256 _preMeshInfo->FullLoadFromFile();
1259 return SMESH::SMESH_Group::_nil();
1264 SMESH::ElementType aType = SMESH::ALL;
1265 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1267 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1268 if ( CORBA::is_nil( aGrp ) )
1270 if ( aType == SMESH::ALL )
1271 aType = aGrp->GetType();
1272 else if ( aType != aGrp->GetType() )
1273 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1276 if ( aType == SMESH::ALL )
1277 return SMESH::SMESH_Group::_nil();
1282 aResGrp = CreateGroup( aType, theName );
1283 if ( aResGrp->_is_nil() )
1284 return SMESH::SMESH_Group::_nil();
1286 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1287 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1289 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1290 if ( !CORBA::is_nil( aGrp ) )
1292 aResGrp->AddFrom( aGrp );
1293 if ( g > 0 ) pyDump << ", ";
1297 pyDump << " ], '" << theName << "' )";
1299 SMESH_CATCH( SMESH::throwCorbaException );
1301 return aResGrp._retn();
1304 //=============================================================================
1306 * New group is created. All mesh elements that are
1307 * present in both initial groups are added to the new one.
1309 //=============================================================================
1311 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1312 SMESH::SMESH_GroupBase_ptr theGroup2,
1313 const char* theName )
1314 throw (SALOME::SALOME_Exception)
1316 SMESH::SMESH_Group_var aResGrp;
1321 _preMeshInfo->FullLoadFromFile();
1323 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1324 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1326 if ( theGroup1->GetType() != theGroup2->GetType() )
1327 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1331 // Create Intersection
1332 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1333 if ( aResGrp->_is_nil() )
1334 return aResGrp._retn();
1336 SMESHDS_GroupBase* groupDS1 = 0;
1337 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1338 groupDS1 = grp_i->GetGroupDS();
1340 SMESHDS_GroupBase* groupDS2 = 0;
1341 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1342 groupDS2 = grp_i->GetGroupDS();
1344 SMESHDS_Group* resGroupDS = 0;
1345 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1346 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1348 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1350 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1351 while ( elemIt1->more() )
1353 const SMDS_MeshElement* e = elemIt1->next();
1354 if ( groupDS2->Contains( e ))
1355 resGroupDS->SMDSGroup().Add( e );
1358 // Update Python script
1359 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1360 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1362 SMESH_CATCH( SMESH::throwCorbaException );
1364 return aResGrp._retn();
1367 //=============================================================================
1369 \brief Intersect list of groups. New group is created. All mesh elements that
1370 are present in all initial groups simultaneously are added to the new one.
1371 \param theGroups list of groups
1372 \param theName name of group to be created
1373 \return pointer on the group
1375 //=============================================================================
1376 SMESH::SMESH_Group_ptr
1377 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1378 const char* theName )
1379 throw (SALOME::SALOME_Exception)
1381 SMESH::SMESH_Group_var aResGrp;
1386 _preMeshInfo->FullLoadFromFile();
1389 return SMESH::SMESH_Group::_nil();
1391 // check types and get SMESHDS_GroupBase's
1392 SMESH::ElementType aType = SMESH::ALL;
1393 vector< SMESHDS_GroupBase* > groupVec;
1394 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1396 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1397 if ( CORBA::is_nil( aGrp ) )
1399 if ( aType == SMESH::ALL )
1400 aType = aGrp->GetType();
1401 else if ( aType != aGrp->GetType() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1405 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1406 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1408 if ( grpDS->IsEmpty() )
1413 groupVec.push_back( grpDS );
1416 if ( aType == SMESH::ALL ) // all groups are nil
1417 return SMESH::SMESH_Group::_nil();
1422 aResGrp = CreateGroup( aType, theName );
1424 SMESHDS_Group* resGroupDS = 0;
1425 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1426 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1427 if ( !resGroupDS || groupVec.empty() )
1428 return aResGrp._retn();
1431 size_t i, nb = groupVec.size();
1432 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1433 while ( elemIt1->more() )
1435 const SMDS_MeshElement* e = elemIt1->next();
1437 for ( i = 1; ( i < nb && inAll ); ++i )
1438 inAll = groupVec[i]->Contains( e );
1441 resGroupDS->SMDSGroup().Add( e );
1444 // Update Python script
1445 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1446 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1448 SMESH_CATCH( SMESH::throwCorbaException );
1450 return aResGrp._retn();
1453 //=============================================================================
1455 * New group is created. All mesh elements that are present in
1456 * a main group but is not present in a tool group are added to the new one
1458 //=============================================================================
1460 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1461 SMESH::SMESH_GroupBase_ptr theGroup2,
1462 const char* theName )
1463 throw (SALOME::SALOME_Exception)
1465 SMESH::SMESH_Group_var aResGrp;
1470 _preMeshInfo->FullLoadFromFile();
1472 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1473 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1475 if ( theGroup1->GetType() != theGroup2->GetType() )
1476 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1480 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1481 if ( aResGrp->_is_nil() )
1482 return aResGrp._retn();
1484 SMESHDS_GroupBase* groupDS1 = 0;
1485 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1486 groupDS1 = grp_i->GetGroupDS();
1488 SMESHDS_GroupBase* groupDS2 = 0;
1489 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1490 groupDS2 = grp_i->GetGroupDS();
1492 SMESHDS_Group* resGroupDS = 0;
1493 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1494 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1496 if ( groupDS1 && groupDS2 && resGroupDS )
1498 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1499 while ( elemIt1->more() )
1501 const SMDS_MeshElement* e = elemIt1->next();
1502 if ( !groupDS2->Contains( e ))
1503 resGroupDS->SMDSGroup().Add( e );
1506 // Update Python script
1507 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1508 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1510 SMESH_CATCH( SMESH::throwCorbaException );
1512 return aResGrp._retn();
1515 //=============================================================================
1517 \brief Cut lists of groups. New group is created. All mesh elements that are
1518 present in main groups but do not present in tool groups are added to the new one
1519 \param theMainGroups list of main groups
1520 \param theToolGroups list of tool groups
1521 \param theName name of group to be created
1522 \return pointer on the group
1524 //=============================================================================
1525 SMESH::SMESH_Group_ptr
1526 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1527 const SMESH::ListOfGroups& theToolGroups,
1528 const char* theName )
1529 throw (SALOME::SALOME_Exception)
1531 SMESH::SMESH_Group_var aResGrp;
1536 _preMeshInfo->FullLoadFromFile();
1539 return SMESH::SMESH_Group::_nil();
1541 // check types and get SMESHDS_GroupBase's
1542 SMESH::ElementType aType = SMESH::ALL;
1543 vector< SMESHDS_GroupBase* > toolGroupVec;
1544 vector< SMDS_ElemIteratorPtr > mainIterVec;
1546 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1548 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1549 if ( CORBA::is_nil( aGrp ) )
1551 if ( aType == SMESH::ALL )
1552 aType = aGrp->GetType();
1553 else if ( aType != aGrp->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1556 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1557 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1558 if ( !grpDS->IsEmpty() )
1559 mainIterVec.push_back( grpDS->GetElements() );
1561 if ( aType == SMESH::ALL ) // all main groups are nil
1562 return SMESH::SMESH_Group::_nil();
1563 if ( mainIterVec.empty() ) // all main groups are empty
1564 return aResGrp._retn();
1566 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1568 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1569 if ( CORBA::is_nil( aGrp ) )
1571 if ( aType != aGrp->GetType() )
1572 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1574 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1575 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1576 toolGroupVec.push_back( grpDS );
1582 aResGrp = CreateGroup( aType, theName );
1584 SMESHDS_Group* resGroupDS = 0;
1585 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1586 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1588 return aResGrp._retn();
1591 size_t i, nb = toolGroupVec.size();
1592 SMDS_ElemIteratorPtr mainElemIt
1593 ( new SMDS_IteratorOnIterators
1594 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1595 while ( mainElemIt->more() )
1597 const SMDS_MeshElement* e = mainElemIt->next();
1599 for ( i = 0; ( i < nb && !isIn ); ++i )
1600 isIn = toolGroupVec[i]->Contains( e );
1603 resGroupDS->SMDSGroup().Add( e );
1606 // Update Python script
1607 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1608 << ".CutListOfGroups( " << theMainGroups << ", "
1609 << theToolGroups << ", '" << theName << "' )";
1611 SMESH_CATCH( SMESH::throwCorbaException );
1613 return aResGrp._retn();
1616 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1618 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1619 bool & toStopChecking )
1621 toStopChecking = ( nbCommon < nbChecked );
1622 return nbCommon == nbNodes;
1624 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1625 bool & toStopChecking )
1627 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1628 return nbCommon == nbCorners;
1630 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1631 bool & toStopChecking )
1633 return nbCommon > 0;
1635 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1636 bool & toStopChecking )
1638 return nbCommon >= (nbNodes+1) / 2;
1642 //=============================================================================
1644 * Create a group of entities basing on nodes of other groups.
1645 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1646 * \param [in] anElemType - a type of elements to include to the new group.
1647 * \param [in] theName - a name of the new group.
1648 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1649 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1650 * new group provided that it is based on nodes of an element of \a aListOfGroups
1651 * \return SMESH_Group - the created group
1653 // IMP 19939, bug 22010, IMP 22635
1654 //=============================================================================
1656 SMESH::SMESH_Group_ptr
1657 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1658 SMESH::ElementType theElemType,
1659 const char* theName,
1660 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1661 CORBA::Boolean theUnderlyingOnly)
1662 throw (SALOME::SALOME_Exception)
1664 SMESH::SMESH_Group_var aResGrp;
1668 _preMeshInfo->FullLoadFromFile();
1670 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1672 if ( !theName || !aMeshDS )
1673 return SMESH::SMESH_Group::_nil();
1675 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1677 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1678 SMESH_Comment nbCoNoStr( "SMESH.");
1679 switch ( theNbCommonNodes ) {
1680 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1681 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1682 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1683 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1684 default: return aResGrp._retn();
1686 int nbChecked, nbCommon, nbNodes, nbCorners;
1692 aResGrp = CreateGroup( theElemType, theName );
1693 if ( aResGrp->_is_nil() )
1694 return SMESH::SMESH_Group::_nil();
1696 SMESHDS_GroupBase* groupBaseDS =
1697 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1698 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1700 vector<bool> isNodeInGroups;
1702 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1704 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1705 if ( CORBA::is_nil( aGrp ) )
1707 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1708 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1711 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1712 if ( !elIt ) continue;
1714 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1716 while ( elIt->more() ) {
1717 const SMDS_MeshElement* el = elIt->next();
1718 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1719 while ( nIt->more() )
1720 resGroupCore.Add( nIt->next() );
1723 // get elements of theElemType based on nodes of every element of group
1724 else if ( theUnderlyingOnly )
1726 while ( elIt->more() )
1728 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1729 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1730 TIDSortedElemSet checkedElems;
1731 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1732 while ( nIt->more() )
1734 const SMDS_MeshNode* n = nIt->next();
1735 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1736 // check nodes of elements of theElemType around el
1737 while ( elOfTypeIt->more() )
1739 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1740 if ( !checkedElems.insert( elOfType ).second ) continue;
1741 nbNodes = elOfType->NbNodes();
1742 nbCorners = elOfType->NbCornerNodes();
1744 bool toStopChecking = false;
1745 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1746 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1747 if ( elNodes.count( nIt2->next() ) &&
1748 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1750 resGroupCore.Add( elOfType );
1757 // get all nodes of elements of groups
1760 while ( elIt->more() )
1762 const SMDS_MeshElement* el = elIt->next(); // an element of group
1763 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1764 while ( nIt->more() )
1766 const SMDS_MeshNode* n = nIt->next();
1767 if ( n->GetID() >= (int) isNodeInGroups.size() )
1768 isNodeInGroups.resize( n->GetID() + 1, false );
1769 isNodeInGroups[ n->GetID() ] = true;
1775 // Get elements of theElemType based on a certain number of nodes of elements of groups
1776 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1778 const SMDS_MeshNode* n;
1779 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1780 const int isNodeInGroupsSize = isNodeInGroups.size();
1781 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1783 if ( !isNodeInGroups[ iN ] ||
1784 !( n = aMeshDS->FindNode( iN )))
1787 // check nodes of elements of theElemType around n
1788 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1789 while ( elOfTypeIt->more() )
1791 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1792 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1797 nbNodes = elOfType->NbNodes();
1798 nbCorners = elOfType->NbCornerNodes();
1800 bool toStopChecking = false;
1801 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1802 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1804 const int nID = nIt->next()->GetID();
1805 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1806 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1808 resGroupCore.Add( elOfType );
1816 // Update Python script
1817 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1818 << ".CreateDimGroup( "
1819 << theGroups << ", " << theElemType << ", '" << theName << "', "
1820 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1822 SMESH_CATCH( SMESH::throwCorbaException );
1824 return aResGrp._retn();
1827 //================================================================================
1829 * \brief Remember GEOM group data
1831 //================================================================================
1833 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1834 CORBA::Object_ptr theSmeshObj)
1836 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1839 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1840 if ( groupSO->_is_nil() )
1843 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1844 GEOM::GEOM_IGroupOperations_wrap groupOp =
1845 geomGen->GetIGroupOperations();
1846 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1849 _geomGroupData.push_back( TGeomGroupData() );
1850 TGeomGroupData & groupData = _geomGroupData.back();
1852 CORBA::String_var entry = groupSO->GetID();
1853 groupData._groupEntry = entry.in();
1855 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1856 groupData._indices.insert( ids[i] );
1858 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1859 // shape index in SMESHDS
1860 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1861 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1864 //================================================================================
1866 * Remove GEOM group data relating to removed smesh object
1868 //================================================================================
1870 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1872 list<TGeomGroupData>::iterator
1873 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1874 for ( ; data != dataEnd; ++data ) {
1875 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1876 _geomGroupData.erase( data );
1882 //================================================================================
1884 * \brief Return new group contents if it has been changed and update group data
1886 //================================================================================
1888 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1890 TopoDS_Shape newShape;
1893 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1894 if ( !groupSO->_is_nil() )
1896 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1897 if ( CORBA::is_nil( groupObj )) return newShape;
1898 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1900 // get indices of group items
1901 set<int> curIndices;
1902 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1903 GEOM::GEOM_IGroupOperations_wrap groupOp =
1904 geomGen->GetIGroupOperations();
1905 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1906 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1907 curIndices.insert( ids[i] );
1909 if ( groupData._indices == curIndices )
1910 return newShape; // group not changed
1913 groupData._indices = curIndices;
1915 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1916 if ( !geomClient ) return newShape;
1917 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1918 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1919 newShape = _gen_i->GeomObjectToShape( geomGroup );
1922 if ( newShape.IsNull() ) {
1923 // geom group becomes empty - return empty compound
1924 TopoDS_Compound compound;
1925 BRep_Builder().MakeCompound(compound);
1926 newShape = compound;
1933 //-----------------------------------------------------------------------------
1935 * \brief Storage of shape and index used in CheckGeomGroupModif()
1937 struct TIndexedShape
1940 TopoDS_Shape _shape;
1941 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1943 //-----------------------------------------------------------------------------
1945 * \brief Data to re-create a group on geometry
1947 struct TGroupOnGeomData
1951 SMDSAbs_ElementType _type;
1953 Quantity_Color _color;
1957 //=============================================================================
1959 * \brief Update data if geometry changes
1963 //=============================================================================
1965 void SMESH_Mesh_i::CheckGeomModif()
1967 if ( !_impl->HasShapeToMesh() ) return;
1969 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1970 //if ( mainGO->_is_nil() ) return;
1972 // Update after group modification
1974 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1975 called by other mesh (IPAL52735) */
1976 mainGO->GetType() == GEOM_GROUP ||
1977 mainGO->GetTick() == _mainShapeTick )
1979 CheckGeomGroupModif();
1983 // Update after shape transformation like Translate
1985 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1986 if ( !geomClient ) return;
1987 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1988 if ( geomGen->_is_nil() ) return;
1990 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1991 geomClient->RemoveShapeFromBuffer( ior.in() );
1993 // Update data taking into account that
1994 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1997 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1998 if ( newShape.IsNull() )
2001 _mainShapeTick = mainGO->GetTick();
2003 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2005 // store data of groups on geometry
2006 vector< TGroupOnGeomData > groupsData;
2007 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2008 groupsData.reserve( groups.size() );
2009 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2010 for ( ; g != groups.end(); ++g )
2011 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2013 TGroupOnGeomData data;
2014 data._oldID = group->GetID();
2015 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2016 data._type = group->GetType();
2017 data._name = group->GetStoreName();
2018 data._color = group->GetColor();
2019 groupsData.push_back( data );
2021 // store assigned hypotheses
2022 vector< pair< int, THypList > > ids2Hyps;
2023 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2024 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2026 const TopoDS_Shape& s = s2hyps.Key();
2027 const THypList& hyps = s2hyps.ChangeValue();
2028 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2031 // change shape to mesh
2032 int oldNbSubShapes = meshDS->MaxShapeIndex();
2033 _impl->ShapeToMesh( TopoDS_Shape() );
2034 _impl->ShapeToMesh( newShape );
2036 // re-add shapes of geom groups
2037 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2038 for ( ; data != _geomGroupData.end(); ++data )
2040 TopoDS_Shape newShape = newGroupShape( *data );
2041 if ( !newShape.IsNull() )
2043 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2045 TopoDS_Compound compound;
2046 BRep_Builder().MakeCompound( compound );
2047 BRep_Builder().Add( compound, newShape );
2048 newShape = compound;
2050 _impl->GetSubMesh( newShape );
2053 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2054 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2055 SALOME::INTERNAL_ERROR );
2057 // re-assign hypotheses
2058 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2060 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2061 const THypList& hyps = ids2Hyps[i].second;
2062 THypList::const_iterator h = hyps.begin();
2063 for ( ; h != hyps.end(); ++h )
2064 _impl->AddHypothesis( s, (*h)->GetID() );
2068 for ( size_t i = 0; i < groupsData.size(); ++i )
2070 const TGroupOnGeomData& data = groupsData[i];
2072 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2073 if ( i2g == _mapGroups.end() ) continue;
2075 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2076 if ( !gr_i ) continue;
2079 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2080 meshDS->IndexToShape( data._shapeID ));
2083 _mapGroups.erase( i2g );
2087 g->GetGroupDS()->SetColor( data._color );
2088 gr_i->changeLocalId( id );
2089 _mapGroups[ id ] = i2g->second;
2090 if ( data._oldID != id )
2091 _mapGroups.erase( i2g );
2095 // update _mapSubMesh
2096 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2097 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2098 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2102 //=============================================================================
2104 * \brief Update objects depending on changed geom groups
2106 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2107 * issue 0020210: Update of a smesh group after modification of the associated geom group
2109 //=============================================================================
2111 void SMESH_Mesh_i::CheckGeomGroupModif()
2113 if ( !_impl->HasShapeToMesh() ) return;
2115 CORBA::Long nbEntities = NbNodes() + NbElements();
2117 // Check if group contents changed
2119 typedef map< string, TopoDS_Shape > TEntry2Geom;
2120 TEntry2Geom newGroupContents;
2122 list<TGeomGroupData>::iterator
2123 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2124 for ( ; data != dataEnd; ++data )
2126 pair< TEntry2Geom::iterator, bool > it_new =
2127 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2128 bool processedGroup = !it_new.second;
2129 TopoDS_Shape& newShape = it_new.first->second;
2130 if ( !processedGroup )
2131 newShape = newGroupShape( *data );
2132 if ( newShape.IsNull() )
2133 continue; // no changes
2136 _preMeshInfo->ForgetOrLoad();
2138 if ( processedGroup ) { // update group indices
2139 list<TGeomGroupData>::iterator data2 = data;
2140 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2141 data->_indices = data2->_indices;
2144 // Update SMESH objects according to new GEOM group contents
2146 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2147 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2149 int oldID = submesh->GetId();
2150 if ( !_mapSubMeshIor.count( oldID ))
2152 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2154 // update hypotheses
2155 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2156 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2157 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2159 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2160 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2162 // care of submeshes
2163 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2164 int newID = newSubmesh->GetId();
2165 if ( newID != oldID ) {
2166 _mapSubMesh [ newID ] = newSubmesh;
2167 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2168 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2169 _mapSubMesh. erase(oldID);
2170 _mapSubMesh_i. erase(oldID);
2171 _mapSubMeshIor.erase(oldID);
2172 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2177 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2178 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2179 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2181 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2183 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2184 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2185 ds->SetShape( newShape );
2190 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2191 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2193 // Remove groups and submeshes basing on removed sub-shapes
2195 TopTools_MapOfShape newShapeMap;
2196 TopoDS_Iterator shapeIt( newShape );
2197 for ( ; shapeIt.More(); shapeIt.Next() )
2198 newShapeMap.Add( shapeIt.Value() );
2200 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2201 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2203 if ( newShapeMap.Contains( shapeIt.Value() ))
2205 TopTools_IndexedMapOfShape oldShapeMap;
2206 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2207 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2209 const TopoDS_Shape& oldShape = oldShapeMap(i);
2210 int oldInd = meshDS->ShapeToIndex( oldShape );
2212 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2213 if ( i_smIor != _mapSubMeshIor.end() ) {
2214 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2217 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2218 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2220 // check if a group bases on oldInd shape
2221 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2222 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2223 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2224 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2226 RemoveGroup( i_grp->second ); // several groups can base on same shape
2227 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2232 // Reassign hypotheses and update groups after setting the new shape to mesh
2234 // collect anassigned hypotheses
2235 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2236 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2237 TShapeHypList assignedHyps;
2238 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2240 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2241 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2242 if ( !hyps.empty() ) {
2243 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2244 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2245 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2248 // collect shapes supporting groups
2249 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2250 TShapeTypeList groupData;
2251 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2252 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2253 for ( ; grIt != groups.end(); ++grIt )
2255 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2257 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2259 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2261 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2262 _impl->ShapeToMesh( newShape );
2264 // reassign hypotheses
2265 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2266 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2268 TIndexedShape& geom = indS_hyps->first;
2269 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2270 int oldID = geom._index;
2271 int newID = meshDS->ShapeToIndex( geom._shape );
2272 if ( oldID == 1 ) { // main shape
2274 geom._shape = newShape;
2278 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2279 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2280 // care of sub-meshes
2281 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2282 if ( newID != oldID ) {
2283 _mapSubMesh [ newID ] = newSubmesh;
2284 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2285 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2286 _mapSubMesh. erase(oldID);
2287 _mapSubMesh_i. erase(oldID);
2288 _mapSubMeshIor.erase(oldID);
2289 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2293 TShapeTypeList::iterator geomType = groupData.begin();
2294 for ( ; geomType != groupData.end(); ++geomType )
2296 const TIndexedShape& geom = geomType->first;
2297 int oldID = geom._index;
2298 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2301 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2302 CORBA::String_var name = groupSO->GetName();
2304 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2306 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2307 group_i->changeLocalId( newID );
2310 break; // everything has been updated
2313 } // loop on group data
2317 CORBA::Long newNbEntities = NbNodes() + NbElements();
2318 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2319 if ( newNbEntities != nbEntities )
2321 // Add all SObjects with icons to soToUpdateIcons
2322 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2324 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2325 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2326 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2328 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2329 i_gr != _mapGroups.end(); ++i_gr ) // groups
2330 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2333 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2334 for ( ; so != soToUpdateIcons.end(); ++so )
2335 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2338 //=============================================================================
2340 * \brief Create standalone group from a group on geometry or filter
2342 //=============================================================================
2344 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2345 throw (SALOME::SALOME_Exception)
2347 SMESH::SMESH_Group_var aGroup;
2352 _preMeshInfo->FullLoadFromFile();
2354 if ( theGroup->_is_nil() )
2355 return aGroup._retn();
2357 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2359 return aGroup._retn();
2361 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2363 const int anId = aGroupToRem->GetLocalID();
2364 if ( !_impl->ConvertToStandalone( anId ) )
2365 return aGroup._retn();
2366 removeGeomGroupData( theGroup );
2368 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2370 // remove old instance of group from own map
2371 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2372 _mapGroups.erase( anId );
2374 SALOMEDS::StudyBuilder_var builder;
2375 SALOMEDS::SObject_wrap aGroupSO;
2376 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2377 if ( !aStudy->_is_nil() ) {
2378 builder = aStudy->NewBuilder();
2379 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2380 if ( !aGroupSO->_is_nil() )
2382 // remove reference to geometry
2383 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2384 for ( ; chItr->More(); chItr->Next() )
2385 // Remove group's child SObject
2386 builder->RemoveObject( chItr->Value() );
2388 // Update Python script
2389 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2390 << ".ConvertToStandalone( " << aGroupSO << " )";
2392 // change icon of Group on Filter
2395 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2396 const int isEmpty = ( elemTypes->length() == 0 );
2399 SALOMEDS::GenericAttribute_wrap anAttr =
2400 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2401 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2402 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2408 // remember new group in own map
2409 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2410 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2412 // register CORBA object for persistence
2413 _gen_i->RegisterObject( aGroup );
2415 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2416 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2417 //aGroup->Register();
2418 aGroupToRem->UnRegister();
2420 SMESH_CATCH( SMESH::throwCorbaException );
2422 return aGroup._retn();
2425 //=============================================================================
2429 //=============================================================================
2431 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2433 if(MYDEBUG) MESSAGE( "createSubMesh" );
2434 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2435 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2436 const int subMeshId = mySubMesh->GetId();
2438 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2439 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2441 _mapSubMesh [subMeshId] = mySubMesh;
2442 _mapSubMesh_i [subMeshId] = subMeshServant;
2443 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2445 subMeshServant->Register();
2447 // register CORBA object for persistence
2448 int nextId = _gen_i->RegisterObject( subMesh );
2449 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2450 else { nextId = 0; } // avoid "unused variable" warning
2452 // to track changes of GEOM groups
2453 addGeomGroupData( theSubShapeObject, subMesh );
2455 return subMesh._retn();
2458 //=======================================================================
2459 //function : getSubMesh
2461 //=======================================================================
2463 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2465 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2466 if ( it == _mapSubMeshIor.end() )
2467 return SMESH::SMESH_subMesh::_nil();
2469 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2472 //=============================================================================
2476 //=============================================================================
2478 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2479 GEOM::GEOM_Object_ptr theSubShapeObject )
2481 bool isHypChanged = false;
2482 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2483 return isHypChanged;
2485 const int subMeshId = theSubMesh->GetId();
2487 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2489 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2491 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2494 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2495 isHypChanged = !hyps.empty();
2496 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2497 for ( ; hyp != hyps.end(); ++hyp )
2498 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2505 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2506 isHypChanged = ( aHypList->length() > 0 );
2507 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2508 removeHypothesis( theSubShapeObject, aHypList[i] );
2511 catch( const SALOME::SALOME_Exception& ) {
2512 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2514 removeGeomGroupData( theSubShapeObject );
2518 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2519 if ( id_smi != _mapSubMesh_i.end() )
2520 id_smi->second->UnRegister();
2522 // remove a CORBA object
2523 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2524 if ( id_smptr != _mapSubMeshIor.end() )
2525 SMESH::SMESH_subMesh_var( id_smptr->second );
2527 _mapSubMesh.erase(subMeshId);
2528 _mapSubMesh_i.erase(subMeshId);
2529 _mapSubMeshIor.erase(subMeshId);
2531 return isHypChanged;
2534 //=============================================================================
2538 //=============================================================================
2540 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2541 const char* theName,
2542 const TopoDS_Shape& theShape,
2543 const SMESH_PredicatePtr& thePredicate )
2545 std::string newName;
2546 if ( !theName || !theName[0] )
2548 std::set< std::string > presentNames;
2549 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2550 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2552 CORBA::String_var name = i_gr->second->GetName();
2553 presentNames.insert( name.in() );
2556 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2557 } while ( !presentNames.insert( newName ).second );
2558 theName = newName.c_str();
2561 SMESH::SMESH_GroupBase_var aGroup;
2562 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2564 SMESH_GroupBase_i* aGroupImpl;
2565 if ( !theShape.IsNull() )
2566 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2567 else if ( thePredicate )
2568 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2570 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2572 aGroup = aGroupImpl->_this();
2573 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2574 aGroupImpl->Register();
2576 // register CORBA object for persistence
2577 int nextId = _gen_i->RegisterObject( aGroup );
2578 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2579 else { nextId = 0; } // avoid "unused variable" warning in release mode
2581 // to track changes of GEOM groups
2582 if ( !theShape.IsNull() ) {
2583 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2584 addGeomGroupData( geom, aGroup );
2587 return aGroup._retn();
2590 //=============================================================================
2592 * SMESH_Mesh_i::removeGroup
2594 * Should be called by ~SMESH_Group_i()
2596 //=============================================================================
2598 void SMESH_Mesh_i::removeGroup( const int theId )
2600 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2601 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2602 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2603 _mapGroups.erase( theId );
2604 removeGeomGroupData( group );
2605 if ( !_impl->RemoveGroup( theId ))
2607 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2608 RemoveGroup( group );
2610 group->UnRegister();
2614 //=============================================================================
2618 //=============================================================================
2620 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2621 throw(SALOME::SALOME_Exception)
2623 SMESH::log_array_var aLog;
2627 _preMeshInfo->FullLoadFromFile();
2629 list < SMESHDS_Command * >logDS = _impl->GetLog();
2630 aLog = new SMESH::log_array;
2632 int lg = logDS.size();
2635 list < SMESHDS_Command * >::iterator its = logDS.begin();
2636 while(its != logDS.end()){
2637 SMESHDS_Command *com = *its;
2638 int comType = com->GetType();
2640 int lgcom = com->GetNumber();
2642 const list < int >&intList = com->GetIndexes();
2643 int inum = intList.size();
2645 list < int >::const_iterator ii = intList.begin();
2646 const list < double >&coordList = com->GetCoords();
2647 int rnum = coordList.size();
2649 list < double >::const_iterator ir = coordList.begin();
2650 aLog[indexLog].commandType = comType;
2651 aLog[indexLog].number = lgcom;
2652 aLog[indexLog].coords.length(rnum);
2653 aLog[indexLog].indexes.length(inum);
2654 for(int i = 0; i < rnum; i++){
2655 aLog[indexLog].coords[i] = *ir;
2656 //MESSAGE(" "<<i<<" "<<ir.Value());
2659 for(int i = 0; i < inum; i++){
2660 aLog[indexLog].indexes[i] = *ii;
2661 //MESSAGE(" "<<i<<" "<<ii.Value());
2670 SMESH_CATCH( SMESH::throwCorbaException );
2672 return aLog._retn();
2676 //=============================================================================
2680 //=============================================================================
2682 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2686 SMESH_CATCH( SMESH::throwCorbaException );
2689 //=============================================================================
2693 //=============================================================================
2695 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2700 //=============================================================================
2703 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2704 // issue 0020918: groups removal is caused by hyp modification
2705 // issue 0021208: to forget not loaded mesh data at hyp modification
2706 struct TCallUp_i : public SMESH_Mesh::TCallUp
2708 SMESH_Mesh_i* _mesh;
2709 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2710 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2711 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2712 virtual void Load () { _mesh->Load(); }
2716 //================================================================================
2718 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2720 //================================================================================
2722 void SMESH_Mesh_i::onHypothesisModified()
2725 _preMeshInfo->ForgetOrLoad();
2727 SMESH::SMESH_Mesh_var mesh = _this();
2728 _gen_i->UpdateIcons( mesh );
2731 //=============================================================================
2735 //=============================================================================
2737 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2739 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2742 _impl->SetCallUp( new TCallUp_i(this));
2745 //=============================================================================
2749 //=============================================================================
2751 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2753 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2757 //=============================================================================
2759 * Return mesh editor
2761 //=============================================================================
2763 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2764 throw (SALOME::SALOME_Exception)
2766 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2770 _preMeshInfo->FullLoadFromFile();
2772 // Create MeshEditor
2774 _editor = new SMESH_MeshEditor_i( this, false );
2775 aMeshEdVar = _editor->_this();
2777 // Update Python script
2778 TPythonDump() << _editor << " = "
2779 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2781 SMESH_CATCH( SMESH::throwCorbaException );
2783 return aMeshEdVar._retn();
2786 //=============================================================================
2788 * Return mesh edition previewer
2790 //=============================================================================
2792 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2793 throw (SALOME::SALOME_Exception)
2795 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2799 _preMeshInfo->FullLoadFromFile();
2801 if ( !_previewEditor )
2802 _previewEditor = new SMESH_MeshEditor_i( this, true );
2803 aMeshEdVar = _previewEditor->_this();
2805 SMESH_CATCH( SMESH::throwCorbaException );
2807 return aMeshEdVar._retn();
2810 //================================================================================
2812 * \brief Return true if the mesh has been edited since a last total re-compute
2813 * and those modifications may prevent successful partial re-compute
2815 //================================================================================
2817 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2819 Unexpect aCatch(SALOME_SalomeException);
2820 return _impl->HasModificationsToDiscard();
2823 //================================================================================
2825 * \brief Returns a random unique color
2827 //================================================================================
2829 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2831 const int MAX_ATTEMPTS = 100;
2833 double tolerance = 0.5;
2834 SALOMEDS::Color col;
2838 // generate random color
2839 double red = (double)rand() / RAND_MAX;
2840 double green = (double)rand() / RAND_MAX;
2841 double blue = (double)rand() / RAND_MAX;
2842 // check existence in the list of the existing colors
2843 bool matched = false;
2844 std::list<SALOMEDS::Color>::const_iterator it;
2845 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2846 SALOMEDS::Color color = *it;
2847 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2848 matched = tol < tolerance;
2850 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2851 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2859 //=============================================================================
2861 * Sets auto-color mode. If it is on, groups get unique random colors
2863 //=============================================================================
2865 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2867 Unexpect aCatch(SALOME_SalomeException);
2868 _impl->SetAutoColor(theAutoColor);
2870 TPythonDump pyDump; // not to dump group->SetColor() from below code
2871 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2873 std::list<SALOMEDS::Color> aReservedColors;
2874 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2875 for ( ; it != _mapGroups.end(); it++ ) {
2876 if ( CORBA::is_nil( it->second )) continue;
2877 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2878 it->second->SetColor( aColor );
2879 aReservedColors.push_back( aColor );
2883 //=============================================================================
2885 * Returns true if auto-color mode is on
2887 //=============================================================================
2889 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2891 Unexpect aCatch(SALOME_SalomeException);
2892 return _impl->GetAutoColor();
2895 //=============================================================================
2897 * Checks if there are groups with equal names
2899 //=============================================================================
2901 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2903 return _impl->HasDuplicatedGroupNamesMED();
2906 //================================================================================
2908 * \brief Care of a file before exporting mesh into it
2910 //================================================================================
2912 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2914 SMESH_File aFile( file );
2916 if (aFile.exists()) {
2917 // existing filesystem node
2918 if ( !aFile.isDirectory() ) {
2919 if ( aFile.openForWriting() ) {
2920 if ( overwrite && ! aFile.remove()) {
2921 msg << "Can't replace " << aFile.getName();
2924 msg << "Can't write into " << aFile.getName();
2927 msg << "Location " << aFile.getName() << " is not a file";
2931 // nonexisting file; check if it can be created
2932 if ( !aFile.openForWriting() ) {
2933 msg << "You cannot create the file "
2935 << ". Check the directory existence and access rights";
2943 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2947 //================================================================================
2949 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2950 * \param file - file name
2951 * \param overwrite - to erase the file or not
2952 * \retval string - mesh name
2954 //================================================================================
2956 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2957 CORBA::Boolean overwrite)
2960 PrepareForWriting(file, overwrite);
2961 string aMeshName = "Mesh";
2962 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2963 if ( !aStudy->_is_nil() ) {
2964 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2965 if ( !aMeshSO->_is_nil() ) {
2966 CORBA::String_var name = aMeshSO->GetName();
2968 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2969 if ( !aStudy->GetProperties()->IsLocked() )
2971 SALOMEDS::GenericAttribute_wrap anAttr;
2972 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2973 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2974 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2975 ASSERT(!aFileName->_is_nil());
2976 aFileName->SetValue(file);
2977 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2978 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2979 ASSERT(!aFileType->_is_nil());
2980 aFileType->SetValue("FICHIERMED");
2984 // Update Python script
2985 // set name of mesh before export
2986 TPythonDump() << _gen_i << ".SetName("
2987 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2989 // check names of groups
2995 //================================================================================
2997 * \brief Export to MED file
2999 //================================================================================
3001 void SMESH_Mesh_i::ExportMED(const char* file,
3002 CORBA::Boolean auto_groups,
3004 CORBA::Boolean overwrite,
3005 CORBA::Boolean autoDimension)
3006 throw(SALOME::SALOME_Exception)
3008 //MESSAGE("MED minor version: "<< minor);
3011 _preMeshInfo->FullLoadFromFile();
3013 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3014 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, 0, autoDimension );
3016 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3018 << "auto_groups=" <<auto_groups << ", "
3019 << "minor=" << minor << ", "
3020 << "overwrite=" << overwrite << ", "
3021 << "meshPart=None, "
3022 << "autoDimension=" << autoDimension << " )";
3024 SMESH_CATCH( SMESH::throwCorbaException );
3027 //================================================================================
3029 * \brief Export a mesh to a SAUV file
3031 //================================================================================
3033 void SMESH_Mesh_i::ExportSAUV (const char* file,
3034 CORBA::Boolean auto_groups)
3035 throw(SALOME::SALOME_Exception)
3037 Unexpect aCatch(SALOME_SalomeException);
3039 _preMeshInfo->FullLoadFromFile();
3041 string aMeshName = prepareMeshNameAndGroups(file, true);
3042 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3043 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3044 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3048 //================================================================================
3050 * \brief Export a mesh to a DAT file
3052 //================================================================================
3054 void SMESH_Mesh_i::ExportDAT (const char *file)
3055 throw(SALOME::SALOME_Exception)
3057 Unexpect aCatch(SALOME_SalomeException);
3059 _preMeshInfo->FullLoadFromFile();
3061 // Update Python script
3062 // check names of groups
3064 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3067 PrepareForWriting(file);
3068 _impl->ExportDAT(file);
3071 //================================================================================
3073 * \brief Export a mesh to an UNV file
3075 //================================================================================
3077 void SMESH_Mesh_i::ExportUNV (const char *file)
3078 throw(SALOME::SALOME_Exception)
3080 Unexpect aCatch(SALOME_SalomeException);
3082 _preMeshInfo->FullLoadFromFile();
3084 // Update Python script
3085 // check names of groups
3087 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3090 PrepareForWriting(file);
3091 _impl->ExportUNV(file);
3094 //================================================================================
3096 * \brief Export a mesh to an STL file
3098 //================================================================================
3100 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3101 throw(SALOME::SALOME_Exception)
3103 Unexpect aCatch(SALOME_SalomeException);
3105 _preMeshInfo->FullLoadFromFile();
3107 // Update Python script
3108 // check names of groups
3110 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3111 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3113 CORBA::String_var name;
3114 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3115 if ( !so->_is_nil() )
3116 name = so->GetName();
3119 PrepareForWriting( file );
3120 _impl->ExportSTL( file, isascii, name.in() );
3123 //================================================================================
3125 * \brief Export a part of mesh to a med file
3127 //================================================================================
3129 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3131 CORBA::Boolean auto_groups,
3133 CORBA::Boolean overwrite,
3134 CORBA::Boolean autoDimension,
3135 const GEOM::ListOfFields& fields,
3136 const char* geomAssocFields)
3137 throw (SALOME::SALOME_Exception)
3139 //MESSAGE("MED minor version: "<< minor);
3142 _preMeshInfo->FullLoadFromFile();
3145 bool have0dField = false;
3146 if ( fields.length() > 0 )
3148 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3149 if ( shapeToMesh->_is_nil() )
3150 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3152 for ( size_t i = 0; i < fields.length(); ++i )
3154 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3155 THROW_SALOME_CORBA_EXCEPTION
3156 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3157 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3158 if ( fieldShape->_is_nil() )
3159 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3160 if ( !fieldShape->IsSame( shapeToMesh ) )
3161 THROW_SALOME_CORBA_EXCEPTION
3162 ( "Field defined not on shape", SALOME::BAD_PARAM);
3163 if ( fields[i]->GetDimension() == 0 )
3166 if ( geomAssocFields )
3167 for ( int i = 0; geomAssocFields[i]; ++i )
3168 switch ( geomAssocFields[i] ) {
3169 case 'v':case 'e':case 'f':case 's': break;
3170 case 'V':case 'E':case 'F':case 'S': break;
3171 default: THROW_SALOME_CORBA_EXCEPTION
3172 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3176 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3180 string aMeshName = "Mesh";
3181 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3182 if ( CORBA::is_nil( meshPart ) ||
3183 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3185 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3186 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
3187 0, autoDimension, /*addODOnVertices=*/have0dField);
3188 meshDS = _impl->GetMeshDS();
3193 _preMeshInfo->FullLoadFromFile();
3195 PrepareForWriting(file, overwrite);
3197 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3198 if ( !SO->_is_nil() ) {
3199 CORBA::String_var name = SO->GetName();
3203 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3204 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
3205 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3206 meshDS = tmpDSDeleter._obj = partDS;
3211 if ( _impl->HasShapeToMesh() )
3213 DriverMED_W_Field fieldWriter;
3214 fieldWriter.SetFile( file );
3215 fieldWriter.SetMeshName( aMeshName );
3216 fieldWriter.AddODOnVertices( have0dField );
3218 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3222 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3223 goList->length( fields.length() );
3224 for ( size_t i = 0; i < fields.length(); ++i )
3226 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3229 TPythonDump() << _this() << ".ExportPartToMED( r'"
3231 << "auto_groups=" << auto_groups << ", "
3232 << "minor=" << minor << ", "
3233 << "overwrite=" << overwrite << ", "
3234 << "meshPart=" << meshPart << ", "
3235 << "autoDimension=" << autoDimension << ", "
3236 << "fields=" << goList << ", geomAssocFields='"
3237 << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3239 SMESH_CATCH( SMESH::throwCorbaException );
3242 //================================================================================
3244 * Write GEOM fields to MED file
3246 //================================================================================
3248 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3249 SMESHDS_Mesh* meshDS,
3250 const GEOM::ListOfFields& fields,
3251 const char* geomAssocFields)
3253 #define METH "SMESH_Mesh_i::exportMEDFields() "
3255 if (( fields.length() < 1 ) &&
3256 ( !geomAssocFields || !geomAssocFields[0] ))
3259 std::vector< std::vector< double > > dblVals;
3260 std::vector< std::vector< int > > intVals;
3261 std::vector< int > subIdsByDim[ 4 ];
3262 const double noneDblValue = 0.;
3263 const double noneIntValue = 0;
3265 for ( size_t iF = 0; iF < fields.length(); ++iF )
3269 int dim = fields[ iF ]->GetDimension();
3270 SMDSAbs_ElementType elemType;
3271 TopAbs_ShapeEnum shapeType;
3273 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3274 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3275 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3276 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3278 continue; // skip fields on whole shape
3280 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3281 if ( dataType == GEOM::FDT_String )
3283 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3284 if ( stepIDs->length() < 1 )
3286 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3287 if ( comps->length() < 1 )
3289 CORBA::String_var name = fields[ iF ]->GetName();
3291 if ( !fieldWriter.Set( meshDS,
3295 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3298 for ( size_t iC = 0; iC < comps->length(); ++iC )
3299 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3301 dblVals.resize( comps->length() );
3302 intVals.resize( comps->length() );
3304 // find sub-shape IDs
3306 std::vector< int >& subIds = subIdsByDim[ dim ];
3307 if ( subIds.empty() )
3308 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3309 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3310 subIds.push_back( id );
3314 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3318 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3320 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3321 if ( step->_is_nil() )
3324 CORBA::Long stamp = step->GetStamp();
3325 CORBA::Long id = step->GetID();
3326 fieldWriter.SetDtIt( int( stamp ), int( id ));
3328 // fill dblVals or intVals
3329 for ( size_t iC = 0; iC < comps->length(); ++iC )
3330 if ( dataType == GEOM::FDT_Double )
3332 dblVals[ iC ].clear();
3333 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3337 intVals[ iC ].clear();
3338 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3342 case GEOM::FDT_Double:
3344 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3345 if ( dblStep->_is_nil() ) continue;
3346 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3347 if ( vv->length() != subIds.size() * comps->length() )
3348 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3349 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3350 for ( size_t iC = 0; iC < comps->length(); ++iC )
3351 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3356 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3357 if ( intStep->_is_nil() ) continue;
3358 GEOM::ListOfLong_var vv = intStep->GetValues();
3359 if ( vv->length() != subIds.size() * comps->length() )
3360 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3361 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3362 for ( size_t iC = 0; iC < comps->length(); ++iC )
3363 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3366 case GEOM::FDT_Bool:
3368 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3369 if ( boolStep->_is_nil() ) continue;
3370 GEOM::short_array_var vv = boolStep->GetValues();
3371 if ( vv->length() != subIds.size() * comps->length() )
3372 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3373 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3374 for ( size_t iC = 0; iC < comps->length(); ++iC )
3375 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3381 // pass values to fieldWriter
3382 elemIt = fieldWriter.GetOrderedElems();
3383 if ( dataType == GEOM::FDT_Double )
3384 while ( elemIt->more() )
3386 const SMDS_MeshElement* e = elemIt->next();
3387 const int shapeID = e->getshapeId();
3388 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3389 for ( size_t iC = 0; iC < comps->length(); ++iC )
3390 fieldWriter.AddValue( noneDblValue );
3392 for ( size_t iC = 0; iC < comps->length(); ++iC )
3393 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3396 while ( elemIt->more() )
3398 const SMDS_MeshElement* e = elemIt->next();
3399 const int shapeID = e->getshapeId();
3400 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3401 for ( size_t iC = 0; iC < comps->length(); ++iC )
3402 fieldWriter.AddValue( (double) noneIntValue );
3404 for ( size_t iC = 0; iC < comps->length(); ++iC )
3405 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3409 fieldWriter.Perform();
3410 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3411 if ( res && res->IsKO() )
3413 if ( res->myComment.empty() )
3414 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3416 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3422 if ( !geomAssocFields || !geomAssocFields[0] )
3425 // write geomAssocFields
3427 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3428 shapeDim[ TopAbs_COMPOUND ] = 3;
3429 shapeDim[ TopAbs_COMPSOLID ] = 3;
3430 shapeDim[ TopAbs_SOLID ] = 3;
3431 shapeDim[ TopAbs_SHELL ] = 2;
3432 shapeDim[ TopAbs_FACE ] = 2;
3433 shapeDim[ TopAbs_WIRE ] = 1;
3434 shapeDim[ TopAbs_EDGE ] = 1;
3435 shapeDim[ TopAbs_VERTEX ] = 0;
3436 shapeDim[ TopAbs_SHAPE ] = 3;
3438 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3440 std::vector< std::string > compNames;
3441 switch ( geomAssocFields[ iF ]) {
3443 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3444 compNames.push_back( "dim" );
3447 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3450 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3453 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3457 compNames.push_back( "id" );
3458 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3459 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3461 fieldWriter.SetDtIt( -1, -1 );
3463 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3467 if ( compNames.size() == 2 ) // _vertices_
3468 while ( elemIt->more() )
3470 const SMDS_MeshElement* e = elemIt->next();
3471 const int shapeID = e->getshapeId();
3474 fieldWriter.AddValue( (double) -1 );
3475 fieldWriter.AddValue( (double) -1 );
3479 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3480 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3481 fieldWriter.AddValue( (double) shapeID );
3485 while ( elemIt->more() )
3487 const SMDS_MeshElement* e = elemIt->next();
3488 const int shapeID = e->getshapeId();
3490 fieldWriter.AddValue( (double) -1 );
3492 fieldWriter.AddValue( (double) shapeID );
3496 fieldWriter.Perform();
3497 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3498 if ( res && res->IsKO() )
3500 if ( res->myComment.empty() )
3501 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3503 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3506 } // loop on geomAssocFields
3511 //================================================================================
3513 * \brief Export a part of mesh to a DAT file
3515 //================================================================================
3517 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3519 throw (SALOME::SALOME_Exception)
3521 Unexpect aCatch(SALOME_SalomeException);
3523 _preMeshInfo->FullLoadFromFile();
3525 PrepareForWriting(file);
3527 SMESH_MeshPartDS partDS( meshPart );
3528 _impl->ExportDAT(file,&partDS);
3530 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3531 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3533 //================================================================================
3535 * \brief Export a part of mesh to an UNV file
3537 //================================================================================
3539 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3541 throw (SALOME::SALOME_Exception)
3543 Unexpect aCatch(SALOME_SalomeException);
3545 _preMeshInfo->FullLoadFromFile();
3547 PrepareForWriting(file);
3549 SMESH_MeshPartDS partDS( meshPart );
3550 _impl->ExportUNV(file, &partDS);
3552 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3553 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3555 //================================================================================
3557 * \brief Export a part of mesh to an STL file
3559 //================================================================================
3561 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3563 ::CORBA::Boolean isascii)
3564 throw (SALOME::SALOME_Exception)
3566 Unexpect aCatch(SALOME_SalomeException);
3568 _preMeshInfo->FullLoadFromFile();
3570 PrepareForWriting(file);
3572 CORBA::String_var name;
3573 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3574 if ( !so->_is_nil() )
3575 name = so->GetName();
3577 SMESH_MeshPartDS partDS( meshPart );
3578 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3580 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3581 << meshPart<< ", r'" << file << "', " << isascii << ")";
3584 //================================================================================
3586 * \brief Export a part of mesh to an STL file
3588 //================================================================================
3590 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3592 CORBA::Boolean overwrite,
3593 CORBA::Boolean groupElemsByType)
3594 throw (SALOME::SALOME_Exception)
3597 Unexpect aCatch(SALOME_SalomeException);
3599 _preMeshInfo->FullLoadFromFile();
3601 PrepareForWriting(file,overwrite);
3603 std::string meshName("");
3604 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3605 if ( !so->_is_nil() )
3607 CORBA::String_var name = so->GetName();
3608 meshName = name.in();
3612 SMESH_MeshPartDS partDS( meshPart );
3613 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3615 SMESH_CATCH( SMESH::throwCorbaException );
3617 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3618 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3620 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3624 //================================================================================
3626 * \brief Export a part of mesh to a GMF file
3628 //================================================================================
3630 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3632 bool withRequiredGroups)
3633 throw (SALOME::SALOME_Exception)
3635 Unexpect aCatch(SALOME_SalomeException);
3637 _preMeshInfo->FullLoadFromFile();
3639 PrepareForWriting(file,/*overwrite=*/true);
3641 SMESH_MeshPartDS partDS( meshPart );
3642 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3644 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3645 << meshPart<< ", r'"
3647 << withRequiredGroups << ")";
3650 //=============================================================================
3652 * Return computation progress [0.,1]
3654 //=============================================================================
3656 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3660 return _impl->GetComputeProgress();
3662 SMESH_CATCH( SMESH::doNothing );
3666 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3668 Unexpect aCatch(SALOME_SalomeException);
3670 return _preMeshInfo->NbNodes();
3672 return _impl->NbNodes();
3675 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3677 Unexpect aCatch(SALOME_SalomeException);
3679 return _preMeshInfo->NbElements();
3681 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3684 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3686 Unexpect aCatch(SALOME_SalomeException);
3688 return _preMeshInfo->Nb0DElements();
3690 return _impl->Nb0DElements();
3693 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3695 Unexpect aCatch(SALOME_SalomeException);
3697 return _preMeshInfo->NbBalls();
3699 return _impl->NbBalls();
3702 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3704 Unexpect aCatch(SALOME_SalomeException);
3706 return _preMeshInfo->NbEdges();
3708 return _impl->NbEdges();
3711 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3712 throw(SALOME::SALOME_Exception)
3714 Unexpect aCatch(SALOME_SalomeException);
3716 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3718 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3721 //=============================================================================
3723 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3725 Unexpect aCatch(SALOME_SalomeException);
3727 return _preMeshInfo->NbFaces();
3729 return _impl->NbFaces();
3732 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3734 Unexpect aCatch(SALOME_SalomeException);
3736 return _preMeshInfo->NbTriangles();
3738 return _impl->NbTriangles();
3741 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3743 Unexpect aCatch(SALOME_SalomeException);
3745 return _preMeshInfo->NbBiQuadTriangles();
3747 return _impl->NbBiQuadTriangles();
3750 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 return _preMeshInfo->NbQuadrangles();
3756 return _impl->NbQuadrangles();
3759 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3763 return _preMeshInfo->NbBiQuadQuadrangles();
3765 return _impl->NbBiQuadQuadrangles();
3768 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbPolygons();
3774 return _impl->NbPolygons();
3777 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3783 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3786 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3787 throw(SALOME::SALOME_Exception)
3789 Unexpect aCatch(SALOME_SalomeException);
3791 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3793 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3796 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3797 throw(SALOME::SALOME_Exception)
3799 Unexpect aCatch(SALOME_SalomeException);
3801 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3803 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3806 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3807 throw(SALOME::SALOME_Exception)
3809 Unexpect aCatch(SALOME_SalomeException);
3811 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3813 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3816 //=============================================================================
3818 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3820 Unexpect aCatch(SALOME_SalomeException);
3822 return _preMeshInfo->NbVolumes();
3824 return _impl->NbVolumes();
3827 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3829 Unexpect aCatch(SALOME_SalomeException);
3831 return _preMeshInfo->NbTetras();
3833 return _impl->NbTetras();
3836 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3838 Unexpect aCatch(SALOME_SalomeException);
3840 return _preMeshInfo->NbHexas();
3842 return _impl->NbHexas();
3845 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3847 Unexpect aCatch(SALOME_SalomeException);
3849 return _preMeshInfo->NbTriQuadHexas();
3851 return _impl->NbTriQuadraticHexas();
3854 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3856 Unexpect aCatch(SALOME_SalomeException);
3858 return _preMeshInfo->NbPyramids();
3860 return _impl->NbPyramids();
3863 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbPrisms();
3869 return _impl->NbPrisms();
3872 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 return _preMeshInfo->NbHexPrisms();
3878 return _impl->NbHexagonalPrisms();
3881 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbPolyhedrons();
3887 return _impl->NbPolyhedrons();
3890 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3891 throw(SALOME::SALOME_Exception)
3893 Unexpect aCatch(SALOME_SalomeException);
3895 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3897 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3900 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3901 throw(SALOME::SALOME_Exception)
3903 Unexpect aCatch(SALOME_SalomeException);
3905 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3907 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3910 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3911 throw(SALOME::SALOME_Exception)
3913 Unexpect aCatch(SALOME_SalomeException);
3915 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3917 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3920 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3921 throw(SALOME::SALOME_Exception)
3923 Unexpect aCatch(SALOME_SalomeException);
3925 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3927 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3930 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3931 throw(SALOME::SALOME_Exception)
3933 Unexpect aCatch(SALOME_SalomeException);
3935 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3937 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3940 //=============================================================================
3942 * Returns nb of published sub-meshes
3944 //=============================================================================
3946 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3948 Unexpect aCatch(SALOME_SalomeException);
3949 return _mapSubMesh_i.size();
3952 //=============================================================================
3954 * Dumps mesh into a string
3956 //=============================================================================
3958 char* SMESH_Mesh_i::Dump()
3962 return CORBA::string_dup( os.str().c_str() );
3965 //=============================================================================
3967 * Method of SMESH_IDSource interface
3969 //=============================================================================
3971 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3973 return GetElementsId();
3976 //=============================================================================
3978 * Returns ids of all elements
3980 //=============================================================================
3982 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3983 throw (SALOME::SALOME_Exception)
3985 Unexpect aCatch(SALOME_SalomeException);
3987 _preMeshInfo->FullLoadFromFile();
3989 SMESH::long_array_var aResult = new SMESH::long_array();
3990 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3992 if ( aSMESHDS_Mesh == NULL )
3993 return aResult._retn();
3995 long nbElements = NbElements();
3996 aResult->length( nbElements );
3997 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3998 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3999 aResult[i] = anIt->next()->GetID();
4001 return aResult._retn();
4005 //=============================================================================
4007 * Returns ids of all elements of given type
4009 //=============================================================================
4011 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4012 throw (SALOME::SALOME_Exception)
4014 Unexpect aCatch(SALOME_SalomeException);
4016 _preMeshInfo->FullLoadFromFile();
4018 SMESH::long_array_var aResult = new SMESH::long_array();
4019 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4021 if ( aSMESHDS_Mesh == NULL )
4022 return aResult._retn();
4024 long nbElements = NbElements();
4026 // No sense in returning ids of elements along with ids of nodes:
4027 // when theElemType == SMESH::ALL, return node ids only if
4028 // there are no elements
4029 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4030 return GetNodesId();
4032 aResult->length( nbElements );
4036 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4037 while ( i < nbElements && anIt->more() )
4038 aResult[i++] = anIt->next()->GetID();
4040 aResult->length( i );
4042 return aResult._retn();
4045 //=============================================================================
4047 * Returns ids of all nodes
4049 //=============================================================================
4051 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4052 throw (SALOME::SALOME_Exception)
4054 Unexpect aCatch(SALOME_SalomeException);
4056 _preMeshInfo->FullLoadFromFile();
4058 SMESH::long_array_var aResult = new SMESH::long_array();
4059 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4061 if ( aMeshDS == NULL )
4062 return aResult._retn();
4064 long nbNodes = NbNodes();
4065 aResult->length( nbNodes );
4066 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4067 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4068 aResult[i] = anIt->next()->GetID();
4070 return aResult._retn();
4073 //=============================================================================
4077 //=============================================================================
4079 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4080 throw (SALOME::SALOME_Exception)
4082 SMESH::ElementType type = SMESH::ALL;
4086 _preMeshInfo->FullLoadFromFile();
4088 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4090 SMESH_CATCH( SMESH::throwCorbaException );
4095 //=============================================================================
4099 //=============================================================================
4101 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4102 throw (SALOME::SALOME_Exception)
4105 _preMeshInfo->FullLoadFromFile();
4107 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4109 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4111 return ( SMESH::EntityType ) e->GetEntityType();
4114 //=============================================================================
4118 //=============================================================================
4120 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4121 throw (SALOME::SALOME_Exception)
4124 _preMeshInfo->FullLoadFromFile();
4126 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4128 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4130 return ( SMESH::GeometryType ) e->GetGeomType();
4133 //=============================================================================
4135 * Returns ID of elements for given submesh
4137 //=============================================================================
4138 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4139 throw (SALOME::SALOME_Exception)
4141 SMESH::long_array_var aResult = new SMESH::long_array();
4145 _preMeshInfo->FullLoadFromFile();
4147 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4148 if(!SM) return aResult._retn();
4150 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4151 if(!SDSM) return aResult._retn();
4153 aResult->length(SDSM->NbElements());
4155 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4157 while ( eIt->more() ) {
4158 aResult[i++] = eIt->next()->GetID();
4161 SMESH_CATCH( SMESH::throwCorbaException );
4163 return aResult._retn();
4166 //=============================================================================
4168 * Returns ID of nodes for given submesh
4169 * If param all==true - returns all nodes, else -
4170 * returns only nodes on shapes.
4172 //=============================================================================
4174 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4176 throw (SALOME::SALOME_Exception)
4178 SMESH::long_array_var aResult = new SMESH::long_array();
4182 _preMeshInfo->FullLoadFromFile();
4184 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4185 if(!SM) return aResult._retn();
4187 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4188 if(!SDSM) return aResult._retn();
4191 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4192 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4193 while ( nIt->more() ) {
4194 const SMDS_MeshNode* elem = nIt->next();
4195 theElems.insert( elem->GetID() );
4198 else { // all nodes of submesh elements
4199 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4200 while ( eIt->more() ) {
4201 const SMDS_MeshElement* anElem = eIt->next();
4202 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4203 while ( nIt->more() ) {
4204 const SMDS_MeshElement* elem = nIt->next();
4205 theElems.insert( elem->GetID() );
4210 aResult->length(theElems.size());
4211 set<int>::iterator itElem;
4213 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4214 aResult[i++] = *itElem;
4216 SMESH_CATCH( SMESH::throwCorbaException );
4218 return aResult._retn();
4221 //=============================================================================
4223 * Returns type of elements for given submesh
4225 //=============================================================================
4227 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4228 throw (SALOME::SALOME_Exception)
4230 SMESH::ElementType type = SMESH::ALL;
4234 _preMeshInfo->FullLoadFromFile();
4236 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4237 if(!SM) return SMESH::ALL;
4239 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4240 if(!SDSM) return SMESH::ALL;
4242 if(SDSM->NbElements()==0)
4243 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4245 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4246 const SMDS_MeshElement* anElem = eIt->next();
4248 type = ( SMESH::ElementType ) anElem->GetType();
4250 SMESH_CATCH( SMESH::throwCorbaException );
4256 //=============================================================================
4258 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4260 //=============================================================================
4262 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4265 _preMeshInfo->FullLoadFromFile();
4267 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4268 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4273 //=============================================================================
4275 * Get XYZ coordinates of node as list of double
4276 * If there is not node for given ID - returns empty list
4278 //=============================================================================
4280 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4283 _preMeshInfo->FullLoadFromFile();
4285 SMESH::double_array_var aResult = new SMESH::double_array();
4286 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4287 if ( aMeshDS == NULL )
4288 return aResult._retn();
4291 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4293 return aResult._retn();
4297 aResult[0] = aNode->X();
4298 aResult[1] = aNode->Y();
4299 aResult[2] = aNode->Z();
4300 return aResult._retn();
4304 //=============================================================================
4306 * For given node returns list of IDs of inverse elements
4307 * If there is not node for given ID - returns empty list
4309 //=============================================================================
4311 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4314 _preMeshInfo->FullLoadFromFile();
4316 SMESH::long_array_var aResult = new SMESH::long_array();
4317 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4318 if ( aMeshDS == NULL )
4319 return aResult._retn();
4322 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4324 return aResult._retn();
4326 // find inverse elements
4327 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4328 aResult->length( aNode->NbInverseElements() );
4329 for( int i = 0; eIt->more(); ++i )
4331 const SMDS_MeshElement* elem = eIt->next();
4332 aResult[ i ] = elem->GetID();
4334 return aResult._retn();
4337 //=============================================================================
4339 * \brief Return position of a node on shape
4341 //=============================================================================
4343 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4346 _preMeshInfo->FullLoadFromFile();
4348 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4349 aNodePosition->shapeID = 0;
4350 aNodePosition->shapeType = GEOM::SHAPE;
4352 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4353 if ( !mesh ) return aNodePosition;
4355 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4357 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4359 aNodePosition->shapeID = aNode->getshapeId();
4360 switch ( pos->GetTypeOfPosition() ) {
4362 aNodePosition->shapeType = GEOM::EDGE;
4363 aNodePosition->params.length(1);
4364 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4366 case SMDS_TOP_FACE: {
4367 SMDS_FacePositionPtr fPos = pos;
4368 aNodePosition->shapeType = GEOM::FACE;
4369 aNodePosition->params.length(2);
4370 aNodePosition->params[0] = fPos->GetUParameter();
4371 aNodePosition->params[1] = fPos->GetVParameter();
4374 case SMDS_TOP_VERTEX:
4375 aNodePosition->shapeType = GEOM::VERTEX;
4377 case SMDS_TOP_3DSPACE:
4378 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4379 aNodePosition->shapeType = GEOM::SOLID;
4380 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4381 aNodePosition->shapeType = GEOM::SHELL;
4387 return aNodePosition;
4390 //=============================================================================
4392 * \brief Return position of an element on shape
4394 //=============================================================================
4396 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4399 _preMeshInfo->FullLoadFromFile();
4401 SMESH::ElementPosition anElementPosition;
4402 anElementPosition.shapeID = 0;
4403 anElementPosition.shapeType = GEOM::SHAPE;
4405 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4406 if ( !mesh ) return anElementPosition;
4408 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4410 anElementPosition.shapeID = anElem->getshapeId();
4411 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4412 if ( !aSp.IsNull() ) {
4413 switch ( aSp.ShapeType() ) {
4415 anElementPosition.shapeType = GEOM::EDGE;
4418 anElementPosition.shapeType = GEOM::FACE;
4421 anElementPosition.shapeType = GEOM::VERTEX;
4424 anElementPosition.shapeType = GEOM::SOLID;
4427 anElementPosition.shapeType = GEOM::SHELL;
4433 return anElementPosition;
4436 //=============================================================================
4438 * If given element is node returns IDs of shape from position
4439 * If there is not node for given ID - returns -1
4441 //=============================================================================
4443 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4446 _preMeshInfo->FullLoadFromFile();
4448 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4449 if ( aMeshDS == NULL )
4453 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4455 return aNode->getshapeId();
4462 //=============================================================================
4464 * For given element returns ID of result shape after
4465 * ::FindShape() from SMESH_MeshEditor
4466 * If there is not element for given ID - returns -1
4468 //=============================================================================
4470 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4473 _preMeshInfo->FullLoadFromFile();
4475 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4476 if ( aMeshDS == NULL )
4479 // try to find element
4480 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4484 ::SMESH_MeshEditor aMeshEditor(_impl);
4485 int index = aMeshEditor.FindShape( elem );
4493 //=============================================================================
4495 * Returns number of nodes for given element
4496 * If there is not element for given ID - returns -1
4498 //=============================================================================
4500 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4503 _preMeshInfo->FullLoadFromFile();
4505 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4506 if ( aMeshDS == NULL ) return -1;
4507 // try to find element
4508 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4509 if(!elem) return -1;
4510 return elem->NbNodes();
4514 //=============================================================================
4516 * Returns ID of node by given index for given element
4517 * If there is not element for given ID - returns -1
4518 * If there is not node for given index - returns -2
4520 //=============================================================================
4522 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4525 _preMeshInfo->FullLoadFromFile();
4527 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4528 if ( aMeshDS == NULL ) return -1;
4529 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4530 if(!elem) return -1;
4531 if( index>=elem->NbNodes() || index<0 ) return -1;
4532 return elem->GetNode(index)->GetID();
4535 //=============================================================================
4537 * Returns IDs of nodes of given element
4539 //=============================================================================
4541 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4544 _preMeshInfo->FullLoadFromFile();
4546 SMESH::long_array_var aResult = new SMESH::long_array();
4547 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4549 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4551 aResult->length( elem->NbNodes() );
4552 for ( int i = 0; i < elem->NbNodes(); ++i )
4553 aResult[ i ] = elem->GetNode( i )->GetID();
4556 return aResult._retn();
4559 //=============================================================================
4561 * Returns true if given node is medium node
4562 * in given quadratic element
4564 //=============================================================================
4566 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4569 _preMeshInfo->FullLoadFromFile();
4571 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4572 if ( aMeshDS == NULL ) return false;
4574 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4575 if(!aNode) return false;
4576 // try to find element
4577 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4578 if(!elem) return false;
4580 return elem->IsMediumNode(aNode);
4584 //=============================================================================
4586 * Returns true if given node is medium node
4587 * in one of quadratic elements
4589 //=============================================================================
4591 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4592 SMESH::ElementType theElemType)
4595 _preMeshInfo->FullLoadFromFile();
4597 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4598 if ( aMeshDS == NULL ) return false;
4601 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4602 if(!aNode) return false;
4604 SMESH_MesherHelper aHelper( *(_impl) );
4606 SMDSAbs_ElementType aType;
4607 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4608 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4609 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4610 else aType = SMDSAbs_All;
4612 return aHelper.IsMedium(aNode,aType);
4616 //=============================================================================
4618 * Returns number of edges for given element
4620 //=============================================================================
4622 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4625 _preMeshInfo->FullLoadFromFile();
4627 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4628 if ( aMeshDS == NULL ) return -1;
4629 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4630 if(!elem) return -1;
4631 return elem->NbEdges();
4635 //=============================================================================
4637 * Returns number of faces for given element
4639 //=============================================================================
4641 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4644 _preMeshInfo->FullLoadFromFile();
4646 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4647 if ( aMeshDS == NULL ) return -1;
4648 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4649 if(!elem) return -1;
4650 return elem->NbFaces();
4653 //=======================================================================
4654 //function : GetElemFaceNodes
4655 //purpose : Returns nodes of given face (counted from zero) for given element.
4656 //=======================================================================
4658 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4659 CORBA::Short faceIndex)
4662 _preMeshInfo->FullLoadFromFile();
4664 SMESH::long_array_var aResult = new SMESH::long_array();
4665 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4667 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4669 SMDS_VolumeTool vtool( elem );
4670 if ( faceIndex < vtool.NbFaces() )
4672 aResult->length( vtool.NbFaceNodes( faceIndex ));
4673 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4674 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4675 aResult[ i ] = nn[ i ]->GetID();
4679 return aResult._retn();
4682 //=======================================================================
4683 //function : GetElemFaceNodes
4684 //purpose : Returns three components of normal of given mesh face.
4685 //=======================================================================
4687 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4688 CORBA::Boolean normalized)
4691 _preMeshInfo->FullLoadFromFile();
4693 SMESH::double_array_var aResult = new SMESH::double_array();
4695 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4698 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4700 aResult->length( 3 );
4701 aResult[ 0 ] = normal.X();
4702 aResult[ 1 ] = normal.Y();
4703 aResult[ 2 ] = normal.Z();
4706 return aResult._retn();
4709 //=======================================================================
4710 //function : FindElementByNodes
4711 //purpose : Returns an element based on all given nodes.
4712 //=======================================================================
4714 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4717 _preMeshInfo->FullLoadFromFile();
4719 CORBA::Long elemID(0);
4720 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4722 vector< const SMDS_MeshNode * > nn( nodes.length() );
4723 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4724 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4727 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4728 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4729 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4730 _impl->NbVolumes( ORDER_QUADRATIC )))
4731 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4733 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4738 //================================================================================
4740 * \brief Return elements including all given nodes.
4742 //================================================================================
4744 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4745 SMESH::ElementType elemType)
4748 _preMeshInfo->FullLoadFromFile();
4750 SMESH::long_array_var result = new SMESH::long_array();
4752 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4754 vector< const SMDS_MeshNode * > nn( nodes.length() );
4755 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4756 nn[i] = mesh->FindNode( nodes[i] );
4758 std::vector<const SMDS_MeshElement *> elems;
4759 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4760 result->length( elems.size() );
4761 for ( size_t i = 0; i < elems.size(); ++i )
4762 result[i] = elems[i]->GetID();
4764 return result._retn();
4767 //=============================================================================
4769 * Returns true if given element is polygon
4771 //=============================================================================
4773 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4776 _preMeshInfo->FullLoadFromFile();
4778 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4779 if ( aMeshDS == NULL ) return false;
4780 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4781 if(!elem) return false;
4782 return elem->IsPoly();
4786 //=============================================================================
4788 * Returns true if given element is quadratic
4790 //=============================================================================
4792 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4795 _preMeshInfo->FullLoadFromFile();
4797 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4798 if ( aMeshDS == NULL ) return false;
4799 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4800 if(!elem) return false;
4801 return elem->IsQuadratic();
4804 //=============================================================================
4806 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4808 //=============================================================================
4810 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4813 _preMeshInfo->FullLoadFromFile();
4815 if ( const SMDS_BallElement* ball =
4816 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4817 return ball->GetDiameter();
4822 //=============================================================================
4824 * Returns bary center for given element
4826 //=============================================================================
4828 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4831 _preMeshInfo->FullLoadFromFile();
4833 SMESH::double_array_var aResult = new SMESH::double_array();
4834 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4835 if ( aMeshDS == NULL )
4836 return aResult._retn();
4838 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4840 return aResult._retn();
4842 if(elem->GetType()==SMDSAbs_Volume) {
4843 SMDS_VolumeTool aTool;
4844 if(aTool.Set(elem)) {
4846 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4851 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4853 double x=0., y=0., z=0.;
4854 for(; anIt->more(); ) {
4856 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4870 return aResult._retn();
4873 //================================================================================
4875 * \brief Create a group of elements preventing computation of a sub-shape
4877 //================================================================================
4879 SMESH::ListOfGroups*
4880 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4881 const char* theGroupName )
4882 throw ( SALOME::SALOME_Exception )
4884 Unexpect aCatch(SALOME_SalomeException);
4886 if ( !theGroupName || strlen( theGroupName) == 0 )
4887 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4889 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4890 ::SMESH_MeshEditor::ElemFeatures elemType;
4892 // submesh by subshape id
4893 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4894 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4897 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4898 if ( error && error->HasBadElems() )
4900 // sort bad elements by type
4901 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4902 const list<const SMDS_MeshElement*>& badElems =
4903 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4904 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4905 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4906 for ( ; elemIt != elemEnd; ++elemIt )
4908 const SMDS_MeshElement* elem = *elemIt;
4909 if ( !elem ) continue;
4911 if ( elem->GetID() < 1 )
4913 // elem is a temporary element, make a real element
4914 vector< const SMDS_MeshNode* > nodes;
4915 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4916 while ( nIt->more() && elem )
4918 nodes.push_back( nIt->next() );
4919 if ( nodes.back()->GetID() < 1 )
4920 elem = 0; // a temporary element on temporary nodes
4924 ::SMESH_MeshEditor editor( _impl );
4925 elem = editor.AddElement( nodes, elemType.Init( elem ));
4929 elemsByType[ elem->GetType() ].push_back( elem );
4932 // how many groups to create?
4934 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4935 nbTypes += int( !elemsByType[ i ].empty() );
4936 groups->length( nbTypes );
4939 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4941 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4942 if ( elems.empty() ) continue;
4944 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4945 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4947 SMESH::SMESH_Mesh_var mesh = _this();
4948 SALOMEDS::SObject_wrap aSO =
4949 _gen_i->PublishGroup( mesh, groups[ iG ],
4950 GEOM::GEOM_Object::_nil(), theGroupName);
4952 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4953 if ( !grp_i ) continue;
4955 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4956 for ( size_t iE = 0; iE < elems.size(); ++iE )
4957 grpDS->SMDSGroup().Add( elems[ iE ]);
4962 return groups._retn();
4965 //=============================================================================
4967 * Create and publish group servants if any groups were imported or created anyhow
4969 //=============================================================================
4971 void SMESH_Mesh_i::CreateGroupServants()
4973 SMESH::SMESH_Mesh_var aMesh = _this();
4976 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4977 while ( groupIt->more() )
4979 ::SMESH_Group* group = groupIt->next();
4980 int anId = group->GetGroupDS()->GetID();
4982 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4983 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4985 addedIDs.insert( anId );
4987 SMESH_GroupBase_i* aGroupImpl;
4989 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4990 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4992 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4993 shape = groupOnGeom->GetShape();
4996 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4999 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5000 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5001 aGroupImpl->Register();
5003 // register CORBA object for persistence
5004 int nextId = _gen_i->RegisterObject( groupVar );
5005 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5006 else { nextId = 0; } // avoid "unused variable" warning in release mode
5008 // publishing the groups in the study
5009 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5010 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5012 if ( !addedIDs.empty() )
5015 set<int>::iterator id = addedIDs.begin();
5016 for ( ; id != addedIDs.end(); ++id )
5018 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5019 int i = std::distance( _mapGroups.begin(), it );
5020 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5025 //=============================================================================
5027 * \brief Return true if all sub-meshes are computed OK - to update an icon
5029 //=============================================================================
5031 bool SMESH_Mesh_i::IsComputedOK()
5033 return _impl->IsComputedOK();
5036 //=============================================================================
5038 * \brief Return groups cantained in _mapGroups by their IDs
5040 //=============================================================================
5042 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5044 int nbGroups = groupIDs.size();
5045 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5046 aList->length( nbGroups );
5048 list<int>::const_iterator ids = groupIDs.begin();
5049 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5051 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5052 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5053 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5055 aList->length( nbGroups );
5056 return aList._retn();
5059 //=============================================================================
5061 * \brief Return information about imported file
5063 //=============================================================================
5065 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5067 SMESH::MedFileInfo_var res( _medFileInfo );
5068 if ( !res.operator->() ) {
5069 res = new SMESH::MedFileInfo;
5071 res->fileSize = res->major = res->minor = res->release = -1;
5076 //=============================================================================
5078 * \brief Pass names of mesh groups from study to mesh DS
5080 //=============================================================================
5082 void SMESH_Mesh_i::checkGroupNames()
5084 int nbGrp = NbGroups();
5088 SMESH::ListOfGroups* grpList = 0;
5089 // avoid dump of "GetGroups"
5091 // store python dump into a local variable inside local scope
5092 SMESH::TPythonDump pDump; // do not delete this line of code
5093 grpList = GetGroups();
5096 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5097 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5100 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5101 if ( aGrpSO->_is_nil() )
5103 // correct name of the mesh group if necessary
5104 const char* guiName = aGrpSO->GetName();
5105 if ( strcmp(guiName, aGrp->GetName()) )
5106 aGrp->SetName( guiName );
5110 //=============================================================================
5112 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5114 //=============================================================================
5115 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5117 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5121 //=============================================================================
5123 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5125 //=============================================================================
5127 char* SMESH_Mesh_i::GetParameters()
5129 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5132 //=============================================================================
5134 * \brief Returns list of notebook variables used for last Mesh operation
5136 //=============================================================================
5137 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5139 SMESH::string_array_var aResult = new SMESH::string_array();
5140 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5142 CORBA::String_var aParameters = GetParameters();
5143 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5144 if ( aSections->length() > 0 ) {
5145 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5146 aResult->length( aVars.length() );
5147 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5148 aResult[i] = CORBA::string_dup( aVars[i] );
5151 return aResult._retn();
5154 //=======================================================================
5155 //function : GetTypes
5156 //purpose : Returns types of elements it contains
5157 //=======================================================================
5159 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5162 return _preMeshInfo->GetTypes();
5164 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5168 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5169 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5170 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5171 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5172 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5173 if (_impl->NbNodes() &&
5174 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5175 types->length( nbTypes );
5177 return types._retn();
5180 //=======================================================================
5181 //function : GetMesh
5182 //purpose : Returns self
5183 //=======================================================================
5185 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5187 return SMESH::SMESH_Mesh::_duplicate( _this() );
5190 //=======================================================================
5191 //function : IsMeshInfoCorrect
5192 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5193 // * happen if mesh data is not yet fully loaded from the file of study.
5194 //=======================================================================
5196 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5198 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5201 //=============================================================================
5203 * \brief Returns number of mesh elements per each \a EntityType
5205 //=============================================================================
5207 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5210 return _preMeshInfo->GetMeshInfo();
5212 SMESH::long_array_var aRes = new SMESH::long_array();
5213 aRes->length(SMESH::Entity_Last);
5214 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5216 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5218 return aRes._retn();
5219 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5220 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5221 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5222 return aRes._retn();
5225 //=============================================================================
5227 * \brief Returns number of mesh elements per each \a ElementType
5229 //=============================================================================
5231 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5233 SMESH::long_array_var aRes = new SMESH::long_array();
5234 aRes->length(SMESH::NB_ELEMENT_TYPES);
5235 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5238 const SMDS_MeshInfo* meshInfo = 0;
5240 meshInfo = _preMeshInfo;
5241 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5242 meshInfo = & meshDS->GetMeshInfo();
5245 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5246 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5248 return aRes._retn();
5251 //=============================================================================
5253 * Collect statistic of mesh elements given by iterator
5255 //=============================================================================
5257 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5258 SMESH::long_array& theInfo)
5260 if (!theItr) return;
5261 while (theItr->more())
5262 theInfo[ theItr->next()->GetEntityType() ]++;
5264 //=============================================================================
5266 * Returns mesh unstructed grid information.
5268 //=============================================================================
5270 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5272 SALOMEDS::TMPFile_var SeqFile;
5273 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5274 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5276 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5277 aWriter->WriteToOutputStringOn();
5278 aWriter->SetInputData(aGrid);
5279 aWriter->SetFileTypeToBinary();
5281 char* str = aWriter->GetOutputString();
5282 int size = aWriter->GetOutputStringLength();
5284 //Allocate octect buffer of required size
5285 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5286 //Copy ostrstream content to the octect buffer
5287 memcpy(OctetBuf, str, size);
5288 //Create and return TMPFile
5289 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5293 return SeqFile._retn();
5296 //=============================================================================
5297 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5298 * SMESH::ElementType type) */
5300 using namespace SMESH::Controls;
5301 //-----------------------------------------------------------------------------
5302 struct PredicateIterator : public SMDS_ElemIterator
5304 SMDS_ElemIteratorPtr _elemIter;
5305 PredicatePtr _predicate;
5306 const SMDS_MeshElement* _elem;
5308 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5309 PredicatePtr predicate):
5310 _elemIter(iterator), _predicate(predicate)
5318 virtual const SMDS_MeshElement* next()
5320 const SMDS_MeshElement* res = _elem;
5322 while ( _elemIter->more() && !_elem )
5324 _elem = _elemIter->next();
5325 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5332 //-----------------------------------------------------------------------------
5333 struct IDSourceIterator : public SMDS_ElemIterator
5335 const CORBA::Long* _idPtr;
5336 const CORBA::Long* _idEndPtr;
5337 SMESH::long_array_var _idArray;
5338 const SMDS_Mesh* _mesh;
5339 const SMDSAbs_ElementType _type;
5340 const SMDS_MeshElement* _elem;
5342 IDSourceIterator( const SMDS_Mesh* mesh,
5343 const CORBA::Long* ids,
5345 SMDSAbs_ElementType type):
5346 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5348 if ( _idPtr && nbIds && _mesh )
5351 IDSourceIterator( const SMDS_Mesh* mesh,
5352 SMESH::long_array* idArray,
5353 SMDSAbs_ElementType type):
5354 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5356 if ( idArray && _mesh )
5358 _idPtr = &_idArray[0];
5359 _idEndPtr = _idPtr + _idArray->length();
5367 virtual const SMDS_MeshElement* next()
5369 const SMDS_MeshElement* res = _elem;
5371 while ( _idPtr < _idEndPtr && !_elem )
5373 if ( _type == SMDSAbs_Node )
5375 _elem = _mesh->FindNode( *_idPtr++ );
5377 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5378 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5386 //-----------------------------------------------------------------------------
5388 struct NodeOfElemIterator : public SMDS_ElemIterator
5390 TColStd_MapOfInteger _checkedNodeIDs;
5391 SMDS_ElemIteratorPtr _elemIter;
5392 SMDS_ElemIteratorPtr _nodeIter;
5393 const SMDS_MeshElement* _node;
5395 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5397 if ( _elemIter && _elemIter->more() )
5399 _nodeIter = _elemIter->next()->nodesIterator();
5407 virtual const SMDS_MeshElement* next()
5409 const SMDS_MeshElement* res = _node;
5411 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5413 if ( _nodeIter->more() )
5415 _node = _nodeIter->next();
5416 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5421 _nodeIter = _elemIter->next()->nodesIterator();
5429 //=============================================================================
5431 * Return iterator on elements of given type in given object
5433 //=============================================================================
5435 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5436 SMESH::ElementType theType)
5438 SMDS_ElemIteratorPtr elemIt;
5439 bool typeOK = ( theType == SMESH::ALL );
5440 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5442 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5443 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5444 if ( !mesh_i ) return elemIt;
5445 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5447 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5449 elemIt = meshDS->elementsIterator( elemType );
5452 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5454 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5457 elemIt = sm->GetElements();
5458 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5460 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5461 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5465 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5467 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5468 if ( groupDS && ( elemType == groupDS->GetType() ||
5469 elemType == SMDSAbs_Node ||
5470 elemType == SMDSAbs_All ))
5472 elemIt = groupDS->GetElements();
5473 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5476 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5478 if ( filter_i->GetElementType() == theType ||
5479 elemType == SMDSAbs_Node ||
5480 elemType == SMDSAbs_All)
5482 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5483 if ( pred_i && pred_i->GetPredicate() )
5485 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5486 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5487 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5488 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5494 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5495 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5496 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5498 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5501 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5502 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5506 SMESH::long_array_var ids = theObject->GetIDs();
5507 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5509 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5512 if ( elemIt && elemIt->more() && !typeOK )
5514 if ( elemType == SMDSAbs_Node )
5516 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5520 elemIt = SMDS_ElemIteratorPtr();
5526 //=============================================================================
5527 namespace // Finding concurrent hypotheses
5528 //=============================================================================
5532 * \brief mapping of mesh dimension into shape type
5534 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5536 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5538 case 0: aType = TopAbs_VERTEX; break;
5539 case 1: aType = TopAbs_EDGE; break;
5540 case 2: aType = TopAbs_FACE; break;
5542 default:aType = TopAbs_SOLID; break;
5547 //-----------------------------------------------------------------------------
5549 * \brief Internal structure used to find concurrent submeshes
5551 * It represents a pair < submesh, concurrent dimension >, where
5552 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5553 * with another submesh. In other words, it is dimension of a hypothesis assigned
5560 int _dim; //!< a dimension the algo can build (concurrent dimension)
5561 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5562 TopTools_MapOfShape _shapeMap;
5563 SMESH_subMesh* _subMesh;
5564 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5566 //-----------------------------------------------------------------------------
5567 // Return the algorithm
5568 const SMESH_Algo* GetAlgo() const
5569 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5571 //-----------------------------------------------------------------------------
5573 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5575 const TopoDS_Shape& theShape)
5577 _subMesh = (SMESH_subMesh*)theSubMesh;
5578 SetShape( theDim, theShape );
5581 //-----------------------------------------------------------------------------
5583 void SetShape(const int theDim,
5584 const TopoDS_Shape& theShape)
5587 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5588 if (_dim >= _ownDim)
5589 _shapeMap.Add( theShape );
5591 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5592 for( ; anExp.More(); anExp.Next() )
5593 _shapeMap.Add( anExp.Current() );
5597 //-----------------------------------------------------------------------------
5598 //! Check sharing of sub-shapes
5599 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5600 const TopTools_MapOfShape& theToFind,
5601 const TopAbs_ShapeEnum theType)
5603 bool isShared = false;
5604 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5605 for (; !isShared && anItr.More(); anItr.Next() )
5607 const TopoDS_Shape aSubSh = anItr.Key();
5608 // check for case when concurrent dimensions are same
5609 isShared = theToFind.Contains( aSubSh );
5610 // check for sub-shape with concurrent dimension
5611 TopExp_Explorer anExp( aSubSh, theType );
5612 for ( ; !isShared && anExp.More(); anExp.Next() )
5613 isShared = theToFind.Contains( anExp.Current() );
5618 //-----------------------------------------------------------------------------
5619 //! check algorithms
5620 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5621 const SMESHDS_Hypothesis* theA2)
5623 if ( !theA1 || !theA2 ||
5624 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5625 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5626 return false; // one of the hypothesis is not algorithm
5627 // check algorithm names (should be equal)
5628 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5632 //-----------------------------------------------------------------------------
5633 //! Check if sub-shape hypotheses are concurrent
5634 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5636 if ( _subMesh == theOther->_subMesh )
5637 return false; // same sub-shape - should not be
5639 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5640 // any of the two submeshes is not on COMPOUND shape )
5641 // -> no concurrency
5642 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5643 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5644 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5645 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5646 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5649 // bool checkSubShape = ( _dim >= theOther->_dim )
5650 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5651 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5652 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5653 if ( !checkSubShape )
5656 // check algorithms to be same
5657 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5658 return true; // different algorithms -> concurrency !
5660 // check hypothesises for concurrence (skip first as algorithm)
5662 // pointers should be same, because it is referened from mesh hypothesis partition
5663 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5664 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5665 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5666 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5668 // the submeshes are concurrent if their algorithms has different parameters
5669 return nbSame != (int)theOther->_hypotheses.size() - 1;
5672 // Return true if algorithm of this SMESH_DimHyp is used if no
5673 // sub-mesh order is imposed by the user
5674 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5676 // NeedDiscreteBoundary() algo has a higher priority
5677 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5678 theOther->GetAlgo()->NeedDiscreteBoundary() )
5679 return !this->GetAlgo()->NeedDiscreteBoundary();
5681 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5684 }; // end of SMESH_DimHyp
5685 //-----------------------------------------------------------------------------
5687 typedef list<const SMESH_DimHyp*> TDimHypList;
5689 //-----------------------------------------------------------------------------
5691 void addDimHypInstance(const int theDim,
5692 const TopoDS_Shape& theShape,
5693 const SMESH_Algo* theAlgo,
5694 const SMESH_subMesh* theSubMesh,
5695 const list <const SMESHDS_Hypothesis*>& theHypList,
5696 TDimHypList* theDimHypListArr )
5698 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5699 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5700 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5701 dimHyp->_hypotheses.push_front(theAlgo);
5702 listOfdimHyp.push_back( dimHyp );
5705 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5706 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5707 theHypList.begin(), theHypList.end() );
5710 //-----------------------------------------------------------------------------
5711 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5712 TDimHypList& theListOfConcurr)
5714 if ( theListOfConcurr.empty() )
5716 theListOfConcurr.push_back( theDimHyp );
5720 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5721 while ( hypIt != theListOfConcurr.end() &&
5722 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5724 theListOfConcurr.insert( hypIt, theDimHyp );
5728 //-----------------------------------------------------------------------------
5729 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5730 const TDimHypList& theListOfDimHyp,
5731 TDimHypList& theListOfConcurrHyp,
5732 set<int>& theSetOfConcurrId )
5734 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5735 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5737 const SMESH_DimHyp* curDimHyp = *rIt;
5738 if ( curDimHyp == theDimHyp )
5739 break; // meet own dimHyp pointer in same dimension
5741 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5742 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5744 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5749 //-----------------------------------------------------------------------------
5750 void unionLists(TListOfInt& theListOfId,
5751 TListOfListOfInt& theListOfListOfId,
5754 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5755 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5757 continue; //skip already treated lists
5758 // check if other list has any same submesh object
5759 TListOfInt& otherListOfId = *it;
5760 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5761 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5764 // union two lists (from source into target)
5765 TListOfInt::iterator it2 = otherListOfId.begin();
5766 for ( ; it2 != otherListOfId.end(); it2++ ) {
5767 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5768 theListOfId.push_back(*it2);
5770 // clear source list
5771 otherListOfId.clear();
5774 //-----------------------------------------------------------------------------
5776 //! free memory allocated for dimension-hypothesis objects
5777 void removeDimHyps( TDimHypList* theArrOfList )
5779 for (int i = 0; i < 4; i++ ) {
5780 TDimHypList& listOfdimHyp = theArrOfList[i];
5781 TDimHypList::const_iterator it = listOfdimHyp.begin();
5782 for ( ; it != listOfdimHyp.end(); it++ )
5787 //-----------------------------------------------------------------------------
5789 * \brief find common submeshes with given submesh
5790 * \param theSubMeshList list of already collected submesh to check
5791 * \param theSubMesh given submesh to intersect with other
5792 * \param theCommonSubMeshes collected common submeshes
5794 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5795 const SMESH_subMesh* theSubMesh,
5796 set<const SMESH_subMesh*>& theCommon )
5800 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5801 for ( ; it != theSubMeshList.end(); it++ )
5802 theSubMesh->FindIntersection( *it, theCommon );
5803 theSubMeshList.push_back( theSubMesh );
5804 //theCommon.insert( theSubMesh );
5807 //-----------------------------------------------------------------------------
5808 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5810 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5811 for ( ; listsIt != smLists.end(); ++listsIt )
5813 const TListOfInt& smIDs = *listsIt;
5814 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5822 //=============================================================================
5824 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5826 //=============================================================================
5828 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5830 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5831 if ( isSubMeshInList( submeshID, anOrder ))
5834 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5835 return isSubMeshInList( submeshID, allConurrent );
5838 //=============================================================================
5840 * \brief Return submesh objects list in meshing order
5842 //=============================================================================
5844 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5846 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5848 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5850 return aResult._retn();
5852 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5853 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5854 anOrder.splice( anOrder.end(), allConurrent );
5857 TListOfListOfInt::iterator listIt = anOrder.begin();
5858 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5859 unionLists( *listIt, anOrder, listIndx + 1 );
5861 // convert submesh ids into interface instances
5862 // and dump command into python
5863 convertMeshOrder( anOrder, aResult, false );
5865 return aResult._retn();
5868 //=============================================================================
5870 * \brief Finds concurrent sub-meshes
5872 //=============================================================================
5874 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5876 TListOfListOfInt anOrder;
5877 ::SMESH_Mesh& mesh = GetImpl();
5879 // collect submeshes and detect concurrent algorithms and hypothesises
5880 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5882 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5883 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5884 ::SMESH_subMesh* sm = (*i_sm).second;
5886 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5888 // list of assigned hypothesises
5889 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5890 // Find out dimensions where the submesh can be concurrent.
5891 // We define the dimensions by algo of each of hypotheses in hypList
5892 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5893 for( ; hypIt != hypList.end(); hypIt++ ) {
5894 SMESH_Algo* anAlgo = 0;
5895 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5896 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5897 // hyp it-self is algo
5898 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5900 // try to find algorithm with help of sub-shapes
5901 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5902 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5903 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5906 continue; // no algorithm assigned to a current submesh
5908 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5909 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5911 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5912 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5913 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5915 } // end iterations on submesh
5917 // iterate on created dimension-hypotheses and check for concurrents
5918 for ( int i = 0; i < 4; i++ ) {
5919 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5920 // check for concurrents in own and other dimensions (step-by-step)
5921 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5922 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5923 const SMESH_DimHyp* dimHyp = *dhIt;
5924 TDimHypList listOfConcurr;
5925 set<int> setOfConcurrIds;
5926 // looking for concurrents and collect into own list
5927 for ( int j = i; j < 4; j++ )
5928 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5929 // check if any concurrents found
5930 if ( listOfConcurr.size() > 0 ) {
5931 // add own submesh to list of concurrent
5932 addInOrderOfPriority( dimHyp, listOfConcurr );
5933 list<int> listOfConcurrIds;
5934 TDimHypList::iterator hypIt = listOfConcurr.begin();
5935 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5936 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5937 anOrder.push_back( listOfConcurrIds );
5942 removeDimHyps(dimHypListArr);
5944 // now, minimize the number of concurrent groups
5945 // Here we assume that lists of submeshes can have same submesh
5946 // in case of multi-dimension algorithms, as result
5947 // list with common submesh has to be united into one list
5949 TListOfListOfInt::iterator listIt = anOrder.begin();
5950 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5951 unionLists( *listIt, anOrder, listIndx + 1 );
5957 //=============================================================================
5959 * \brief Set submesh object order
5960 * \param theSubMeshArray submesh array order
5962 //=============================================================================
5964 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5967 _preMeshInfo->ForgetOrLoad();
5970 ::SMESH_Mesh& mesh = GetImpl();
5972 TPythonDump aPythonDump; // prevent dump of called methods
5973 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5975 TListOfListOfInt subMeshOrder;
5976 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5978 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5979 TListOfInt subMeshIds;
5981 aPythonDump << ", ";
5982 aPythonDump << "[ ";
5983 // Collect subMeshes which should be clear
5984 // do it list-by-list, because modification of submesh order
5985 // take effect between concurrent submeshes only
5986 set<const SMESH_subMesh*> subMeshToClear;
5987 list<const SMESH_subMesh*> subMeshList;
5988 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5990 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5992 aPythonDump << ", ";
5993 aPythonDump << subMesh;
5994 subMeshIds.push_back( subMesh->GetId() );
5995 // detect common parts of submeshes
5996 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5997 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5999 aPythonDump << " ]";
6000 subMeshOrder.push_back( subMeshIds );
6002 // clear collected submeshes
6003 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6004 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6005 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6006 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6008 aPythonDump << " ])";
6010 mesh.SetMeshOrder( subMeshOrder );
6013 SMESH::SMESH_Mesh_var me = _this();
6014 _gen_i->UpdateIcons( me );
6019 //=============================================================================
6021 * \brief Convert submesh ids into submesh interfaces
6023 //=============================================================================
6025 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6026 SMESH::submesh_array_array& theResOrder,
6027 const bool theIsDump)
6029 int nbSet = theIdsOrder.size();
6030 TPythonDump aPythonDump; // prevent dump of called methods
6032 aPythonDump << "[ ";
6033 theResOrder.length(nbSet);
6034 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6036 for( ; it != theIdsOrder.end(); it++ ) {
6037 // translate submesh identificators into submesh objects
6038 // takeing into account real number of concurrent lists
6039 const TListOfInt& aSubOrder = (*it);
6040 if (!aSubOrder.size())
6043 aPythonDump << "[ ";
6044 // convert shape indices into interfaces
6045 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6046 aResSubSet->length(aSubOrder.size());
6047 TListOfInt::const_iterator subIt = aSubOrder.begin();
6049 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6050 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6052 SMESH::SMESH_subMesh_var subMesh =
6053 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6056 aPythonDump << ", ";
6057 aPythonDump << subMesh;
6059 aResSubSet[ j++ ] = subMesh;
6062 aPythonDump << " ]";
6064 theResOrder[ listIndx++ ] = aResSubSet;
6066 // correct number of lists
6067 theResOrder.length( listIndx );
6070 // finilise python dump
6071 aPythonDump << " ]";
6072 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6076 namespace // utils used by SMESH_MeshPartDS
6079 * \brief Class used to access to protected data of SMDS_MeshInfo
6081 struct TMeshInfo : public SMDS_MeshInfo
6083 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6086 * \brief Element holing its ID only
6088 struct TElemID : public SMDS_LinearEdge
6090 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6094 //================================================================================
6096 // Implementation of SMESH_MeshPartDS
6098 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6099 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6101 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6102 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6105 _meshDS = mesh_i->GetImpl().GetMeshDS();
6107 SetPersistentId( _meshDS->GetPersistentId() );
6109 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6111 // <meshPart> is the whole mesh
6112 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6114 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6115 myGroupSet = _meshDS->GetGroups();
6120 SMESH::long_array_var anIDs = meshPart->GetIDs();
6121 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6122 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6124 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6125 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6126 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6131 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6132 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6133 if ( _elements[ e->GetType() ].insert( e ).second )
6136 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6137 while ( nIt->more() )
6139 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6140 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6147 ShapeToMesh( _meshDS->ShapeToMesh() );
6149 _meshDS = 0; // to enforce iteration on _elements and _nodes
6152 // -------------------------------------------------------------------------------------
6153 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6154 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6157 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6158 for ( ; partIt != meshPart.end(); ++partIt )
6159 if ( const SMDS_MeshElement * e = *partIt )
6160 if ( _elements[ e->GetType() ].insert( e ).second )
6163 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6164 while ( nIt->more() )
6166 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6167 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6173 // -------------------------------------------------------------------------------------
6174 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6176 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6178 TElemID elem( IDelem );
6179 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6180 if ( !_elements[ iType ].empty() )
6182 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6183 if ( it != _elements[ iType ].end() )
6188 // -------------------------------------------------------------------------------------
6189 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6191 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6193 typedef SMDS_SetIterator
6194 <const SMDS_MeshElement*,
6195 TIDSortedElemSet::const_iterator,
6196 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6197 SMDS_MeshElement::GeomFilter
6200 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6202 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6203 _elements[type].end(),
6204 SMDS_MeshElement::GeomFilter( geomType )));
6206 // -------------------------------------------------------------------------------------
6207 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6209 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6211 typedef SMDS_SetIterator
6212 <const SMDS_MeshElement*,
6213 TIDSortedElemSet::const_iterator,
6214 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6215 SMDS_MeshElement::EntityFilter
6218 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6220 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6221 _elements[type].end(),
6222 SMDS_MeshElement::EntityFilter( entity )));
6224 // -------------------------------------------------------------------------------------
6225 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6227 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6228 if ( type == SMDSAbs_All && !_meshDS )
6230 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6232 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6233 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6235 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6237 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6238 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6240 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6241 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6243 // -------------------------------------------------------------------------------------
6244 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6245 iterType SMESH_MeshPartDS::methName() const \
6247 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6248 return _meshDS ? _meshDS->methName() : iterType \
6249 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6251 // -------------------------------------------------------------------------------------
6252 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6253 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6254 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6255 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6256 #undef _GET_ITER_DEFINE
6258 // END Implementation of SMESH_MeshPartDS
6260 //================================================================================