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 _medFileInfo = new SMESH::MedFileInfo();
449 _medFileInfo->fileName = theFileName;
450 _medFileInfo->major = 0;
451 _medFileInfo->minor = 0;
452 _medFileInfo->release = 0;
453 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
455 return ConvertDriverMEDReadStatus(status);
458 //=============================================================================
462 * Imports mesh data from MED file
464 //=============================================================================
466 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
467 throw ( SALOME::SALOME_Exception )
471 // Read mesh with name = <theMeshName> into SMESH_Mesh
472 _impl->UNVToMesh( theFileName );
474 CreateGroupServants();
476 _medFileInfo = new SMESH::MedFileInfo();
477 _medFileInfo->fileName = theFileName;
478 _medFileInfo->major = 0;
479 _medFileInfo->minor = 0;
480 _medFileInfo->release = 0;
481 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
483 SMESH_CATCH( SMESH::throwCorbaException );
488 //=============================================================================
492 * Imports mesh data from STL file
494 //=============================================================================
495 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
496 throw ( SALOME::SALOME_Exception )
500 // Read mesh with name = <theMeshName> into SMESH_Mesh
501 std::string name = _impl->STLToMesh( theFileName );
504 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
505 _gen_i->SetName( meshSO, name.c_str() );
507 _medFileInfo = new SMESH::MedFileInfo();
508 _medFileInfo->fileName = theFileName;
509 _medFileInfo->major = 0;
510 _medFileInfo->minor = 0;
511 _medFileInfo->release = 0;
512 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
514 SMESH_CATCH( SMESH::throwCorbaException );
519 //================================================================================
521 * \brief Function used in SMESH_CATCH by ImportGMFFile()
523 //================================================================================
527 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
529 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
533 //================================================================================
535 * \brief Imports data from a GMF file and returns an error description
537 //================================================================================
539 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
540 bool theMakeRequiredGroups )
541 throw (SALOME::SALOME_Exception)
543 SMESH_ComputeErrorPtr error;
546 #define SMESH_CAUGHT error =
549 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
551 _medFileInfo = new SMESH::MedFileInfo();
552 _medFileInfo->fileName = theFileName;
553 _medFileInfo->major = 0;
554 _medFileInfo->minor = 0;
555 _medFileInfo->release = 0;
556 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
558 SMESH_CATCH( exceptionToComputeError );
562 CreateGroupServants();
564 return ConvertComputeError( error );
567 //=============================================================================
571 //=============================================================================
573 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
575 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
576 (SMESH_Hypothesis::Hypothesis_Status theStatus)
579 RETURNCASE( HYP_OK );
580 RETURNCASE( HYP_MISSING );
581 RETURNCASE( HYP_CONCURRENT );
582 RETURNCASE( HYP_BAD_PARAMETER );
583 RETURNCASE( HYP_HIDDEN_ALGO );
584 RETURNCASE( HYP_HIDING_ALGO );
585 RETURNCASE( HYP_UNKNOWN_FATAL );
586 RETURNCASE( HYP_INCOMPATIBLE );
587 RETURNCASE( HYP_NOTCONFORM );
588 RETURNCASE( HYP_ALREADY_EXIST );
589 RETURNCASE( HYP_BAD_DIM );
590 RETURNCASE( HYP_BAD_SUBSHAPE );
591 RETURNCASE( HYP_BAD_GEOMETRY );
592 RETURNCASE( HYP_NEED_SHAPE );
593 RETURNCASE( HYP_INCOMPAT_HYPS );
596 return SMESH::HYP_UNKNOWN_FATAL;
599 //=============================================================================
603 * calls internal addHypothesis() and then adds a reference to <anHyp> under
604 * the SObject actually having a reference to <aSubShape>.
605 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
607 //=============================================================================
609 SMESH::Hypothesis_Status
610 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
611 SMESH::SMESH_Hypothesis_ptr anHyp,
612 CORBA::String_out anErrorText)
613 throw(SALOME::SALOME_Exception)
615 Unexpect aCatch(SALOME_SalomeException);
617 _preMeshInfo->ForgetOrLoad();
620 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
621 anErrorText = error.c_str();
623 SMESH::SMESH_Mesh_var mesh( _this() );
624 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
626 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
627 _gen_i->UpdateIcons( mesh );
629 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
631 // Update Python script
632 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
633 << aSubShape << ", " << anHyp << " )";
635 return ConvertHypothesisStatus(status);
638 //=============================================================================
642 //=============================================================================
644 SMESH_Hypothesis::Hypothesis_Status
645 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
646 SMESH::SMESH_Hypothesis_ptr anHyp,
647 std::string* anErrorText)
649 if(MYDEBUG) MESSAGE("addHypothesis");
651 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
652 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
654 if (CORBA::is_nil( anHyp ))
655 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
657 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
660 TopoDS_Shape myLocSubShape;
661 //use PseudoShape in case if mesh has no shape
663 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
665 myLocSubShape = _impl->GetShapeToMesh();
667 const int hypId = anHyp->GetId();
669 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
670 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
672 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
674 // assure there is a corresponding submesh
675 if ( !_impl->IsMainShape( myLocSubShape )) {
676 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
677 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
678 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
681 else if ( anErrorText )
683 *anErrorText = error;
686 catch(SALOME_Exception & S_ex)
688 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
693 //=============================================================================
697 //=============================================================================
699 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
700 SMESH::SMESH_Hypothesis_ptr anHyp)
701 throw(SALOME::SALOME_Exception)
703 Unexpect aCatch(SALOME_SalomeException);
705 _preMeshInfo->ForgetOrLoad();
707 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
708 SMESH::SMESH_Mesh_var mesh = _this();
710 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
712 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
713 _gen_i->UpdateIcons( mesh );
715 // Update Python script
716 if(_impl->HasShapeToMesh())
717 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
718 << aSubShape << ", " << anHyp << " )";
720 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
723 return ConvertHypothesisStatus(status);
726 //=============================================================================
730 //=============================================================================
732 SMESH_Hypothesis::Hypothesis_Status
733 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
734 SMESH::SMESH_Hypothesis_ptr anHyp)
736 if(MYDEBUG) MESSAGE("removeHypothesis()");
738 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
739 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
741 if (CORBA::is_nil( anHyp ))
742 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
744 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
747 TopoDS_Shape myLocSubShape;
748 //use PseudoShape in case if mesh has no shape
749 if( _impl->HasShapeToMesh() )
750 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
752 myLocSubShape = _impl->GetShapeToMesh();
754 const int hypId = anHyp->GetId();
755 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
756 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
758 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
762 catch(SALOME_Exception & S_ex)
764 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
769 //=============================================================================
773 //=============================================================================
775 SMESH::ListOfHypothesis *
776 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
777 throw(SALOME::SALOME_Exception)
779 Unexpect aCatch(SALOME_SalomeException);
780 if (MYDEBUG) MESSAGE("GetHypothesisList");
781 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
782 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
784 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
787 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
788 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
789 myLocSubShape = _impl->GetShapeToMesh();
790 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
791 int i = 0, n = aLocalList.size();
794 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
795 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
796 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
798 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
799 if ( id_hypptr != _mapHypo.end() )
800 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
804 catch(SALOME_Exception & S_ex) {
805 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
808 return aList._retn();
811 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
813 Unexpect aCatch(SALOME_SalomeException);
814 if (MYDEBUG) MESSAGE("GetSubMeshes");
816 SMESH::submesh_array_var aList = new SMESH::submesh_array();
819 TPythonDump aPythonDump;
820 if ( !_mapSubMeshIor.empty() )
824 aList->length( _mapSubMeshIor.size() );
826 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
827 for ( ; it != _mapSubMeshIor.end(); it++ ) {
828 if ( CORBA::is_nil( it->second )) continue;
829 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
831 if (i > 1) aPythonDump << ", ";
832 aPythonDump << it->second;
836 catch(SALOME_Exception & S_ex) {
837 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
840 // Update Python script
841 if ( !_mapSubMeshIor.empty() )
842 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
844 return aList._retn();
847 //=============================================================================
851 //=============================================================================
853 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
854 const char* theName )
855 throw(SALOME::SALOME_Exception)
857 Unexpect aCatch(SALOME_SalomeException);
858 if (CORBA::is_nil(aSubShape))
859 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
861 SMESH::SMESH_subMesh_var subMesh;
862 SMESH::SMESH_Mesh_var aMesh = _this();
864 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
866 //Get or Create the SMESH_subMesh object implementation
868 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
870 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
872 TopoDS_Iterator it( myLocSubShape );
874 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
876 subMesh = getSubMesh( subMeshId );
878 // create a new subMesh object servant if there is none for the shape
879 if ( subMesh->_is_nil() )
880 subMesh = createSubMesh( aSubShape );
881 if ( _gen_i->CanPublishInStudy( subMesh ))
883 SALOMEDS::SObject_wrap aSO =
884 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
885 if ( !aSO->_is_nil()) {
886 // Update Python script
887 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
888 << aSubShape << ", '" << theName << "' )";
892 catch(SALOME_Exception & S_ex) {
893 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
895 return subMesh._retn();
898 //=============================================================================
902 //=============================================================================
904 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
905 throw (SALOME::SALOME_Exception)
909 if ( theSubMesh->_is_nil() )
912 GEOM::GEOM_Object_var aSubShape;
913 // Remove submesh's SObject
914 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
915 if ( !anSO->_is_nil() ) {
916 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
917 SALOMEDS::SObject_wrap anObj, aRef;
918 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
919 anObj->ReferencedObject( aRef.inout() ))
921 CORBA::Object_var obj = aRef->GetObject();
922 aSubShape = GEOM::GEOM_Object::_narrow( obj );
924 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
925 // aSubShape = theSubMesh->GetSubShape();
927 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
928 builder->RemoveObjectWithChildren( anSO );
930 // Update Python script
931 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
934 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
936 _preMeshInfo->ForgetOrLoad();
938 SMESH_CATCH( SMESH::throwCorbaException );
941 //=============================================================================
945 //=============================================================================
947 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
948 const char* theName )
949 throw(SALOME::SALOME_Exception)
951 Unexpect aCatch(SALOME_SalomeException);
953 _preMeshInfo->FullLoadFromFile();
955 SMESH::SMESH_Group_var aNewGroup =
956 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
958 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
960 SMESH::SMESH_Mesh_var mesh = _this();
961 SALOMEDS::SObject_wrap aSO =
962 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
963 if ( !aSO->_is_nil())
964 // Update Python script
965 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
966 << theElemType << ", '" << theName << "' )";
968 return aNewGroup._retn();
971 //=============================================================================
975 //=============================================================================
976 SMESH::SMESH_GroupOnGeom_ptr
977 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
979 GEOM::GEOM_Object_ptr theGeomObj)
980 throw(SALOME::SALOME_Exception)
982 Unexpect aCatch(SALOME_SalomeException);
984 _preMeshInfo->FullLoadFromFile();
986 SMESH::SMESH_GroupOnGeom_var aNewGroup;
988 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
989 if ( !aShape.IsNull() )
992 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
994 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
996 SMESH::SMESH_Mesh_var mesh = _this();
997 SALOMEDS::SObject_wrap aSO =
998 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
999 if ( !aSO->_is_nil())
1000 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1001 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1005 return aNewGroup._retn();
1008 //================================================================================
1010 * \brief Creates a group whose contents is defined by filter
1011 * \param theElemType - group type
1012 * \param theName - group name
1013 * \param theFilter - the filter
1014 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1016 //================================================================================
1018 SMESH::SMESH_GroupOnFilter_ptr
1019 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1020 const char* theName,
1021 SMESH::Filter_ptr theFilter )
1022 throw (SALOME::SALOME_Exception)
1024 Unexpect aCatch(SALOME_SalomeException);
1026 _preMeshInfo->FullLoadFromFile();
1028 if ( CORBA::is_nil( theFilter ))
1029 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1031 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1033 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1035 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1036 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1039 if ( !aNewGroup->_is_nil() )
1040 aNewGroup->SetFilter( theFilter );
1042 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1044 SMESH::SMESH_Mesh_var mesh = _this();
1045 SALOMEDS::SObject_wrap aSO =
1046 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1048 if ( !aSO->_is_nil())
1049 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1050 << theElemType << ", '" << theName << "', " << theFilter << " )";
1052 return aNewGroup._retn();
1055 //=============================================================================
1059 //=============================================================================
1061 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1062 throw (SALOME::SALOME_Exception)
1064 if ( theGroup->_is_nil() )
1069 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1073 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1074 if ( !aGroupSO->_is_nil() )
1076 // Update Python script
1077 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1079 // Remove group's SObject
1080 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1081 builder->RemoveObjectWithChildren( aGroupSO );
1083 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1085 // Remove the group from SMESH data structures
1086 removeGroup( aGroup->GetLocalID() );
1088 SMESH_CATCH( SMESH::throwCorbaException );
1091 //=============================================================================
1093 * Remove group with its contents
1095 //=============================================================================
1097 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1098 throw (SALOME::SALOME_Exception)
1102 _preMeshInfo->FullLoadFromFile();
1104 if ( theGroup->_is_nil() )
1107 vector<int> nodeIds; // to remove nodes becoming free
1108 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1109 if ( !isNodal && !theGroup->IsEmpty() )
1111 CORBA::Long elemID = theGroup->GetID( 1 );
1112 int nbElemNodes = GetElemNbNodes( elemID );
1113 if ( nbElemNodes > 0 )
1114 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1117 // Retrieve contents
1118 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1119 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1120 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1121 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1122 elems.assign( elemBeg, elemEnd );
1124 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1127 RemoveGroup( theGroup );
1130 for ( size_t i = 0; i < elems.size(); ++i )
1132 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1136 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1137 nodeIds.push_back( nIt->next()->GetID() );
1139 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1143 _impl->GetMeshDS()->RemoveElement( elems[i] );
1147 // Remove free nodes
1148 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1149 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1150 if ( n->NbInverseElements() == 0 )
1151 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1153 // Update Python script (theGroup must be alive for this)
1154 pyDump << SMESH::SMESH_Mesh_var(_this())
1155 << ".RemoveGroupWithContents( " << theGroup << " )";
1157 SMESH_CATCH( SMESH::throwCorbaException );
1160 //================================================================================
1162 * \brief Get the list of groups existing in the mesh
1163 * \retval SMESH::ListOfGroups * - list of groups
1165 //================================================================================
1167 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1169 Unexpect aCatch(SALOME_SalomeException);
1170 if (MYDEBUG) MESSAGE("GetGroups");
1172 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1175 TPythonDump aPythonDump;
1176 if ( !_mapGroups.empty() )
1178 aPythonDump << "[ ";
1180 aList->length( _mapGroups.size() );
1182 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1183 for ( ; it != _mapGroups.end(); it++ ) {
1184 if ( CORBA::is_nil( it->second )) continue;
1185 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1187 if (i > 1) aPythonDump << ", ";
1188 aPythonDump << it->second;
1192 catch(SALOME_Exception & S_ex) {
1193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1195 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1197 return aList._retn();
1200 //=============================================================================
1202 * Get number of groups existing in the mesh
1204 //=============================================================================
1206 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1208 Unexpect aCatch(SALOME_SalomeException);
1209 return _mapGroups.size();
1212 //=============================================================================
1214 * New group including all mesh elements present in initial groups is created.
1216 //=============================================================================
1218 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1219 SMESH::SMESH_GroupBase_ptr theGroup2,
1220 const char* theName )
1221 throw (SALOME::SALOME_Exception)
1223 SMESH::SMESH_Group_var aResGrp;
1227 _preMeshInfo->FullLoadFromFile();
1229 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1230 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1232 if ( theGroup1->GetType() != theGroup2->GetType() )
1233 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1238 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1239 if ( aResGrp->_is_nil() )
1240 return SMESH::SMESH_Group::_nil();
1242 aResGrp->AddFrom( theGroup1 );
1243 aResGrp->AddFrom( theGroup2 );
1245 // Update Python script
1246 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1247 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1249 SMESH_CATCH( SMESH::throwCorbaException );
1251 return aResGrp._retn();
1254 //=============================================================================
1256 * \brief New group including all mesh elements present in initial groups is created.
1257 * \param theGroups list of groups
1258 * \param theName name of group to be created
1259 * \return pointer to the new group
1261 //=============================================================================
1263 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1264 const char* theName )
1265 throw (SALOME::SALOME_Exception)
1267 SMESH::SMESH_Group_var aResGrp;
1270 _preMeshInfo->FullLoadFromFile();
1273 return SMESH::SMESH_Group::_nil();
1278 SMESH::ElementType aType = SMESH::ALL;
1279 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1281 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1282 if ( CORBA::is_nil( aGrp ) )
1284 if ( aType == SMESH::ALL )
1285 aType = aGrp->GetType();
1286 else if ( aType != aGrp->GetType() )
1287 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1290 if ( aType == SMESH::ALL )
1291 return SMESH::SMESH_Group::_nil();
1296 aResGrp = CreateGroup( aType, theName );
1297 if ( aResGrp->_is_nil() )
1298 return SMESH::SMESH_Group::_nil();
1300 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1301 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1303 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1304 if ( !CORBA::is_nil( aGrp ) )
1306 aResGrp->AddFrom( aGrp );
1307 if ( g > 0 ) pyDump << ", ";
1311 pyDump << " ], '" << theName << "' )";
1313 SMESH_CATCH( SMESH::throwCorbaException );
1315 return aResGrp._retn();
1318 //=============================================================================
1320 * New group is created. All mesh elements that are
1321 * present in both initial groups are added to the new one.
1323 //=============================================================================
1325 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1326 SMESH::SMESH_GroupBase_ptr theGroup2,
1327 const char* theName )
1328 throw (SALOME::SALOME_Exception)
1330 SMESH::SMESH_Group_var aResGrp;
1335 _preMeshInfo->FullLoadFromFile();
1337 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1338 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1340 if ( theGroup1->GetType() != theGroup2->GetType() )
1341 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1345 // Create Intersection
1346 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1347 if ( aResGrp->_is_nil() )
1348 return aResGrp._retn();
1350 SMESHDS_GroupBase* groupDS1 = 0;
1351 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1352 groupDS1 = grp_i->GetGroupDS();
1354 SMESHDS_GroupBase* groupDS2 = 0;
1355 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1356 groupDS2 = grp_i->GetGroupDS();
1358 SMESHDS_Group* resGroupDS = 0;
1359 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1360 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1362 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1364 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1365 while ( elemIt1->more() )
1367 const SMDS_MeshElement* e = elemIt1->next();
1368 if ( groupDS2->Contains( e ))
1369 resGroupDS->SMDSGroup().Add( e );
1372 // Update Python script
1373 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1374 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1376 SMESH_CATCH( SMESH::throwCorbaException );
1378 return aResGrp._retn();
1381 //=============================================================================
1383 \brief Intersect list of groups. New group is created. All mesh elements that
1384 are present in all initial groups simultaneously are added to the new one.
1385 \param theGroups list of groups
1386 \param theName name of group to be created
1387 \return pointer on the group
1389 //=============================================================================
1390 SMESH::SMESH_Group_ptr
1391 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1392 const char* theName )
1393 throw (SALOME::SALOME_Exception)
1395 SMESH::SMESH_Group_var aResGrp;
1400 _preMeshInfo->FullLoadFromFile();
1403 return SMESH::SMESH_Group::_nil();
1405 // check types and get SMESHDS_GroupBase's
1406 SMESH::ElementType aType = SMESH::ALL;
1407 vector< SMESHDS_GroupBase* > groupVec;
1408 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1410 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1411 if ( CORBA::is_nil( aGrp ) )
1413 if ( aType == SMESH::ALL )
1414 aType = aGrp->GetType();
1415 else if ( aType != aGrp->GetType() )
1416 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1419 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1420 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1422 if ( grpDS->IsEmpty() )
1427 groupVec.push_back( grpDS );
1430 if ( aType == SMESH::ALL ) // all groups are nil
1431 return SMESH::SMESH_Group::_nil();
1436 aResGrp = CreateGroup( aType, theName );
1438 SMESHDS_Group* resGroupDS = 0;
1439 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1440 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1441 if ( !resGroupDS || groupVec.empty() )
1442 return aResGrp._retn();
1445 size_t i, nb = groupVec.size();
1446 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1447 while ( elemIt1->more() )
1449 const SMDS_MeshElement* e = elemIt1->next();
1451 for ( i = 1; ( i < nb && inAll ); ++i )
1452 inAll = groupVec[i]->Contains( e );
1455 resGroupDS->SMDSGroup().Add( e );
1458 // Update Python script
1459 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1460 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1462 SMESH_CATCH( SMESH::throwCorbaException );
1464 return aResGrp._retn();
1467 //=============================================================================
1469 * New group is created. All mesh elements that are present in
1470 * a main group but is not present in a tool group are added to the new one
1472 //=============================================================================
1474 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1475 SMESH::SMESH_GroupBase_ptr theGroup2,
1476 const char* theName )
1477 throw (SALOME::SALOME_Exception)
1479 SMESH::SMESH_Group_var aResGrp;
1484 _preMeshInfo->FullLoadFromFile();
1486 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1487 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1489 if ( theGroup1->GetType() != theGroup2->GetType() )
1490 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1494 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1495 if ( aResGrp->_is_nil() )
1496 return aResGrp._retn();
1498 SMESHDS_GroupBase* groupDS1 = 0;
1499 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1500 groupDS1 = grp_i->GetGroupDS();
1502 SMESHDS_GroupBase* groupDS2 = 0;
1503 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1504 groupDS2 = grp_i->GetGroupDS();
1506 SMESHDS_Group* resGroupDS = 0;
1507 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1508 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1510 if ( groupDS1 && groupDS2 && resGroupDS )
1512 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1513 while ( elemIt1->more() )
1515 const SMDS_MeshElement* e = elemIt1->next();
1516 if ( !groupDS2->Contains( e ))
1517 resGroupDS->SMDSGroup().Add( e );
1520 // Update Python script
1521 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1522 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1524 SMESH_CATCH( SMESH::throwCorbaException );
1526 return aResGrp._retn();
1529 //=============================================================================
1531 \brief Cut lists of groups. New group is created. All mesh elements that are
1532 present in main groups but do not present in tool groups are added to the new one
1533 \param theMainGroups list of main groups
1534 \param theToolGroups list of tool groups
1535 \param theName name of group to be created
1536 \return pointer on the group
1538 //=============================================================================
1539 SMESH::SMESH_Group_ptr
1540 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1541 const SMESH::ListOfGroups& theToolGroups,
1542 const char* theName )
1543 throw (SALOME::SALOME_Exception)
1545 SMESH::SMESH_Group_var aResGrp;
1550 _preMeshInfo->FullLoadFromFile();
1553 return SMESH::SMESH_Group::_nil();
1555 // check types and get SMESHDS_GroupBase's
1556 SMESH::ElementType aType = SMESH::ALL;
1557 vector< SMESHDS_GroupBase* > toolGroupVec;
1558 vector< SMDS_ElemIteratorPtr > mainIterVec;
1560 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1562 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1563 if ( CORBA::is_nil( aGrp ) )
1565 if ( aType == SMESH::ALL )
1566 aType = aGrp->GetType();
1567 else if ( aType != aGrp->GetType() )
1568 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1570 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1571 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1572 if ( !grpDS->IsEmpty() )
1573 mainIterVec.push_back( grpDS->GetElements() );
1575 if ( aType == SMESH::ALL ) // all main groups are nil
1576 return SMESH::SMESH_Group::_nil();
1577 if ( mainIterVec.empty() ) // all main groups are empty
1578 return aResGrp._retn();
1580 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1582 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1583 if ( CORBA::is_nil( aGrp ) )
1585 if ( aType != aGrp->GetType() )
1586 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1588 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1589 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1590 toolGroupVec.push_back( grpDS );
1596 aResGrp = CreateGroup( aType, theName );
1598 SMESHDS_Group* resGroupDS = 0;
1599 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1600 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1602 return aResGrp._retn();
1605 size_t i, nb = toolGroupVec.size();
1606 SMDS_ElemIteratorPtr mainElemIt
1607 ( new SMDS_IteratorOnIterators
1608 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1609 while ( mainElemIt->more() )
1611 const SMDS_MeshElement* e = mainElemIt->next();
1613 for ( i = 0; ( i < nb && !isIn ); ++i )
1614 isIn = toolGroupVec[i]->Contains( e );
1617 resGroupDS->SMDSGroup().Add( e );
1620 // Update Python script
1621 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1622 << ".CutListOfGroups( " << theMainGroups << ", "
1623 << theToolGroups << ", '" << theName << "' )";
1625 SMESH_CATCH( SMESH::throwCorbaException );
1627 return aResGrp._retn();
1630 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1632 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1633 bool & toStopChecking )
1635 toStopChecking = ( nbCommon < nbChecked );
1636 return nbCommon == nbNodes;
1638 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1639 bool & toStopChecking )
1641 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1642 return nbCommon == nbCorners;
1644 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1645 bool & toStopChecking )
1647 return nbCommon > 0;
1649 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1650 bool & toStopChecking )
1652 return nbCommon >= (nbNodes+1) / 2;
1656 //=============================================================================
1658 * Create a group of entities basing on nodes of other groups.
1659 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1660 * \param [in] anElemType - a type of elements to include to the new group.
1661 * \param [in] theName - a name of the new group.
1662 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1663 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1664 * new group provided that it is based on nodes of an element of \a aListOfGroups
1665 * \return SMESH_Group - the created group
1667 // IMP 19939, bug 22010, IMP 22635
1668 //=============================================================================
1670 SMESH::SMESH_Group_ptr
1671 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1672 SMESH::ElementType theElemType,
1673 const char* theName,
1674 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1675 CORBA::Boolean theUnderlyingOnly)
1676 throw (SALOME::SALOME_Exception)
1678 SMESH::SMESH_Group_var aResGrp;
1682 _preMeshInfo->FullLoadFromFile();
1684 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1686 if ( !theName || !aMeshDS )
1687 return SMESH::SMESH_Group::_nil();
1689 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1691 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1692 SMESH_Comment nbCoNoStr( "SMESH.");
1693 switch ( theNbCommonNodes ) {
1694 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1695 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1696 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1697 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1698 default: return aResGrp._retn();
1700 int nbChecked, nbCommon, nbNodes, nbCorners;
1706 aResGrp = CreateGroup( theElemType, theName );
1707 if ( aResGrp->_is_nil() )
1708 return SMESH::SMESH_Group::_nil();
1710 SMESHDS_GroupBase* groupBaseDS =
1711 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1712 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1714 vector<bool> isNodeInGroups;
1716 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1718 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1719 if ( CORBA::is_nil( aGrp ) )
1721 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1722 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1725 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1726 if ( !elIt ) continue;
1728 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1730 while ( elIt->more() ) {
1731 const SMDS_MeshElement* el = elIt->next();
1732 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1733 while ( nIt->more() )
1734 resGroupCore.Add( nIt->next() );
1737 // get elements of theElemType based on nodes of every element of group
1738 else if ( theUnderlyingOnly )
1740 while ( elIt->more() )
1742 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1743 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1744 TIDSortedElemSet checkedElems;
1745 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1746 while ( nIt->more() )
1748 const SMDS_MeshNode* n = nIt->next();
1749 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1750 // check nodes of elements of theElemType around el
1751 while ( elOfTypeIt->more() )
1753 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1754 if ( !checkedElems.insert( elOfType ).second ) continue;
1755 nbNodes = elOfType->NbNodes();
1756 nbCorners = elOfType->NbCornerNodes();
1758 bool toStopChecking = false;
1759 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1760 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1761 if ( elNodes.count( nIt2->next() ) &&
1762 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1764 resGroupCore.Add( elOfType );
1771 // get all nodes of elements of groups
1774 while ( elIt->more() )
1776 const SMDS_MeshElement* el = elIt->next(); // an element of group
1777 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1778 while ( nIt->more() )
1780 const SMDS_MeshNode* n = nIt->next();
1781 if ( n->GetID() >= (int) isNodeInGroups.size() )
1782 isNodeInGroups.resize( n->GetID() + 1, false );
1783 isNodeInGroups[ n->GetID() ] = true;
1789 // Get elements of theElemType based on a certain number of nodes of elements of groups
1790 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1792 const SMDS_MeshNode* n;
1793 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1794 const int isNodeInGroupsSize = isNodeInGroups.size();
1795 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1797 if ( !isNodeInGroups[ iN ] ||
1798 !( n = aMeshDS->FindNode( iN )))
1801 // check nodes of elements of theElemType around n
1802 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1803 while ( elOfTypeIt->more() )
1805 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1806 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1811 nbNodes = elOfType->NbNodes();
1812 nbCorners = elOfType->NbCornerNodes();
1814 bool toStopChecking = false;
1815 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1816 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1818 const int nID = nIt->next()->GetID();
1819 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1820 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1822 resGroupCore.Add( elOfType );
1830 // Update Python script
1831 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1832 << ".CreateDimGroup( "
1833 << theGroups << ", " << theElemType << ", '" << theName << "', "
1834 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1836 SMESH_CATCH( SMESH::throwCorbaException );
1838 return aResGrp._retn();
1841 //================================================================================
1843 * \brief Remember GEOM group data
1845 //================================================================================
1847 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1848 CORBA::Object_ptr theSmeshObj)
1850 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1853 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1854 if ( groupSO->_is_nil() )
1857 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1858 GEOM::GEOM_IGroupOperations_wrap groupOp =
1859 geomGen->GetIGroupOperations();
1860 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1863 _geomGroupData.push_back( TGeomGroupData() );
1864 TGeomGroupData & groupData = _geomGroupData.back();
1866 CORBA::String_var entry = groupSO->GetID();
1867 groupData._groupEntry = entry.in();
1869 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1870 groupData._indices.insert( ids[i] );
1872 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1873 // shape index in SMESHDS
1874 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1875 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1878 //================================================================================
1880 * Remove GEOM group data relating to removed smesh object
1882 //================================================================================
1884 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1886 list<TGeomGroupData>::iterator
1887 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1888 for ( ; data != dataEnd; ++data ) {
1889 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1890 _geomGroupData.erase( data );
1896 //================================================================================
1898 * \brief Return new group contents if it has been changed and update group data
1900 //================================================================================
1902 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1904 TopoDS_Shape newShape;
1907 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1908 if ( !groupSO->_is_nil() )
1910 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1911 if ( CORBA::is_nil( groupObj )) return newShape;
1912 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1914 // get indices of group items
1915 set<int> curIndices;
1916 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1917 GEOM::GEOM_IGroupOperations_wrap groupOp =
1918 geomGen->GetIGroupOperations();
1919 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1920 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1921 curIndices.insert( ids[i] );
1923 if ( groupData._indices == curIndices )
1924 return newShape; // group not changed
1927 groupData._indices = curIndices;
1929 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1930 if ( !geomClient ) return newShape;
1931 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1932 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1933 newShape = _gen_i->GeomObjectToShape( geomGroup );
1936 if ( newShape.IsNull() ) {
1937 // geom group becomes empty - return empty compound
1938 TopoDS_Compound compound;
1939 BRep_Builder().MakeCompound(compound);
1940 newShape = compound;
1947 //-----------------------------------------------------------------------------
1949 * \brief Storage of shape and index used in CheckGeomGroupModif()
1951 struct TIndexedShape
1954 TopoDS_Shape _shape;
1955 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1957 //-----------------------------------------------------------------------------
1959 * \brief Data to re-create a group on geometry
1961 struct TGroupOnGeomData
1965 SMDSAbs_ElementType _type;
1967 Quantity_Color _color;
1971 //=============================================================================
1973 * \brief Update data if geometry changes
1977 //=============================================================================
1979 void SMESH_Mesh_i::CheckGeomModif()
1981 if ( !_impl->HasShapeToMesh() ) return;
1983 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1984 //if ( mainGO->_is_nil() ) return;
1986 // Update after group modification
1988 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1989 called by other mesh (IPAL52735) */
1990 mainGO->GetType() == GEOM_GROUP ||
1991 mainGO->GetTick() == _mainShapeTick )
1993 CheckGeomGroupModif();
1997 // Update after shape transformation like Translate
1999 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2000 if ( !geomClient ) return;
2001 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2002 if ( geomGen->_is_nil() ) return;
2004 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2005 geomClient->RemoveShapeFromBuffer( ior.in() );
2007 // Update data taking into account that
2008 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2011 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2012 if ( newShape.IsNull() )
2015 _mainShapeTick = mainGO->GetTick();
2017 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2019 // store data of groups on geometry
2020 vector< TGroupOnGeomData > groupsData;
2021 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2022 groupsData.reserve( groups.size() );
2023 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2024 for ( ; g != groups.end(); ++g )
2025 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2027 TGroupOnGeomData data;
2028 data._oldID = group->GetID();
2029 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2030 data._type = group->GetType();
2031 data._name = group->GetStoreName();
2032 data._color = group->GetColor();
2033 groupsData.push_back( data );
2035 // store assigned hypotheses
2036 vector< pair< int, THypList > > ids2Hyps;
2037 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2038 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2040 const TopoDS_Shape& s = s2hyps.Key();
2041 const THypList& hyps = s2hyps.ChangeValue();
2042 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2045 // change shape to mesh
2046 int oldNbSubShapes = meshDS->MaxShapeIndex();
2047 _impl->ShapeToMesh( TopoDS_Shape() );
2048 _impl->ShapeToMesh( newShape );
2050 // re-add shapes of geom groups
2051 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2052 for ( ; data != _geomGroupData.end(); ++data )
2054 TopoDS_Shape newShape = newGroupShape( *data );
2055 if ( !newShape.IsNull() )
2057 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2059 TopoDS_Compound compound;
2060 BRep_Builder().MakeCompound( compound );
2061 BRep_Builder().Add( compound, newShape );
2062 newShape = compound;
2064 _impl->GetSubMesh( newShape );
2067 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2068 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2069 SALOME::INTERNAL_ERROR );
2071 // re-assign hypotheses
2072 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2074 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2075 const THypList& hyps = ids2Hyps[i].second;
2076 THypList::const_iterator h = hyps.begin();
2077 for ( ; h != hyps.end(); ++h )
2078 _impl->AddHypothesis( s, (*h)->GetID() );
2082 for ( size_t i = 0; i < groupsData.size(); ++i )
2084 const TGroupOnGeomData& data = groupsData[i];
2086 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2087 if ( i2g == _mapGroups.end() ) continue;
2089 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2090 if ( !gr_i ) continue;
2093 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2094 meshDS->IndexToShape( data._shapeID ));
2097 _mapGroups.erase( i2g );
2101 g->GetGroupDS()->SetColor( data._color );
2102 gr_i->changeLocalId( id );
2103 _mapGroups[ id ] = i2g->second;
2104 if ( data._oldID != id )
2105 _mapGroups.erase( i2g );
2109 // update _mapSubMesh
2110 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2111 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2112 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2116 //=============================================================================
2118 * \brief Update objects depending on changed geom groups
2120 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2121 * issue 0020210: Update of a smesh group after modification of the associated geom group
2123 //=============================================================================
2125 void SMESH_Mesh_i::CheckGeomGroupModif()
2127 if ( !_impl->HasShapeToMesh() ) return;
2129 CORBA::Long nbEntities = NbNodes() + NbElements();
2131 // Check if group contents changed
2133 typedef map< string, TopoDS_Shape > TEntry2Geom;
2134 TEntry2Geom newGroupContents;
2136 list<TGeomGroupData>::iterator
2137 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2138 for ( ; data != dataEnd; ++data )
2140 pair< TEntry2Geom::iterator, bool > it_new =
2141 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2142 bool processedGroup = !it_new.second;
2143 TopoDS_Shape& newShape = it_new.first->second;
2144 if ( !processedGroup )
2145 newShape = newGroupShape( *data );
2146 if ( newShape.IsNull() )
2147 continue; // no changes
2150 _preMeshInfo->ForgetOrLoad();
2152 if ( processedGroup ) { // update group indices
2153 list<TGeomGroupData>::iterator data2 = data;
2154 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2155 data->_indices = data2->_indices;
2158 // Update SMESH objects according to new GEOM group contents
2160 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2161 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2163 int oldID = submesh->GetId();
2164 if ( !_mapSubMeshIor.count( oldID ))
2166 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2168 // update hypotheses
2169 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2170 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2171 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2173 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2174 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2176 // care of submeshes
2177 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2178 int newID = newSubmesh->GetId();
2179 if ( newID != oldID ) {
2180 _mapSubMesh [ newID ] = newSubmesh;
2181 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2182 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2183 _mapSubMesh. erase(oldID);
2184 _mapSubMesh_i. erase(oldID);
2185 _mapSubMeshIor.erase(oldID);
2186 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2191 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2192 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2193 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2195 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2197 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2198 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2199 ds->SetShape( newShape );
2204 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2205 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2207 // Remove groups and submeshes basing on removed sub-shapes
2209 TopTools_MapOfShape newShapeMap;
2210 TopoDS_Iterator shapeIt( newShape );
2211 for ( ; shapeIt.More(); shapeIt.Next() )
2212 newShapeMap.Add( shapeIt.Value() );
2214 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2215 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2217 if ( newShapeMap.Contains( shapeIt.Value() ))
2219 TopTools_IndexedMapOfShape oldShapeMap;
2220 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2221 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2223 const TopoDS_Shape& oldShape = oldShapeMap(i);
2224 int oldInd = meshDS->ShapeToIndex( oldShape );
2226 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2227 if ( i_smIor != _mapSubMeshIor.end() ) {
2228 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2231 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2232 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2234 // check if a group bases on oldInd shape
2235 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2236 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2237 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2238 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2240 RemoveGroup( i_grp->second ); // several groups can base on same shape
2241 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2246 // Reassign hypotheses and update groups after setting the new shape to mesh
2248 // collect anassigned hypotheses
2249 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2250 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2251 TShapeHypList assignedHyps;
2252 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2254 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2255 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2256 if ( !hyps.empty() ) {
2257 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2258 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2259 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2262 // collect shapes supporting groups
2263 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2264 TShapeTypeList groupData;
2265 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2266 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2267 for ( ; grIt != groups.end(); ++grIt )
2269 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2271 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2273 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2275 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2276 _impl->ShapeToMesh( newShape );
2278 // reassign hypotheses
2279 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2280 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2282 TIndexedShape& geom = indS_hyps->first;
2283 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2284 int oldID = geom._index;
2285 int newID = meshDS->ShapeToIndex( geom._shape );
2286 if ( oldID == 1 ) { // main shape
2288 geom._shape = newShape;
2292 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2293 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2294 // care of sub-meshes
2295 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2296 if ( newID != oldID ) {
2297 _mapSubMesh [ newID ] = newSubmesh;
2298 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2299 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2300 _mapSubMesh. erase(oldID);
2301 _mapSubMesh_i. erase(oldID);
2302 _mapSubMeshIor.erase(oldID);
2303 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2307 TShapeTypeList::iterator geomType = groupData.begin();
2308 for ( ; geomType != groupData.end(); ++geomType )
2310 const TIndexedShape& geom = geomType->first;
2311 int oldID = geom._index;
2312 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2315 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2316 CORBA::String_var name = groupSO->GetName();
2318 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2320 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2321 group_i->changeLocalId( newID );
2324 break; // everything has been updated
2327 } // loop on group data
2331 CORBA::Long newNbEntities = NbNodes() + NbElements();
2332 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2333 if ( newNbEntities != nbEntities )
2335 // Add all SObjects with icons to soToUpdateIcons
2336 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2338 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2339 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2340 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2342 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2343 i_gr != _mapGroups.end(); ++i_gr ) // groups
2344 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2347 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2348 for ( ; so != soToUpdateIcons.end(); ++so )
2349 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2352 //=============================================================================
2354 * \brief Create standalone group from a group on geometry or filter
2356 //=============================================================================
2358 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2359 throw (SALOME::SALOME_Exception)
2361 SMESH::SMESH_Group_var aGroup;
2366 _preMeshInfo->FullLoadFromFile();
2368 if ( theGroup->_is_nil() )
2369 return aGroup._retn();
2371 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2373 return aGroup._retn();
2375 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2377 const int anId = aGroupToRem->GetLocalID();
2378 if ( !_impl->ConvertToStandalone( anId ) )
2379 return aGroup._retn();
2380 removeGeomGroupData( theGroup );
2382 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2384 // remove old instance of group from own map
2385 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2386 _mapGroups.erase( anId );
2388 SALOMEDS::StudyBuilder_var builder;
2389 SALOMEDS::SObject_wrap aGroupSO;
2390 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2391 if ( !aStudy->_is_nil() ) {
2392 builder = aStudy->NewBuilder();
2393 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2394 if ( !aGroupSO->_is_nil() )
2396 // remove reference to geometry
2397 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2398 for ( ; chItr->More(); chItr->Next() )
2399 // Remove group's child SObject
2400 builder->RemoveObject( chItr->Value() );
2402 // Update Python script
2403 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2404 << ".ConvertToStandalone( " << aGroupSO << " )";
2406 // change icon of Group on Filter
2409 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2410 const int isEmpty = ( elemTypes->length() == 0 );
2413 SALOMEDS::GenericAttribute_wrap anAttr =
2414 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2415 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2416 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2422 // remember new group in own map
2423 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2424 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2426 // register CORBA object for persistence
2427 _gen_i->RegisterObject( aGroup );
2429 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2430 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2431 //aGroup->Register();
2432 aGroupToRem->UnRegister();
2434 SMESH_CATCH( SMESH::throwCorbaException );
2436 return aGroup._retn();
2439 //=============================================================================
2443 //=============================================================================
2445 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2447 if(MYDEBUG) MESSAGE( "createSubMesh" );
2448 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2449 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2450 const int subMeshId = mySubMesh->GetId();
2452 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2453 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2455 _mapSubMesh [subMeshId] = mySubMesh;
2456 _mapSubMesh_i [subMeshId] = subMeshServant;
2457 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2459 subMeshServant->Register();
2461 // register CORBA object for persistence
2462 int nextId = _gen_i->RegisterObject( subMesh );
2463 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2464 else { nextId = 0; } // avoid "unused variable" warning
2466 // to track changes of GEOM groups
2467 addGeomGroupData( theSubShapeObject, subMesh );
2469 return subMesh._retn();
2472 //=======================================================================
2473 //function : getSubMesh
2475 //=======================================================================
2477 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2479 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2480 if ( it == _mapSubMeshIor.end() )
2481 return SMESH::SMESH_subMesh::_nil();
2483 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2486 //=============================================================================
2490 //=============================================================================
2492 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2493 GEOM::GEOM_Object_ptr theSubShapeObject )
2495 bool isHypChanged = false;
2496 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2497 return isHypChanged;
2499 const int subMeshId = theSubMesh->GetId();
2501 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2503 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2505 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2508 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2509 isHypChanged = !hyps.empty();
2510 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2511 for ( ; hyp != hyps.end(); ++hyp )
2512 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2519 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2520 isHypChanged = ( aHypList->length() > 0 );
2521 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2522 removeHypothesis( theSubShapeObject, aHypList[i] );
2525 catch( const SALOME::SALOME_Exception& ) {
2526 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2528 removeGeomGroupData( theSubShapeObject );
2532 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2533 if ( id_smi != _mapSubMesh_i.end() )
2534 id_smi->second->UnRegister();
2536 // remove a CORBA object
2537 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2538 if ( id_smptr != _mapSubMeshIor.end() )
2539 SMESH::SMESH_subMesh_var( id_smptr->second );
2541 _mapSubMesh.erase(subMeshId);
2542 _mapSubMesh_i.erase(subMeshId);
2543 _mapSubMeshIor.erase(subMeshId);
2545 return isHypChanged;
2548 //=============================================================================
2552 //=============================================================================
2554 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2555 const char* theName,
2556 const TopoDS_Shape& theShape,
2557 const SMESH_PredicatePtr& thePredicate )
2559 std::string newName;
2560 if ( !theName || !theName[0] )
2562 std::set< std::string > presentNames;
2563 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2564 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2566 CORBA::String_var name = i_gr->second->GetName();
2567 presentNames.insert( name.in() );
2570 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2571 } while ( !presentNames.insert( newName ).second );
2572 theName = newName.c_str();
2575 SMESH::SMESH_GroupBase_var aGroup;
2576 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2578 SMESH_GroupBase_i* aGroupImpl;
2579 if ( !theShape.IsNull() )
2580 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2581 else if ( thePredicate )
2582 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2584 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2586 aGroup = aGroupImpl->_this();
2587 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2588 aGroupImpl->Register();
2590 // register CORBA object for persistence
2591 int nextId = _gen_i->RegisterObject( aGroup );
2592 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2593 else { nextId = 0; } // avoid "unused variable" warning in release mode
2595 // to track changes of GEOM groups
2596 if ( !theShape.IsNull() ) {
2597 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2598 addGeomGroupData( geom, aGroup );
2601 return aGroup._retn();
2604 //=============================================================================
2606 * SMESH_Mesh_i::removeGroup
2608 * Should be called by ~SMESH_Group_i()
2610 //=============================================================================
2612 void SMESH_Mesh_i::removeGroup( const int theId )
2614 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2615 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2616 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2617 _mapGroups.erase( theId );
2618 removeGeomGroupData( group );
2619 if ( !_impl->RemoveGroup( theId ))
2621 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2622 RemoveGroup( group );
2624 group->UnRegister();
2628 //=============================================================================
2632 //=============================================================================
2634 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2635 throw(SALOME::SALOME_Exception)
2637 SMESH::log_array_var aLog;
2641 _preMeshInfo->FullLoadFromFile();
2643 list < SMESHDS_Command * >logDS = _impl->GetLog();
2644 aLog = new SMESH::log_array;
2646 int lg = logDS.size();
2649 list < SMESHDS_Command * >::iterator its = logDS.begin();
2650 while(its != logDS.end()){
2651 SMESHDS_Command *com = *its;
2652 int comType = com->GetType();
2654 int lgcom = com->GetNumber();
2656 const list < int >&intList = com->GetIndexes();
2657 int inum = intList.size();
2659 list < int >::const_iterator ii = intList.begin();
2660 const list < double >&coordList = com->GetCoords();
2661 int rnum = coordList.size();
2663 list < double >::const_iterator ir = coordList.begin();
2664 aLog[indexLog].commandType = comType;
2665 aLog[indexLog].number = lgcom;
2666 aLog[indexLog].coords.length(rnum);
2667 aLog[indexLog].indexes.length(inum);
2668 for(int i = 0; i < rnum; i++){
2669 aLog[indexLog].coords[i] = *ir;
2670 //MESSAGE(" "<<i<<" "<<ir.Value());
2673 for(int i = 0; i < inum; i++){
2674 aLog[indexLog].indexes[i] = *ii;
2675 //MESSAGE(" "<<i<<" "<<ii.Value());
2684 SMESH_CATCH( SMESH::throwCorbaException );
2686 return aLog._retn();
2690 //=============================================================================
2694 //=============================================================================
2696 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2700 SMESH_CATCH( SMESH::throwCorbaException );
2703 //=============================================================================
2707 //=============================================================================
2709 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2714 //=============================================================================
2717 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2718 // issue 0020918: groups removal is caused by hyp modification
2719 // issue 0021208: to forget not loaded mesh data at hyp modification
2720 struct TCallUp_i : public SMESH_Mesh::TCallUp
2722 SMESH_Mesh_i* _mesh;
2723 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2724 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2725 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2726 virtual void Load () { _mesh->Load(); }
2730 //================================================================================
2732 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2734 //================================================================================
2736 void SMESH_Mesh_i::onHypothesisModified()
2739 _preMeshInfo->ForgetOrLoad();
2741 SMESH::SMESH_Mesh_var mesh = _this();
2742 _gen_i->UpdateIcons( mesh );
2745 //=============================================================================
2749 //=============================================================================
2751 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2753 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2756 _impl->SetCallUp( new TCallUp_i(this));
2759 //=============================================================================
2763 //=============================================================================
2765 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2767 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2771 //=============================================================================
2773 * Return mesh editor
2775 //=============================================================================
2777 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2778 throw (SALOME::SALOME_Exception)
2780 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2784 _preMeshInfo->FullLoadFromFile();
2786 // Create MeshEditor
2788 _editor = new SMESH_MeshEditor_i( this, false );
2789 aMeshEdVar = _editor->_this();
2791 // Update Python script
2792 TPythonDump() << _editor << " = "
2793 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2795 SMESH_CATCH( SMESH::throwCorbaException );
2797 return aMeshEdVar._retn();
2800 //=============================================================================
2802 * Return mesh edition previewer
2804 //=============================================================================
2806 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2807 throw (SALOME::SALOME_Exception)
2809 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2813 _preMeshInfo->FullLoadFromFile();
2815 if ( !_previewEditor )
2816 _previewEditor = new SMESH_MeshEditor_i( this, true );
2817 aMeshEdVar = _previewEditor->_this();
2819 SMESH_CATCH( SMESH::throwCorbaException );
2821 return aMeshEdVar._retn();
2824 //================================================================================
2826 * \brief Return true if the mesh has been edited since a last total re-compute
2827 * and those modifications may prevent successful partial re-compute
2829 //================================================================================
2831 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2833 Unexpect aCatch(SALOME_SalomeException);
2834 return _impl->HasModificationsToDiscard();
2837 //================================================================================
2839 * \brief Returns a random unique color
2841 //================================================================================
2843 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2845 const int MAX_ATTEMPTS = 100;
2847 double tolerance = 0.5;
2848 SALOMEDS::Color col;
2852 // generate random color
2853 double red = (double)rand() / RAND_MAX;
2854 double green = (double)rand() / RAND_MAX;
2855 double blue = (double)rand() / RAND_MAX;
2856 // check existence in the list of the existing colors
2857 bool matched = false;
2858 std::list<SALOMEDS::Color>::const_iterator it;
2859 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2860 SALOMEDS::Color color = *it;
2861 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2862 matched = tol < tolerance;
2864 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2865 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2873 //=============================================================================
2875 * Sets auto-color mode. If it is on, groups get unique random colors
2877 //=============================================================================
2879 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2881 Unexpect aCatch(SALOME_SalomeException);
2882 _impl->SetAutoColor(theAutoColor);
2884 TPythonDump pyDump; // not to dump group->SetColor() from below code
2885 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2887 std::list<SALOMEDS::Color> aReservedColors;
2888 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2889 for ( ; it != _mapGroups.end(); it++ ) {
2890 if ( CORBA::is_nil( it->second )) continue;
2891 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2892 it->second->SetColor( aColor );
2893 aReservedColors.push_back( aColor );
2897 //=============================================================================
2899 * Returns true if auto-color mode is on
2901 //=============================================================================
2903 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2905 Unexpect aCatch(SALOME_SalomeException);
2906 return _impl->GetAutoColor();
2909 //=============================================================================
2911 * Checks if there are groups with equal names
2913 //=============================================================================
2915 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2917 return _impl->HasDuplicatedGroupNamesMED();
2920 //================================================================================
2922 * \brief Care of a file before exporting mesh into it
2924 //================================================================================
2926 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2928 SMESH_File aFile( file );
2930 if (aFile.exists()) {
2931 // existing filesystem node
2932 if ( !aFile.isDirectory() ) {
2933 if ( aFile.openForWriting() ) {
2934 if ( overwrite && ! aFile.remove()) {
2935 msg << "Can't replace " << aFile.getName();
2938 msg << "Can't write into " << aFile.getName();
2941 msg << "Location " << aFile.getName() << " is not a file";
2945 // nonexisting file; check if it can be created
2946 if ( !aFile.openForWriting() ) {
2947 msg << "You cannot create the file "
2949 << ". Check the directory existence and access rights";
2957 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2961 //================================================================================
2963 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2964 * \param file - file name
2965 * \param overwrite - to erase the file or not
2966 * \retval string - mesh name
2968 //================================================================================
2970 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2971 CORBA::Boolean overwrite)
2974 PrepareForWriting(file, overwrite);
2975 string aMeshName = "Mesh";
2976 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2977 if ( !aStudy->_is_nil() ) {
2978 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2979 if ( !aMeshSO->_is_nil() ) {
2980 CORBA::String_var name = aMeshSO->GetName();
2982 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2983 if ( !aStudy->GetProperties()->IsLocked() )
2985 SALOMEDS::GenericAttribute_wrap anAttr;
2986 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2987 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2988 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2989 ASSERT(!aFileName->_is_nil());
2990 aFileName->SetValue(file);
2991 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2992 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2993 ASSERT(!aFileType->_is_nil());
2994 aFileType->SetValue("FICHIERMED");
2998 // Update Python script
2999 // set name of mesh before export
3000 TPythonDump() << _gen_i << ".SetName("
3001 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3003 // check names of groups
3009 //================================================================================
3011 * \brief Export to MED file
3013 //================================================================================
3015 void SMESH_Mesh_i::ExportMED(const char* file,
3016 CORBA::Boolean auto_groups,
3017 CORBA::Boolean overwrite,
3018 CORBA::Boolean autoDimension)
3019 throw(SALOME::SALOME_Exception)
3021 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3024 _preMeshInfo->FullLoadFromFile();
3026 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3027 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, 0, autoDimension );
3029 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3030 << file << "', " << auto_groups << ", "
3031 << overwrite << ", "
3032 << autoDimension << " )";
3034 SMESH_CATCH( SMESH::throwCorbaException );
3037 //================================================================================
3039 * \brief Export a mesh to a SAUV file
3041 //================================================================================
3043 void SMESH_Mesh_i::ExportSAUV (const char* file,
3044 CORBA::Boolean auto_groups)
3045 throw(SALOME::SALOME_Exception)
3047 Unexpect aCatch(SALOME_SalomeException);
3049 _preMeshInfo->FullLoadFromFile();
3051 string aMeshName = prepareMeshNameAndGroups(file, true);
3052 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3053 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3054 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3058 //================================================================================
3060 * \brief Export a mesh to a DAT file
3062 //================================================================================
3064 void SMESH_Mesh_i::ExportDAT (const char *file)
3065 throw(SALOME::SALOME_Exception)
3067 Unexpect aCatch(SALOME_SalomeException);
3069 _preMeshInfo->FullLoadFromFile();
3071 // Update Python script
3072 // check names of groups
3074 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3077 PrepareForWriting(file);
3078 _impl->ExportDAT(file);
3081 //================================================================================
3083 * \brief Export a mesh to an UNV file
3085 //================================================================================
3087 void SMESH_Mesh_i::ExportUNV (const char *file)
3088 throw(SALOME::SALOME_Exception)
3090 Unexpect aCatch(SALOME_SalomeException);
3092 _preMeshInfo->FullLoadFromFile();
3094 // Update Python script
3095 // check names of groups
3097 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3100 PrepareForWriting(file);
3101 _impl->ExportUNV(file);
3104 //================================================================================
3106 * \brief Export a mesh to an STL file
3108 //================================================================================
3110 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3111 throw(SALOME::SALOME_Exception)
3113 Unexpect aCatch(SALOME_SalomeException);
3115 _preMeshInfo->FullLoadFromFile();
3117 // Update Python script
3118 // check names of groups
3120 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3121 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3123 CORBA::String_var name;
3124 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3125 if ( !so->_is_nil() )
3126 name = so->GetName();
3129 PrepareForWriting( file );
3130 _impl->ExportSTL( file, isascii, name.in() );
3133 //================================================================================
3135 * \brief Export a part of mesh to a med file
3137 //================================================================================
3139 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3141 CORBA::Boolean auto_groups,
3142 CORBA::Boolean overwrite,
3143 CORBA::Boolean autoDimension,
3144 const GEOM::ListOfFields& fields,
3145 const char* geomAssocFields)
3146 throw (SALOME::SALOME_Exception)
3150 _preMeshInfo->FullLoadFromFile();
3153 bool have0dField = false;
3154 if ( fields.length() > 0 )
3156 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3157 if ( shapeToMesh->_is_nil() )
3158 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3160 for ( size_t i = 0; i < fields.length(); ++i )
3162 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3163 THROW_SALOME_CORBA_EXCEPTION
3164 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3165 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3166 if ( fieldShape->_is_nil() )
3167 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3168 if ( !fieldShape->IsSame( shapeToMesh ) )
3169 THROW_SALOME_CORBA_EXCEPTION
3170 ( "Field defined not on shape", SALOME::BAD_PARAM);
3171 if ( fields[i]->GetDimension() == 0 )
3174 if ( geomAssocFields )
3175 for ( int i = 0; geomAssocFields[i]; ++i )
3176 switch ( geomAssocFields[i] ) {
3177 case 'v':case 'e':case 'f':case 's': break;
3178 case 'V':case 'E':case 'F':case 'S': break;
3179 default: THROW_SALOME_CORBA_EXCEPTION
3180 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3184 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3188 string aMeshName = "Mesh";
3189 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3190 if ( CORBA::is_nil( meshPart ) ||
3191 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3193 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3194 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3195 0, autoDimension, /*addODOnVertices=*/have0dField);
3196 meshDS = _impl->GetMeshDS();
3201 _preMeshInfo->FullLoadFromFile();
3203 PrepareForWriting(file, overwrite);
3205 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3206 if ( !SO->_is_nil() ) {
3207 CORBA::String_var name = SO->GetName();
3211 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3212 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3213 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3214 meshDS = tmpDSDeleter._obj = partDS;
3219 if ( _impl->HasShapeToMesh() )
3221 DriverMED_W_Field fieldWriter;
3222 fieldWriter.SetFile( file );
3223 fieldWriter.SetMeshName( aMeshName );
3224 fieldWriter.AddODOnVertices( have0dField );
3226 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3230 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3231 goList->length( fields.length() );
3232 for ( size_t i = 0; i < fields.length(); ++i )
3234 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3237 TPythonDump() << _this() << ".ExportPartToMED( "
3238 << meshPart << ", r'" << file << "', "
3239 << auto_groups << ", " << overwrite << ", "
3240 << autoDimension << ", " << goList
3241 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3243 SMESH_CATCH( SMESH::throwCorbaException );
3246 //================================================================================
3248 * Write GEOM fields to MED file
3250 //================================================================================
3252 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3253 SMESHDS_Mesh* meshDS,
3254 const GEOM::ListOfFields& fields,
3255 const char* geomAssocFields)
3257 #define METH "SMESH_Mesh_i::exportMEDFields() "
3259 if (( fields.length() < 1 ) &&
3260 ( !geomAssocFields || !geomAssocFields[0] ))
3263 std::vector< std::vector< double > > dblVals;
3264 std::vector< std::vector< int > > intVals;
3265 std::vector< int > subIdsByDim[ 4 ];
3266 const double noneDblValue = 0.;
3267 const double noneIntValue = 0;
3269 for ( size_t iF = 0; iF < fields.length(); ++iF )
3273 int dim = fields[ iF ]->GetDimension();
3274 SMDSAbs_ElementType elemType;
3275 TopAbs_ShapeEnum shapeType;
3277 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3278 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3279 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3280 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3282 continue; // skip fields on whole shape
3284 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3285 if ( dataType == GEOM::FDT_String )
3287 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3288 if ( stepIDs->length() < 1 )
3290 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3291 if ( comps->length() < 1 )
3293 CORBA::String_var name = fields[ iF ]->GetName();
3295 if ( !fieldWriter.Set( meshDS,
3299 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3302 for ( size_t iC = 0; iC < comps->length(); ++iC )
3303 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3305 dblVals.resize( comps->length() );
3306 intVals.resize( comps->length() );
3308 // find sub-shape IDs
3310 std::vector< int >& subIds = subIdsByDim[ dim ];
3311 if ( subIds.empty() )
3312 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3313 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3314 subIds.push_back( id );
3318 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3322 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3324 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3325 if ( step->_is_nil() )
3328 CORBA::Long stamp = step->GetStamp();
3329 CORBA::Long id = step->GetID();
3330 fieldWriter.SetDtIt( int( stamp ), int( id ));
3332 // fill dblVals or intVals
3333 for ( size_t iC = 0; iC < comps->length(); ++iC )
3334 if ( dataType == GEOM::FDT_Double )
3336 dblVals[ iC ].clear();
3337 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3341 intVals[ iC ].clear();
3342 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3346 case GEOM::FDT_Double:
3348 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3349 if ( dblStep->_is_nil() ) continue;
3350 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3351 if ( vv->length() != subIds.size() * comps->length() )
3352 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3353 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3354 for ( size_t iC = 0; iC < comps->length(); ++iC )
3355 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3360 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3361 if ( intStep->_is_nil() ) continue;
3362 GEOM::ListOfLong_var vv = intStep->GetValues();
3363 if ( vv->length() != subIds.size() * comps->length() )
3364 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3365 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3366 for ( size_t iC = 0; iC < comps->length(); ++iC )
3367 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3370 case GEOM::FDT_Bool:
3372 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3373 if ( boolStep->_is_nil() ) continue;
3374 GEOM::short_array_var vv = boolStep->GetValues();
3375 if ( vv->length() != subIds.size() * comps->length() )
3376 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3377 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3378 for ( size_t iC = 0; iC < comps->length(); ++iC )
3379 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3385 // pass values to fieldWriter
3386 elemIt = fieldWriter.GetOrderedElems();
3387 if ( dataType == GEOM::FDT_Double )
3388 while ( elemIt->more() )
3390 const SMDS_MeshElement* e = elemIt->next();
3391 const int shapeID = e->getshapeId();
3392 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3393 for ( size_t iC = 0; iC < comps->length(); ++iC )
3394 fieldWriter.AddValue( noneDblValue );
3396 for ( size_t iC = 0; iC < comps->length(); ++iC )
3397 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3400 while ( elemIt->more() )
3402 const SMDS_MeshElement* e = elemIt->next();
3403 const int shapeID = e->getshapeId();
3404 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3405 for ( size_t iC = 0; iC < comps->length(); ++iC )
3406 fieldWriter.AddValue( (double) noneIntValue );
3408 for ( size_t iC = 0; iC < comps->length(); ++iC )
3409 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3413 fieldWriter.Perform();
3414 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3415 if ( res && res->IsKO() )
3417 if ( res->myComment.empty() )
3418 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3420 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3426 if ( !geomAssocFields || !geomAssocFields[0] )
3429 // write geomAssocFields
3431 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3432 shapeDim[ TopAbs_COMPOUND ] = 3;
3433 shapeDim[ TopAbs_COMPSOLID ] = 3;
3434 shapeDim[ TopAbs_SOLID ] = 3;
3435 shapeDim[ TopAbs_SHELL ] = 2;
3436 shapeDim[ TopAbs_FACE ] = 2;
3437 shapeDim[ TopAbs_WIRE ] = 1;
3438 shapeDim[ TopAbs_EDGE ] = 1;
3439 shapeDim[ TopAbs_VERTEX ] = 0;
3440 shapeDim[ TopAbs_SHAPE ] = 3;
3442 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3444 std::vector< std::string > compNames;
3445 switch ( geomAssocFields[ iF ]) {
3447 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3448 compNames.push_back( "dim" );
3451 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3454 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3457 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3461 compNames.push_back( "id" );
3462 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3463 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3465 fieldWriter.SetDtIt( -1, -1 );
3467 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3471 if ( compNames.size() == 2 ) // _vertices_
3472 while ( elemIt->more() )
3474 const SMDS_MeshElement* e = elemIt->next();
3475 const int shapeID = e->getshapeId();
3478 fieldWriter.AddValue( (double) -1 );
3479 fieldWriter.AddValue( (double) -1 );
3483 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3484 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3485 fieldWriter.AddValue( (double) shapeID );
3489 while ( elemIt->more() )
3491 const SMDS_MeshElement* e = elemIt->next();
3492 const int shapeID = e->getshapeId();
3494 fieldWriter.AddValue( (double) -1 );
3496 fieldWriter.AddValue( (double) shapeID );
3500 fieldWriter.Perform();
3501 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3502 if ( res && res->IsKO() )
3504 if ( res->myComment.empty() )
3505 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3507 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3510 } // loop on geomAssocFields
3515 //================================================================================
3517 * \brief Export a part of mesh to a DAT file
3519 //================================================================================
3521 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3523 throw (SALOME::SALOME_Exception)
3525 Unexpect aCatch(SALOME_SalomeException);
3527 _preMeshInfo->FullLoadFromFile();
3529 PrepareForWriting(file);
3531 SMESH_MeshPartDS partDS( meshPart );
3532 _impl->ExportDAT(file,&partDS);
3534 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3535 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3537 //================================================================================
3539 * \brief Export a part of mesh to an UNV file
3541 //================================================================================
3543 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3545 throw (SALOME::SALOME_Exception)
3547 Unexpect aCatch(SALOME_SalomeException);
3549 _preMeshInfo->FullLoadFromFile();
3551 PrepareForWriting(file);
3553 SMESH_MeshPartDS partDS( meshPart );
3554 _impl->ExportUNV(file, &partDS);
3556 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3557 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3559 //================================================================================
3561 * \brief Export a part of mesh to an STL file
3563 //================================================================================
3565 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3567 ::CORBA::Boolean isascii)
3568 throw (SALOME::SALOME_Exception)
3570 Unexpect aCatch(SALOME_SalomeException);
3572 _preMeshInfo->FullLoadFromFile();
3574 PrepareForWriting(file);
3576 CORBA::String_var name;
3577 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3578 if ( !so->_is_nil() )
3579 name = so->GetName();
3581 SMESH_MeshPartDS partDS( meshPart );
3582 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3584 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3585 << meshPart<< ", r'" << file << "', " << isascii << ")";
3588 //================================================================================
3590 * \brief Export a part of mesh to an STL file
3592 //================================================================================
3594 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3596 CORBA::Boolean overwrite,
3597 CORBA::Boolean groupElemsByType)
3598 throw (SALOME::SALOME_Exception)
3601 Unexpect aCatch(SALOME_SalomeException);
3603 _preMeshInfo->FullLoadFromFile();
3605 PrepareForWriting(file,overwrite);
3607 std::string meshName("");
3608 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3609 if ( !so->_is_nil() )
3611 CORBA::String_var name = so->GetName();
3612 meshName = name.in();
3616 SMESH_MeshPartDS partDS( meshPart );
3617 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3619 SMESH_CATCH( SMESH::throwCorbaException );
3621 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3622 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3624 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3628 //================================================================================
3630 * \brief Export a part of mesh to a GMF file
3632 //================================================================================
3634 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3636 bool withRequiredGroups)
3637 throw (SALOME::SALOME_Exception)
3639 Unexpect aCatch(SALOME_SalomeException);
3641 _preMeshInfo->FullLoadFromFile();
3643 PrepareForWriting(file,/*overwrite=*/true);
3645 SMESH_MeshPartDS partDS( meshPart );
3646 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3648 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3649 << meshPart<< ", r'"
3651 << withRequiredGroups << ")";
3654 //=============================================================================
3656 * Return computation progress [0.,1]
3658 //=============================================================================
3660 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3664 return _impl->GetComputeProgress();
3666 SMESH_CATCH( SMESH::doNothing );
3670 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3672 Unexpect aCatch(SALOME_SalomeException);
3674 return _preMeshInfo->NbNodes();
3676 return _impl->NbNodes();
3679 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3681 Unexpect aCatch(SALOME_SalomeException);
3683 return _preMeshInfo->NbElements();
3685 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3688 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3690 Unexpect aCatch(SALOME_SalomeException);
3692 return _preMeshInfo->Nb0DElements();
3694 return _impl->Nb0DElements();
3697 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3699 Unexpect aCatch(SALOME_SalomeException);
3701 return _preMeshInfo->NbBalls();
3703 return _impl->NbBalls();
3706 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3708 Unexpect aCatch(SALOME_SalomeException);
3710 return _preMeshInfo->NbEdges();
3712 return _impl->NbEdges();
3715 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3716 throw(SALOME::SALOME_Exception)
3718 Unexpect aCatch(SALOME_SalomeException);
3720 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3722 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3725 //=============================================================================
3727 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3729 Unexpect aCatch(SALOME_SalomeException);
3731 return _preMeshInfo->NbFaces();
3733 return _impl->NbFaces();
3736 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3738 Unexpect aCatch(SALOME_SalomeException);
3740 return _preMeshInfo->NbTriangles();
3742 return _impl->NbTriangles();
3745 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3747 Unexpect aCatch(SALOME_SalomeException);
3749 return _preMeshInfo->NbBiQuadTriangles();
3751 return _impl->NbBiQuadTriangles();
3754 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3756 Unexpect aCatch(SALOME_SalomeException);
3758 return _preMeshInfo->NbQuadrangles();
3760 return _impl->NbQuadrangles();
3763 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3765 Unexpect aCatch(SALOME_SalomeException);
3767 return _preMeshInfo->NbBiQuadQuadrangles();
3769 return _impl->NbBiQuadQuadrangles();
3772 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3774 Unexpect aCatch(SALOME_SalomeException);
3776 return _preMeshInfo->NbPolygons();
3778 return _impl->NbPolygons();
3781 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3783 Unexpect aCatch(SALOME_SalomeException);
3785 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3787 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3790 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3791 throw(SALOME::SALOME_Exception)
3793 Unexpect aCatch(SALOME_SalomeException);
3795 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3797 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3800 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3801 throw(SALOME::SALOME_Exception)
3803 Unexpect aCatch(SALOME_SalomeException);
3805 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3807 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3810 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3811 throw(SALOME::SALOME_Exception)
3813 Unexpect aCatch(SALOME_SalomeException);
3815 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3817 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3820 //=============================================================================
3822 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 return _preMeshInfo->NbVolumes();
3828 return _impl->NbVolumes();
3831 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3833 Unexpect aCatch(SALOME_SalomeException);
3835 return _preMeshInfo->NbTetras();
3837 return _impl->NbTetras();
3840 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3842 Unexpect aCatch(SALOME_SalomeException);
3844 return _preMeshInfo->NbHexas();
3846 return _impl->NbHexas();
3849 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3851 Unexpect aCatch(SALOME_SalomeException);
3853 return _preMeshInfo->NbTriQuadHexas();
3855 return _impl->NbTriQuadraticHexas();
3858 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3860 Unexpect aCatch(SALOME_SalomeException);
3862 return _preMeshInfo->NbPyramids();
3864 return _impl->NbPyramids();
3867 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 return _preMeshInfo->NbPrisms();
3873 return _impl->NbPrisms();
3876 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3878 Unexpect aCatch(SALOME_SalomeException);
3880 return _preMeshInfo->NbHexPrisms();
3882 return _impl->NbHexagonalPrisms();
3885 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3887 Unexpect aCatch(SALOME_SalomeException);
3889 return _preMeshInfo->NbPolyhedrons();
3891 return _impl->NbPolyhedrons();
3894 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3895 throw(SALOME::SALOME_Exception)
3897 Unexpect aCatch(SALOME_SalomeException);
3899 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3901 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3904 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3905 throw(SALOME::SALOME_Exception)
3907 Unexpect aCatch(SALOME_SalomeException);
3909 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3911 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3914 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3915 throw(SALOME::SALOME_Exception)
3917 Unexpect aCatch(SALOME_SalomeException);
3919 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3921 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3924 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3925 throw(SALOME::SALOME_Exception)
3927 Unexpect aCatch(SALOME_SalomeException);
3929 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3931 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3934 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3935 throw(SALOME::SALOME_Exception)
3937 Unexpect aCatch(SALOME_SalomeException);
3939 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3941 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3944 //=============================================================================
3946 * Returns nb of published sub-meshes
3948 //=============================================================================
3950 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3952 Unexpect aCatch(SALOME_SalomeException);
3953 return _mapSubMesh_i.size();
3956 //=============================================================================
3958 * Dumps mesh into a string
3960 //=============================================================================
3962 char* SMESH_Mesh_i::Dump()
3966 return CORBA::string_dup( os.str().c_str() );
3969 //=============================================================================
3971 * Method of SMESH_IDSource interface
3973 //=============================================================================
3975 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3977 return GetElementsId();
3980 //=============================================================================
3982 * Returns ids of all elements
3984 //=============================================================================
3986 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3987 throw (SALOME::SALOME_Exception)
3989 Unexpect aCatch(SALOME_SalomeException);
3991 _preMeshInfo->FullLoadFromFile();
3993 SMESH::long_array_var aResult = new SMESH::long_array();
3994 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3996 if ( aSMESHDS_Mesh == NULL )
3997 return aResult._retn();
3999 long nbElements = NbElements();
4000 aResult->length( nbElements );
4001 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4002 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4003 aResult[i] = anIt->next()->GetID();
4005 return aResult._retn();
4009 //=============================================================================
4011 * Returns ids of all elements of given type
4013 //=============================================================================
4015 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4016 throw (SALOME::SALOME_Exception)
4018 Unexpect aCatch(SALOME_SalomeException);
4020 _preMeshInfo->FullLoadFromFile();
4022 SMESH::long_array_var aResult = new SMESH::long_array();
4023 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4025 if ( aSMESHDS_Mesh == NULL )
4026 return aResult._retn();
4028 long nbElements = NbElements();
4030 // No sense in returning ids of elements along with ids of nodes:
4031 // when theElemType == SMESH::ALL, return node ids only if
4032 // there are no elements
4033 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4034 return GetNodesId();
4036 aResult->length( nbElements );
4040 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4041 while ( i < nbElements && anIt->more() )
4042 aResult[i++] = anIt->next()->GetID();
4044 aResult->length( i );
4046 return aResult._retn();
4049 //=============================================================================
4051 * Returns ids of all nodes
4053 //=============================================================================
4055 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4056 throw (SALOME::SALOME_Exception)
4058 Unexpect aCatch(SALOME_SalomeException);
4060 _preMeshInfo->FullLoadFromFile();
4062 SMESH::long_array_var aResult = new SMESH::long_array();
4063 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4065 if ( aMeshDS == NULL )
4066 return aResult._retn();
4068 long nbNodes = NbNodes();
4069 aResult->length( nbNodes );
4070 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4071 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4072 aResult[i] = anIt->next()->GetID();
4074 return aResult._retn();
4077 //=============================================================================
4081 //=============================================================================
4083 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4084 throw (SALOME::SALOME_Exception)
4086 SMESH::ElementType type = SMESH::ALL;
4090 _preMeshInfo->FullLoadFromFile();
4092 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4094 SMESH_CATCH( SMESH::throwCorbaException );
4099 //=============================================================================
4103 //=============================================================================
4105 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4106 throw (SALOME::SALOME_Exception)
4109 _preMeshInfo->FullLoadFromFile();
4111 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4113 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4115 return ( SMESH::EntityType ) e->GetEntityType();
4118 //=============================================================================
4122 //=============================================================================
4124 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4125 throw (SALOME::SALOME_Exception)
4128 _preMeshInfo->FullLoadFromFile();
4130 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4132 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4134 return ( SMESH::GeometryType ) e->GetGeomType();
4137 //=============================================================================
4139 * Returns ID of elements for given submesh
4141 //=============================================================================
4142 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4143 throw (SALOME::SALOME_Exception)
4145 SMESH::long_array_var aResult = new SMESH::long_array();
4149 _preMeshInfo->FullLoadFromFile();
4151 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4152 if(!SM) return aResult._retn();
4154 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4155 if(!SDSM) return aResult._retn();
4157 aResult->length(SDSM->NbElements());
4159 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4161 while ( eIt->more() ) {
4162 aResult[i++] = eIt->next()->GetID();
4165 SMESH_CATCH( SMESH::throwCorbaException );
4167 return aResult._retn();
4170 //=============================================================================
4172 * Returns ID of nodes for given submesh
4173 * If param all==true - returns all nodes, else -
4174 * returns only nodes on shapes.
4176 //=============================================================================
4178 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4180 throw (SALOME::SALOME_Exception)
4182 SMESH::long_array_var aResult = new SMESH::long_array();
4186 _preMeshInfo->FullLoadFromFile();
4188 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4189 if(!SM) return aResult._retn();
4191 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4192 if(!SDSM) return aResult._retn();
4195 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4196 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4197 while ( nIt->more() ) {
4198 const SMDS_MeshNode* elem = nIt->next();
4199 theElems.insert( elem->GetID() );
4202 else { // all nodes of submesh elements
4203 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4204 while ( eIt->more() ) {
4205 const SMDS_MeshElement* anElem = eIt->next();
4206 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4207 while ( nIt->more() ) {
4208 const SMDS_MeshElement* elem = nIt->next();
4209 theElems.insert( elem->GetID() );
4214 aResult->length(theElems.size());
4215 set<int>::iterator itElem;
4217 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4218 aResult[i++] = *itElem;
4220 SMESH_CATCH( SMESH::throwCorbaException );
4222 return aResult._retn();
4225 //=============================================================================
4227 * Returns type of elements for given submesh
4229 //=============================================================================
4231 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4232 throw (SALOME::SALOME_Exception)
4234 SMESH::ElementType type = SMESH::ALL;
4238 _preMeshInfo->FullLoadFromFile();
4240 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4241 if(!SM) return SMESH::ALL;
4243 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4244 if(!SDSM) return SMESH::ALL;
4246 if(SDSM->NbElements()==0)
4247 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4249 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4250 const SMDS_MeshElement* anElem = eIt->next();
4252 type = ( SMESH::ElementType ) anElem->GetType();
4254 SMESH_CATCH( SMESH::throwCorbaException );
4260 //=============================================================================
4262 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4264 //=============================================================================
4266 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4269 _preMeshInfo->FullLoadFromFile();
4271 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4272 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4277 //=============================================================================
4279 * Get XYZ coordinates of node as list of double
4280 * If there is not node for given ID - returns empty list
4282 //=============================================================================
4284 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4287 _preMeshInfo->FullLoadFromFile();
4289 SMESH::double_array_var aResult = new SMESH::double_array();
4290 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4291 if ( aMeshDS == NULL )
4292 return aResult._retn();
4295 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4297 return aResult._retn();
4301 aResult[0] = aNode->X();
4302 aResult[1] = aNode->Y();
4303 aResult[2] = aNode->Z();
4304 return aResult._retn();
4308 //=============================================================================
4310 * For given node returns list of IDs of inverse elements
4311 * If there is not node for given ID - returns empty list
4313 //=============================================================================
4315 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4318 _preMeshInfo->FullLoadFromFile();
4320 SMESH::long_array_var aResult = new SMESH::long_array();
4321 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4322 if ( aMeshDS == NULL )
4323 return aResult._retn();
4326 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4328 return aResult._retn();
4330 // find inverse elements
4331 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4332 aResult->length( aNode->NbInverseElements() );
4333 for( int i = 0; eIt->more(); ++i )
4335 const SMDS_MeshElement* elem = eIt->next();
4336 aResult[ i ] = elem->GetID();
4338 return aResult._retn();
4341 //=============================================================================
4343 * \brief Return position of a node on shape
4345 //=============================================================================
4347 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4350 _preMeshInfo->FullLoadFromFile();
4352 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4353 aNodePosition->shapeID = 0;
4354 aNodePosition->shapeType = GEOM::SHAPE;
4356 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4357 if ( !mesh ) return aNodePosition;
4359 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4361 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4363 aNodePosition->shapeID = aNode->getshapeId();
4364 switch ( pos->GetTypeOfPosition() ) {
4366 aNodePosition->shapeType = GEOM::EDGE;
4367 aNodePosition->params.length(1);
4368 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4370 case SMDS_TOP_FACE: {
4371 SMDS_FacePositionPtr fPos = pos;
4372 aNodePosition->shapeType = GEOM::FACE;
4373 aNodePosition->params.length(2);
4374 aNodePosition->params[0] = fPos->GetUParameter();
4375 aNodePosition->params[1] = fPos->GetVParameter();
4378 case SMDS_TOP_VERTEX:
4379 aNodePosition->shapeType = GEOM::VERTEX;
4381 case SMDS_TOP_3DSPACE:
4382 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4383 aNodePosition->shapeType = GEOM::SOLID;
4384 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4385 aNodePosition->shapeType = GEOM::SHELL;
4391 return aNodePosition;
4394 //=============================================================================
4396 * \brief Return position of an element on shape
4398 //=============================================================================
4400 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4403 _preMeshInfo->FullLoadFromFile();
4405 SMESH::ElementPosition anElementPosition;
4406 anElementPosition.shapeID = 0;
4407 anElementPosition.shapeType = GEOM::SHAPE;
4409 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4410 if ( !mesh ) return anElementPosition;
4412 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4414 anElementPosition.shapeID = anElem->getshapeId();
4415 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4416 if ( !aSp.IsNull() ) {
4417 switch ( aSp.ShapeType() ) {
4419 anElementPosition.shapeType = GEOM::EDGE;
4422 anElementPosition.shapeType = GEOM::FACE;
4425 anElementPosition.shapeType = GEOM::VERTEX;
4428 anElementPosition.shapeType = GEOM::SOLID;
4431 anElementPosition.shapeType = GEOM::SHELL;
4437 return anElementPosition;
4440 //=============================================================================
4442 * If given element is node returns IDs of shape from position
4443 * If there is not node for given ID - returns -1
4445 //=============================================================================
4447 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4450 _preMeshInfo->FullLoadFromFile();
4452 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4453 if ( aMeshDS == NULL )
4457 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4459 return aNode->getshapeId();
4466 //=============================================================================
4468 * For given element returns ID of result shape after
4469 * ::FindShape() from SMESH_MeshEditor
4470 * If there is not element for given ID - returns -1
4472 //=============================================================================
4474 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4477 _preMeshInfo->FullLoadFromFile();
4479 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4480 if ( aMeshDS == NULL )
4483 // try to find element
4484 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4488 ::SMESH_MeshEditor aMeshEditor(_impl);
4489 int index = aMeshEditor.FindShape( elem );
4497 //=============================================================================
4499 * Returns number of nodes for given element
4500 * If there is not element for given ID - returns -1
4502 //=============================================================================
4504 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4507 _preMeshInfo->FullLoadFromFile();
4509 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4510 if ( aMeshDS == NULL ) return -1;
4511 // try to find element
4512 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4513 if(!elem) return -1;
4514 return elem->NbNodes();
4518 //=============================================================================
4520 * Returns ID of node by given index for given element
4521 * If there is not element for given ID - returns -1
4522 * If there is not node for given index - returns -2
4524 //=============================================================================
4526 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4529 _preMeshInfo->FullLoadFromFile();
4531 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4532 if ( aMeshDS == NULL ) return -1;
4533 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4534 if(!elem) return -1;
4535 if( index>=elem->NbNodes() || index<0 ) return -1;
4536 return elem->GetNode(index)->GetID();
4539 //=============================================================================
4541 * Returns IDs of nodes of given element
4543 //=============================================================================
4545 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4548 _preMeshInfo->FullLoadFromFile();
4550 SMESH::long_array_var aResult = new SMESH::long_array();
4551 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4553 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4555 aResult->length( elem->NbNodes() );
4556 for ( int i = 0; i < elem->NbNodes(); ++i )
4557 aResult[ i ] = elem->GetNode( i )->GetID();
4560 return aResult._retn();
4563 //=============================================================================
4565 * Returns true if given node is medium node
4566 * in given quadratic element
4568 //=============================================================================
4570 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4573 _preMeshInfo->FullLoadFromFile();
4575 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4576 if ( aMeshDS == NULL ) return false;
4578 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4579 if(!aNode) return false;
4580 // try to find element
4581 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4582 if(!elem) return false;
4584 return elem->IsMediumNode(aNode);
4588 //=============================================================================
4590 * Returns true if given node is medium node
4591 * in one of quadratic elements
4593 //=============================================================================
4595 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4596 SMESH::ElementType theElemType)
4599 _preMeshInfo->FullLoadFromFile();
4601 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4602 if ( aMeshDS == NULL ) return false;
4605 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4606 if(!aNode) return false;
4608 SMESH_MesherHelper aHelper( *(_impl) );
4610 SMDSAbs_ElementType aType;
4611 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4612 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4613 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4614 else aType = SMDSAbs_All;
4616 return aHelper.IsMedium(aNode,aType);
4620 //=============================================================================
4622 * Returns number of edges for given element
4624 //=============================================================================
4626 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4629 _preMeshInfo->FullLoadFromFile();
4631 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4632 if ( aMeshDS == NULL ) return -1;
4633 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4634 if(!elem) return -1;
4635 return elem->NbEdges();
4639 //=============================================================================
4641 * Returns number of faces for given element
4643 //=============================================================================
4645 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4648 _preMeshInfo->FullLoadFromFile();
4650 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4651 if ( aMeshDS == NULL ) return -1;
4652 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4653 if(!elem) return -1;
4654 return elem->NbFaces();
4657 //=======================================================================
4658 //function : GetElemFaceNodes
4659 //purpose : Returns nodes of given face (counted from zero) for given element.
4660 //=======================================================================
4662 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4663 CORBA::Short faceIndex)
4666 _preMeshInfo->FullLoadFromFile();
4668 SMESH::long_array_var aResult = new SMESH::long_array();
4669 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4671 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4673 SMDS_VolumeTool vtool( elem );
4674 if ( faceIndex < vtool.NbFaces() )
4676 aResult->length( vtool.NbFaceNodes( faceIndex ));
4677 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4678 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4679 aResult[ i ] = nn[ i ]->GetID();
4683 return aResult._retn();
4686 //=======================================================================
4687 //function : GetElemFaceNodes
4688 //purpose : Returns three components of normal of given mesh face.
4689 //=======================================================================
4691 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4692 CORBA::Boolean normalized)
4695 _preMeshInfo->FullLoadFromFile();
4697 SMESH::double_array_var aResult = new SMESH::double_array();
4699 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4702 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4704 aResult->length( 3 );
4705 aResult[ 0 ] = normal.X();
4706 aResult[ 1 ] = normal.Y();
4707 aResult[ 2 ] = normal.Z();
4710 return aResult._retn();
4713 //=======================================================================
4714 //function : FindElementByNodes
4715 //purpose : Returns an element based on all given nodes.
4716 //=======================================================================
4718 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4721 _preMeshInfo->FullLoadFromFile();
4723 CORBA::Long elemID(0);
4724 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4726 vector< const SMDS_MeshNode * > nn( nodes.length() );
4727 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4728 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4731 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4732 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4733 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4734 _impl->NbVolumes( ORDER_QUADRATIC )))
4735 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4737 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4742 //================================================================================
4744 * \brief Return elements including all given nodes.
4746 //================================================================================
4748 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4749 SMESH::ElementType elemType)
4752 _preMeshInfo->FullLoadFromFile();
4754 SMESH::long_array_var result = new SMESH::long_array();
4756 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4758 vector< const SMDS_MeshNode * > nn( nodes.length() );
4759 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4760 nn[i] = mesh->FindNode( nodes[i] );
4762 std::vector<const SMDS_MeshElement *> elems;
4763 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4764 result->length( elems.size() );
4765 for ( size_t i = 0; i < elems.size(); ++i )
4766 result[i] = elems[i]->GetID();
4768 return result._retn();
4771 //=============================================================================
4773 * Returns true if given element is polygon
4775 //=============================================================================
4777 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4780 _preMeshInfo->FullLoadFromFile();
4782 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4783 if ( aMeshDS == NULL ) return false;
4784 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4785 if(!elem) return false;
4786 return elem->IsPoly();
4790 //=============================================================================
4792 * Returns true if given element is quadratic
4794 //=============================================================================
4796 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4799 _preMeshInfo->FullLoadFromFile();
4801 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4802 if ( aMeshDS == NULL ) return false;
4803 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4804 if(!elem) return false;
4805 return elem->IsQuadratic();
4808 //=============================================================================
4810 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4812 //=============================================================================
4814 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4817 _preMeshInfo->FullLoadFromFile();
4819 if ( const SMDS_BallElement* ball =
4820 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4821 return ball->GetDiameter();
4826 //=============================================================================
4828 * Returns bary center for given element
4830 //=============================================================================
4832 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4835 _preMeshInfo->FullLoadFromFile();
4837 SMESH::double_array_var aResult = new SMESH::double_array();
4838 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4839 if ( aMeshDS == NULL )
4840 return aResult._retn();
4842 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4844 return aResult._retn();
4846 if(elem->GetType()==SMDSAbs_Volume) {
4847 SMDS_VolumeTool aTool;
4848 if(aTool.Set(elem)) {
4850 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4855 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4857 double x=0., y=0., z=0.;
4858 for(; anIt->more(); ) {
4860 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4874 return aResult._retn();
4877 //================================================================================
4879 * \brief Create a group of elements preventing computation of a sub-shape
4881 //================================================================================
4883 SMESH::ListOfGroups*
4884 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4885 const char* theGroupName )
4886 throw ( SALOME::SALOME_Exception )
4888 Unexpect aCatch(SALOME_SalomeException);
4890 if ( !theGroupName || strlen( theGroupName) == 0 )
4891 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4893 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4894 ::SMESH_MeshEditor::ElemFeatures elemType;
4896 // submesh by subshape id
4897 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4898 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4901 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4902 if ( error && error->HasBadElems() )
4904 // sort bad elements by type
4905 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4906 const list<const SMDS_MeshElement*>& badElems =
4907 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4908 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4909 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4910 for ( ; elemIt != elemEnd; ++elemIt )
4912 const SMDS_MeshElement* elem = *elemIt;
4913 if ( !elem ) continue;
4915 if ( elem->GetID() < 1 )
4917 // elem is a temporary element, make a real element
4918 vector< const SMDS_MeshNode* > nodes;
4919 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4920 while ( nIt->more() && elem )
4922 nodes.push_back( nIt->next() );
4923 if ( nodes.back()->GetID() < 1 )
4924 elem = 0; // a temporary element on temporary nodes
4928 ::SMESH_MeshEditor editor( _impl );
4929 elem = editor.AddElement( nodes, elemType.Init( elem ));
4933 elemsByType[ elem->GetType() ].push_back( elem );
4936 // how many groups to create?
4938 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4939 nbTypes += int( !elemsByType[ i ].empty() );
4940 groups->length( nbTypes );
4943 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4945 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4946 if ( elems.empty() ) continue;
4948 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4949 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4951 SMESH::SMESH_Mesh_var mesh = _this();
4952 SALOMEDS::SObject_wrap aSO =
4953 _gen_i->PublishGroup( mesh, groups[ iG ],
4954 GEOM::GEOM_Object::_nil(), theGroupName);
4956 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4957 if ( !grp_i ) continue;
4959 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4960 for ( size_t iE = 0; iE < elems.size(); ++iE )
4961 grpDS->SMDSGroup().Add( elems[ iE ]);
4966 return groups._retn();
4969 //=============================================================================
4971 * Create and publish group servants if any groups were imported or created anyhow
4973 //=============================================================================
4975 void SMESH_Mesh_i::CreateGroupServants()
4977 SMESH::SMESH_Mesh_var aMesh = _this();
4980 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4981 while ( groupIt->more() )
4983 ::SMESH_Group* group = groupIt->next();
4984 int anId = group->GetGroupDS()->GetID();
4986 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4987 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4989 addedIDs.insert( anId );
4991 SMESH_GroupBase_i* aGroupImpl;
4993 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4994 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4996 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4997 shape = groupOnGeom->GetShape();
5000 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5003 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5004 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5005 aGroupImpl->Register();
5007 // register CORBA object for persistence
5008 int nextId = _gen_i->RegisterObject( groupVar );
5009 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5010 else { nextId = 0; } // avoid "unused variable" warning in release mode
5012 // publishing the groups in the study
5013 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5014 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5016 if ( !addedIDs.empty() )
5019 set<int>::iterator id = addedIDs.begin();
5020 for ( ; id != addedIDs.end(); ++id )
5022 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5023 int i = std::distance( _mapGroups.begin(), it );
5024 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5029 //=============================================================================
5031 * \brief Return true if all sub-meshes are computed OK - to update an icon
5033 //=============================================================================
5035 bool SMESH_Mesh_i::IsComputedOK()
5037 return _impl->IsComputedOK();
5040 //=============================================================================
5042 * \brief Return groups cantained in _mapGroups by their IDs
5044 //=============================================================================
5046 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5048 int nbGroups = groupIDs.size();
5049 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5050 aList->length( nbGroups );
5052 list<int>::const_iterator ids = groupIDs.begin();
5053 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5055 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5056 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5057 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5059 aList->length( nbGroups );
5060 return aList._retn();
5063 //=============================================================================
5065 * \brief Return information about imported file
5067 //=============================================================================
5069 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5071 SMESH::MedFileInfo_var res( _medFileInfo );
5072 if ( !res.operator->() ) {
5073 res = new SMESH::MedFileInfo;
5075 res->fileSize = res->major = res->minor = res->release = -1;
5080 //=======================================================================
5081 //function : FileInfoToString
5082 //purpose : Persistence of file info
5083 //=======================================================================
5085 std::string SMESH_Mesh_i::FileInfoToString()
5088 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5090 s = SMESH_Comment( _medFileInfo->fileSize )
5091 << " " << _medFileInfo->major
5092 << " " << _medFileInfo->minor
5093 << " " << _medFileInfo->release
5094 << " " << _medFileInfo->fileName;
5099 //=======================================================================
5100 //function : FileInfoFromString
5101 //purpose : Persistence of file info
5102 //=======================================================================
5104 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5106 std::string size, major, minor, release, fileName;
5107 std::istringstream is(info);
5108 is >> size >> major >> minor >> release;
5109 fileName = info.data() + ( size.size() + 1 +
5112 release.size()+ 1 );
5114 _medFileInfo = new SMESH::MedFileInfo();
5115 _medFileInfo->fileName = fileName.c_str();
5116 _medFileInfo->fileSize = atoi( size.c_str() );
5117 _medFileInfo->major = atoi( major.c_str() );
5118 _medFileInfo->minor = atoi( minor.c_str() );
5119 _medFileInfo->release = atoi( release.c_str() );
5122 //=============================================================================
5124 * \brief Pass names of mesh groups from study to mesh DS
5126 //=============================================================================
5128 void SMESH_Mesh_i::checkGroupNames()
5130 int nbGrp = NbGroups();
5134 SMESH::ListOfGroups* grpList = 0;
5135 // avoid dump of "GetGroups"
5137 // store python dump into a local variable inside local scope
5138 SMESH::TPythonDump pDump; // do not delete this line of code
5139 grpList = GetGroups();
5142 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5143 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5146 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5147 if ( aGrpSO->_is_nil() )
5149 // correct name of the mesh group if necessary
5150 const char* guiName = aGrpSO->GetName();
5151 if ( strcmp(guiName, aGrp->GetName()) )
5152 aGrp->SetName( guiName );
5156 //=============================================================================
5158 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5160 //=============================================================================
5161 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5163 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5167 //=============================================================================
5169 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5171 //=============================================================================
5173 char* SMESH_Mesh_i::GetParameters()
5175 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5178 //=============================================================================
5180 * \brief Returns list of notebook variables used for last Mesh operation
5182 //=============================================================================
5183 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5185 SMESH::string_array_var aResult = new SMESH::string_array();
5186 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5188 CORBA::String_var aParameters = GetParameters();
5189 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5190 if ( aSections->length() > 0 ) {
5191 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5192 aResult->length( aVars.length() );
5193 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5194 aResult[i] = CORBA::string_dup( aVars[i] );
5197 return aResult._retn();
5200 //=======================================================================
5201 //function : GetTypes
5202 //purpose : Returns types of elements it contains
5203 //=======================================================================
5205 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5208 return _preMeshInfo->GetTypes();
5210 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5214 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5215 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5216 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5217 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5218 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5219 if (_impl->NbNodes() &&
5220 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5221 types->length( nbTypes );
5223 return types._retn();
5226 //=======================================================================
5227 //function : GetMesh
5228 //purpose : Returns self
5229 //=======================================================================
5231 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5233 return SMESH::SMESH_Mesh::_duplicate( _this() );
5236 //=======================================================================
5237 //function : IsMeshInfoCorrect
5238 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5239 // * happen if mesh data is not yet fully loaded from the file of study.
5240 //=======================================================================
5242 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5244 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5247 //=============================================================================
5249 * \brief Returns number of mesh elements per each \a EntityType
5251 //=============================================================================
5253 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5256 return _preMeshInfo->GetMeshInfo();
5258 SMESH::long_array_var aRes = new SMESH::long_array();
5259 aRes->length(SMESH::Entity_Last);
5260 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5262 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5264 return aRes._retn();
5265 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5266 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5267 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5268 return aRes._retn();
5271 //=============================================================================
5273 * \brief Returns number of mesh elements per each \a ElementType
5275 //=============================================================================
5277 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5279 SMESH::long_array_var aRes = new SMESH::long_array();
5280 aRes->length(SMESH::NB_ELEMENT_TYPES);
5281 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5284 const SMDS_MeshInfo* meshInfo = 0;
5286 meshInfo = _preMeshInfo;
5287 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5288 meshInfo = & meshDS->GetMeshInfo();
5291 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5292 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5294 return aRes._retn();
5297 //=============================================================================
5299 * Collect statistic of mesh elements given by iterator
5301 //=============================================================================
5303 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5304 SMESH::long_array& theInfo)
5306 if (!theItr) return;
5307 while (theItr->more())
5308 theInfo[ theItr->next()->GetEntityType() ]++;
5310 //=============================================================================
5312 * Returns mesh unstructed grid information.
5314 //=============================================================================
5316 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5318 SALOMEDS::TMPFile_var SeqFile;
5319 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5320 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5322 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5323 aWriter->WriteToOutputStringOn();
5324 aWriter->SetInputData(aGrid);
5325 aWriter->SetFileTypeToBinary();
5327 char* str = aWriter->GetOutputString();
5328 int size = aWriter->GetOutputStringLength();
5330 //Allocate octect buffer of required size
5331 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5332 //Copy ostrstream content to the octect buffer
5333 memcpy(OctetBuf, str, size);
5334 //Create and return TMPFile
5335 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5339 return SeqFile._retn();
5342 //=============================================================================
5343 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5344 * SMESH::ElementType type) */
5346 using namespace SMESH::Controls;
5347 //-----------------------------------------------------------------------------
5348 struct PredicateIterator : public SMDS_ElemIterator
5350 SMDS_ElemIteratorPtr _elemIter;
5351 PredicatePtr _predicate;
5352 const SMDS_MeshElement* _elem;
5354 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5355 PredicatePtr predicate):
5356 _elemIter(iterator), _predicate(predicate)
5364 virtual const SMDS_MeshElement* next()
5366 const SMDS_MeshElement* res = _elem;
5368 while ( _elemIter->more() && !_elem )
5370 _elem = _elemIter->next();
5371 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5378 //-----------------------------------------------------------------------------
5379 struct IDSourceIterator : public SMDS_ElemIterator
5381 const CORBA::Long* _idPtr;
5382 const CORBA::Long* _idEndPtr;
5383 SMESH::long_array_var _idArray;
5384 const SMDS_Mesh* _mesh;
5385 const SMDSAbs_ElementType _type;
5386 const SMDS_MeshElement* _elem;
5388 IDSourceIterator( const SMDS_Mesh* mesh,
5389 const CORBA::Long* ids,
5391 SMDSAbs_ElementType type):
5392 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5394 if ( _idPtr && nbIds && _mesh )
5397 IDSourceIterator( const SMDS_Mesh* mesh,
5398 SMESH::long_array* idArray,
5399 SMDSAbs_ElementType type):
5400 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5402 if ( idArray && _mesh )
5404 _idPtr = &_idArray[0];
5405 _idEndPtr = _idPtr + _idArray->length();
5413 virtual const SMDS_MeshElement* next()
5415 const SMDS_MeshElement* res = _elem;
5417 while ( _idPtr < _idEndPtr && !_elem )
5419 if ( _type == SMDSAbs_Node )
5421 _elem = _mesh->FindNode( *_idPtr++ );
5423 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5424 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5432 //-----------------------------------------------------------------------------
5434 struct NodeOfElemIterator : public SMDS_ElemIterator
5436 TColStd_MapOfInteger _checkedNodeIDs;
5437 SMDS_ElemIteratorPtr _elemIter;
5438 SMDS_ElemIteratorPtr _nodeIter;
5439 const SMDS_MeshElement* _node;
5441 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5443 if ( _elemIter && _elemIter->more() )
5445 _nodeIter = _elemIter->next()->nodesIterator();
5453 virtual const SMDS_MeshElement* next()
5455 const SMDS_MeshElement* res = _node;
5457 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5459 if ( _nodeIter->more() )
5461 _node = _nodeIter->next();
5462 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5467 _nodeIter = _elemIter->next()->nodesIterator();
5475 //=============================================================================
5477 * Return iterator on elements of given type in given object
5479 //=============================================================================
5481 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5482 SMESH::ElementType theType)
5484 SMDS_ElemIteratorPtr elemIt;
5485 bool typeOK = ( theType == SMESH::ALL );
5486 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5488 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5489 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5490 if ( !mesh_i ) return elemIt;
5491 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5493 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5495 elemIt = meshDS->elementsIterator( elemType );
5498 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5500 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5503 elemIt = sm->GetElements();
5504 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5506 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5507 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5511 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5513 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5514 if ( groupDS && ( elemType == groupDS->GetType() ||
5515 elemType == SMDSAbs_Node ||
5516 elemType == SMDSAbs_All ))
5518 elemIt = groupDS->GetElements();
5519 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5522 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5524 if ( filter_i->GetElementType() == theType ||
5525 elemType == SMDSAbs_Node ||
5526 elemType == SMDSAbs_All)
5528 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5529 if ( pred_i && pred_i->GetPredicate() )
5531 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5532 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5533 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5534 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5540 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5541 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5542 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5544 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5547 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5548 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5552 SMESH::long_array_var ids = theObject->GetIDs();
5553 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5555 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5558 if ( elemIt && elemIt->more() && !typeOK )
5560 if ( elemType == SMDSAbs_Node )
5562 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5566 elemIt = SMDS_ElemIteratorPtr();
5572 //=============================================================================
5573 namespace // Finding concurrent hypotheses
5574 //=============================================================================
5578 * \brief mapping of mesh dimension into shape type
5580 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5582 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5584 case 0: aType = TopAbs_VERTEX; break;
5585 case 1: aType = TopAbs_EDGE; break;
5586 case 2: aType = TopAbs_FACE; break;
5588 default:aType = TopAbs_SOLID; break;
5593 //-----------------------------------------------------------------------------
5595 * \brief Internal structure used to find concurrent submeshes
5597 * It represents a pair < submesh, concurrent dimension >, where
5598 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5599 * with another submesh. In other words, it is dimension of a hypothesis assigned
5606 int _dim; //!< a dimension the algo can build (concurrent dimension)
5607 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5608 TopTools_MapOfShape _shapeMap;
5609 SMESH_subMesh* _subMesh;
5610 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5612 //-----------------------------------------------------------------------------
5613 // Return the algorithm
5614 const SMESH_Algo* GetAlgo() const
5615 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5617 //-----------------------------------------------------------------------------
5619 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5621 const TopoDS_Shape& theShape)
5623 _subMesh = (SMESH_subMesh*)theSubMesh;
5624 SetShape( theDim, theShape );
5627 //-----------------------------------------------------------------------------
5629 void SetShape(const int theDim,
5630 const TopoDS_Shape& theShape)
5633 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5634 if (_dim >= _ownDim)
5635 _shapeMap.Add( theShape );
5637 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5638 for( ; anExp.More(); anExp.Next() )
5639 _shapeMap.Add( anExp.Current() );
5643 //-----------------------------------------------------------------------------
5644 //! Check sharing of sub-shapes
5645 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5646 const TopTools_MapOfShape& theToFind,
5647 const TopAbs_ShapeEnum theType)
5649 bool isShared = false;
5650 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5651 for (; !isShared && anItr.More(); anItr.Next() )
5653 const TopoDS_Shape aSubSh = anItr.Key();
5654 // check for case when concurrent dimensions are same
5655 isShared = theToFind.Contains( aSubSh );
5656 // check for sub-shape with concurrent dimension
5657 TopExp_Explorer anExp( aSubSh, theType );
5658 for ( ; !isShared && anExp.More(); anExp.Next() )
5659 isShared = theToFind.Contains( anExp.Current() );
5664 //-----------------------------------------------------------------------------
5665 //! check algorithms
5666 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5667 const SMESHDS_Hypothesis* theA2)
5669 if ( !theA1 || !theA2 ||
5670 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5671 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5672 return false; // one of the hypothesis is not algorithm
5673 // check algorithm names (should be equal)
5674 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5678 //-----------------------------------------------------------------------------
5679 //! Check if sub-shape hypotheses are concurrent
5680 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5682 if ( _subMesh == theOther->_subMesh )
5683 return false; // same sub-shape - should not be
5685 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5686 // any of the two submeshes is not on COMPOUND shape )
5687 // -> no concurrency
5688 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5689 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5690 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5691 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5692 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5695 // bool checkSubShape = ( _dim >= theOther->_dim )
5696 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5697 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5698 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5699 if ( !checkSubShape )
5702 // check algorithms to be same
5703 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5704 return true; // different algorithms -> concurrency !
5706 // check hypothesises for concurrence (skip first as algorithm)
5708 // pointers should be same, because it is referened from mesh hypothesis partition
5709 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5710 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5711 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5712 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5714 // the submeshes are concurrent if their algorithms has different parameters
5715 return nbSame != (int)theOther->_hypotheses.size() - 1;
5718 // Return true if algorithm of this SMESH_DimHyp is used if no
5719 // sub-mesh order is imposed by the user
5720 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5722 // NeedDiscreteBoundary() algo has a higher priority
5723 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5724 theOther->GetAlgo()->NeedDiscreteBoundary() )
5725 return !this->GetAlgo()->NeedDiscreteBoundary();
5727 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5730 }; // end of SMESH_DimHyp
5731 //-----------------------------------------------------------------------------
5733 typedef list<const SMESH_DimHyp*> TDimHypList;
5735 //-----------------------------------------------------------------------------
5737 void addDimHypInstance(const int theDim,
5738 const TopoDS_Shape& theShape,
5739 const SMESH_Algo* theAlgo,
5740 const SMESH_subMesh* theSubMesh,
5741 const list <const SMESHDS_Hypothesis*>& theHypList,
5742 TDimHypList* theDimHypListArr )
5744 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5745 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5746 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5747 dimHyp->_hypotheses.push_front(theAlgo);
5748 listOfdimHyp.push_back( dimHyp );
5751 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5752 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5753 theHypList.begin(), theHypList.end() );
5756 //-----------------------------------------------------------------------------
5757 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5758 TDimHypList& theListOfConcurr)
5760 if ( theListOfConcurr.empty() )
5762 theListOfConcurr.push_back( theDimHyp );
5766 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5767 while ( hypIt != theListOfConcurr.end() &&
5768 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5770 theListOfConcurr.insert( hypIt, theDimHyp );
5774 //-----------------------------------------------------------------------------
5775 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5776 const TDimHypList& theListOfDimHyp,
5777 TDimHypList& theListOfConcurrHyp,
5778 set<int>& theSetOfConcurrId )
5780 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5781 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5783 const SMESH_DimHyp* curDimHyp = *rIt;
5784 if ( curDimHyp == theDimHyp )
5785 break; // meet own dimHyp pointer in same dimension
5787 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5788 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5790 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5795 //-----------------------------------------------------------------------------
5796 void unionLists(TListOfInt& theListOfId,
5797 TListOfListOfInt& theListOfListOfId,
5800 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5801 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5803 continue; //skip already treated lists
5804 // check if other list has any same submesh object
5805 TListOfInt& otherListOfId = *it;
5806 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5807 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5810 // union two lists (from source into target)
5811 TListOfInt::iterator it2 = otherListOfId.begin();
5812 for ( ; it2 != otherListOfId.end(); it2++ ) {
5813 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5814 theListOfId.push_back(*it2);
5816 // clear source list
5817 otherListOfId.clear();
5820 //-----------------------------------------------------------------------------
5822 //! free memory allocated for dimension-hypothesis objects
5823 void removeDimHyps( TDimHypList* theArrOfList )
5825 for (int i = 0; i < 4; i++ ) {
5826 TDimHypList& listOfdimHyp = theArrOfList[i];
5827 TDimHypList::const_iterator it = listOfdimHyp.begin();
5828 for ( ; it != listOfdimHyp.end(); it++ )
5833 //-----------------------------------------------------------------------------
5835 * \brief find common submeshes with given submesh
5836 * \param theSubMeshList list of already collected submesh to check
5837 * \param theSubMesh given submesh to intersect with other
5838 * \param theCommonSubMeshes collected common submeshes
5840 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5841 const SMESH_subMesh* theSubMesh,
5842 set<const SMESH_subMesh*>& theCommon )
5846 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5847 for ( ; it != theSubMeshList.end(); it++ )
5848 theSubMesh->FindIntersection( *it, theCommon );
5849 theSubMeshList.push_back( theSubMesh );
5850 //theCommon.insert( theSubMesh );
5853 //-----------------------------------------------------------------------------
5854 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5856 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5857 for ( ; listsIt != smLists.end(); ++listsIt )
5859 const TListOfInt& smIDs = *listsIt;
5860 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5868 //=============================================================================
5870 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5872 //=============================================================================
5874 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5876 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5877 if ( isSubMeshInList( submeshID, anOrder ))
5880 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5881 return isSubMeshInList( submeshID, allConurrent );
5884 //=============================================================================
5886 * \brief Return submesh objects list in meshing order
5888 //=============================================================================
5890 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5892 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5894 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5896 return aResult._retn();
5898 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5899 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5900 anOrder.splice( anOrder.end(), allConurrent );
5903 TListOfListOfInt::iterator listIt = anOrder.begin();
5904 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5905 unionLists( *listIt, anOrder, listIndx + 1 );
5907 // convert submesh ids into interface instances
5908 // and dump command into python
5909 convertMeshOrder( anOrder, aResult, false );
5911 return aResult._retn();
5914 //=============================================================================
5916 * \brief Finds concurrent sub-meshes
5918 //=============================================================================
5920 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5922 TListOfListOfInt anOrder;
5923 ::SMESH_Mesh& mesh = GetImpl();
5925 // collect submeshes and detect concurrent algorithms and hypothesises
5926 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5928 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5929 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5930 ::SMESH_subMesh* sm = (*i_sm).second;
5932 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5934 // list of assigned hypothesises
5935 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5936 // Find out dimensions where the submesh can be concurrent.
5937 // We define the dimensions by algo of each of hypotheses in hypList
5938 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5939 for( ; hypIt != hypList.end(); hypIt++ ) {
5940 SMESH_Algo* anAlgo = 0;
5941 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5942 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5943 // hyp it-self is algo
5944 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5946 // try to find algorithm with help of sub-shapes
5947 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5948 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5949 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5952 continue; // no algorithm assigned to a current submesh
5954 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5955 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5957 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5958 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5959 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5961 } // end iterations on submesh
5963 // iterate on created dimension-hypotheses and check for concurrents
5964 for ( int i = 0; i < 4; i++ ) {
5965 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5966 // check for concurrents in own and other dimensions (step-by-step)
5967 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5968 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5969 const SMESH_DimHyp* dimHyp = *dhIt;
5970 TDimHypList listOfConcurr;
5971 set<int> setOfConcurrIds;
5972 // looking for concurrents and collect into own list
5973 for ( int j = i; j < 4; j++ )
5974 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5975 // check if any concurrents found
5976 if ( listOfConcurr.size() > 0 ) {
5977 // add own submesh to list of concurrent
5978 addInOrderOfPriority( dimHyp, listOfConcurr );
5979 list<int> listOfConcurrIds;
5980 TDimHypList::iterator hypIt = listOfConcurr.begin();
5981 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5982 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5983 anOrder.push_back( listOfConcurrIds );
5988 removeDimHyps(dimHypListArr);
5990 // now, minimize the number of concurrent groups
5991 // Here we assume that lists of submeshes can have same submesh
5992 // in case of multi-dimension algorithms, as result
5993 // list with common submesh has to be united into one list
5995 TListOfListOfInt::iterator listIt = anOrder.begin();
5996 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5997 unionLists( *listIt, anOrder, listIndx + 1 );
6003 //=============================================================================
6005 * \brief Set submesh object order
6006 * \param theSubMeshArray submesh array order
6008 //=============================================================================
6010 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6013 _preMeshInfo->ForgetOrLoad();
6016 ::SMESH_Mesh& mesh = GetImpl();
6018 TPythonDump aPythonDump; // prevent dump of called methods
6019 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6021 TListOfListOfInt subMeshOrder;
6022 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6024 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6025 TListOfInt subMeshIds;
6027 aPythonDump << ", ";
6028 aPythonDump << "[ ";
6029 // Collect subMeshes which should be clear
6030 // do it list-by-list, because modification of submesh order
6031 // take effect between concurrent submeshes only
6032 set<const SMESH_subMesh*> subMeshToClear;
6033 list<const SMESH_subMesh*> subMeshList;
6034 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6036 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6038 aPythonDump << ", ";
6039 aPythonDump << subMesh;
6040 subMeshIds.push_back( subMesh->GetId() );
6041 // detect common parts of submeshes
6042 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6043 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6045 aPythonDump << " ]";
6046 subMeshOrder.push_back( subMeshIds );
6048 // clear collected submeshes
6049 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6050 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6051 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6052 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6054 aPythonDump << " ])";
6056 mesh.SetMeshOrder( subMeshOrder );
6059 SMESH::SMESH_Mesh_var me = _this();
6060 _gen_i->UpdateIcons( me );
6065 //=============================================================================
6067 * \brief Convert submesh ids into submesh interfaces
6069 //=============================================================================
6071 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6072 SMESH::submesh_array_array& theResOrder,
6073 const bool theIsDump)
6075 int nbSet = theIdsOrder.size();
6076 TPythonDump aPythonDump; // prevent dump of called methods
6078 aPythonDump << "[ ";
6079 theResOrder.length(nbSet);
6080 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6082 for( ; it != theIdsOrder.end(); it++ ) {
6083 // translate submesh identificators into submesh objects
6084 // takeing into account real number of concurrent lists
6085 const TListOfInt& aSubOrder = (*it);
6086 if (!aSubOrder.size())
6089 aPythonDump << "[ ";
6090 // convert shape indices into interfaces
6091 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6092 aResSubSet->length(aSubOrder.size());
6093 TListOfInt::const_iterator subIt = aSubOrder.begin();
6095 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6096 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6098 SMESH::SMESH_subMesh_var subMesh =
6099 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6102 aPythonDump << ", ";
6103 aPythonDump << subMesh;
6105 aResSubSet[ j++ ] = subMesh;
6108 aPythonDump << " ]";
6110 theResOrder[ listIndx++ ] = aResSubSet;
6112 // correct number of lists
6113 theResOrder.length( listIndx );
6116 // finilise python dump
6117 aPythonDump << " ]";
6118 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6122 namespace // utils used by SMESH_MeshPartDS
6125 * \brief Class used to access to protected data of SMDS_MeshInfo
6127 struct TMeshInfo : public SMDS_MeshInfo
6129 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6132 * \brief Element holing its ID only
6134 struct TElemID : public SMDS_LinearEdge
6136 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6140 //================================================================================
6142 // Implementation of SMESH_MeshPartDS
6144 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6145 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6147 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6148 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6151 _meshDS = mesh_i->GetImpl().GetMeshDS();
6153 SetPersistentId( _meshDS->GetPersistentId() );
6155 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6157 // <meshPart> is the whole mesh
6158 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6160 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6161 myGroupSet = _meshDS->GetGroups();
6166 SMESH::long_array_var anIDs = meshPart->GetIDs();
6167 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6168 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6170 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6171 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6172 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6177 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6178 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6179 if ( _elements[ e->GetType() ].insert( e ).second )
6182 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6183 while ( nIt->more() )
6185 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6186 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6193 ShapeToMesh( _meshDS->ShapeToMesh() );
6195 _meshDS = 0; // to enforce iteration on _elements and _nodes
6198 // -------------------------------------------------------------------------------------
6199 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6200 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6203 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6204 for ( ; partIt != meshPart.end(); ++partIt )
6205 if ( const SMDS_MeshElement * e = *partIt )
6206 if ( _elements[ e->GetType() ].insert( e ).second )
6209 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6210 while ( nIt->more() )
6212 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6213 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6219 // -------------------------------------------------------------------------------------
6220 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6222 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6224 TElemID elem( IDelem );
6225 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6226 if ( !_elements[ iType ].empty() )
6228 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6229 if ( it != _elements[ iType ].end() )
6234 // -------------------------------------------------------------------------------------
6235 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6237 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6239 typedef SMDS_SetIterator
6240 <const SMDS_MeshElement*,
6241 TIDSortedElemSet::const_iterator,
6242 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6243 SMDS_MeshElement::GeomFilter
6246 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6248 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6249 _elements[type].end(),
6250 SMDS_MeshElement::GeomFilter( geomType )));
6252 // -------------------------------------------------------------------------------------
6253 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6255 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6257 typedef SMDS_SetIterator
6258 <const SMDS_MeshElement*,
6259 TIDSortedElemSet::const_iterator,
6260 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6261 SMDS_MeshElement::EntityFilter
6264 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6266 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6267 _elements[type].end(),
6268 SMDS_MeshElement::EntityFilter( entity )));
6270 // -------------------------------------------------------------------------------------
6271 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6273 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6274 if ( type == SMDSAbs_All && !_meshDS )
6276 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6278 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6279 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6281 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6283 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6284 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6286 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6287 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6289 // -------------------------------------------------------------------------------------
6290 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6291 iterType SMESH_MeshPartDS::methName() const \
6293 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6294 return _meshDS ? _meshDS->methName() : iterType \
6295 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6297 // -------------------------------------------------------------------------------------
6298 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6299 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6300 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6301 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6302 #undef _GET_ITER_DEFINE
6304 // END Implementation of SMESH_MeshPartDS
6306 //================================================================================