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