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)
3025 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3028 _preMeshInfo->FullLoadFromFile();
3030 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3031 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3033 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3034 << file << "', " << auto_groups << ", "
3035 << theVersion << ", " << overwrite << ", "
3036 << autoDimension << " )";
3038 SMESH_CATCH( SMESH::throwCorbaException );
3041 //================================================================================
3043 * \brief Export a mesh to a med file
3045 //================================================================================
3047 void SMESH_Mesh_i::ExportToMED (const char* file,
3048 CORBA::Boolean auto_groups,
3049 SMESH::MED_VERSION theVersion)
3050 throw(SALOME::SALOME_Exception)
3052 //MESSAGE("SMESH::MED_VERSION:"<< theVersion);
3053 ExportToMEDX(file,auto_groups,theVersion,true);
3056 //================================================================================
3058 * \brief Export a mesh to a med file
3060 //================================================================================
3062 void SMESH_Mesh_i::ExportMED (const char* file,
3063 CORBA::Boolean auto_groups)
3064 throw(SALOME::SALOME_Exception)
3066 //MESSAGE("SMESH::MED_VERSION:"<< SMESH::MED_LATEST);
3067 ExportToMEDX(file,auto_groups,SMESH::MED_LATEST,true);
3070 //================================================================================
3072 * \brief Export a mesh to a SAUV file
3074 //================================================================================
3076 void SMESH_Mesh_i::ExportSAUV (const char* file,
3077 CORBA::Boolean auto_groups)
3078 throw(SALOME::SALOME_Exception)
3080 Unexpect aCatch(SALOME_SalomeException);
3082 _preMeshInfo->FullLoadFromFile();
3084 string aMeshName = prepareMeshNameAndGroups(file, true);
3085 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3086 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3087 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3091 //================================================================================
3093 * \brief Export a mesh to a DAT file
3095 //================================================================================
3097 void SMESH_Mesh_i::ExportDAT (const char *file)
3098 throw(SALOME::SALOME_Exception)
3100 Unexpect aCatch(SALOME_SalomeException);
3102 _preMeshInfo->FullLoadFromFile();
3104 // Update Python script
3105 // check names of groups
3107 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3110 PrepareForWriting(file);
3111 _impl->ExportDAT(file);
3114 //================================================================================
3116 * \brief Export a mesh to an UNV file
3118 //================================================================================
3120 void SMESH_Mesh_i::ExportUNV (const char *file)
3121 throw(SALOME::SALOME_Exception)
3123 Unexpect aCatch(SALOME_SalomeException);
3125 _preMeshInfo->FullLoadFromFile();
3127 // Update Python script
3128 // check names of groups
3130 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3133 PrepareForWriting(file);
3134 _impl->ExportUNV(file);
3137 //================================================================================
3139 * \brief Export a mesh to an STL file
3141 //================================================================================
3143 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3144 throw(SALOME::SALOME_Exception)
3146 Unexpect aCatch(SALOME_SalomeException);
3148 _preMeshInfo->FullLoadFromFile();
3150 // Update Python script
3151 // check names of groups
3153 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3154 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3156 CORBA::String_var name;
3157 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3158 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() );
3159 if ( !so->_is_nil() )
3160 name = so->GetName();
3163 PrepareForWriting( file );
3164 _impl->ExportSTL( file, isascii, name.in() );
3167 //================================================================================
3169 * \brief Export a part of mesh to a med file
3171 //================================================================================
3173 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3175 CORBA::Boolean auto_groups,
3176 SMESH::MED_VERSION version,
3177 CORBA::Boolean overwrite,
3178 CORBA::Boolean autoDimension,
3179 const GEOM::ListOfFields& fields,
3180 const char* geomAssocFields)
3181 throw (SALOME::SALOME_Exception)
3185 _preMeshInfo->FullLoadFromFile();
3188 bool have0dField = false;
3189 if ( fields.length() > 0 )
3191 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3192 if ( shapeToMesh->_is_nil() )
3193 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3195 for ( size_t i = 0; i < fields.length(); ++i )
3197 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3198 THROW_SALOME_CORBA_EXCEPTION
3199 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3200 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3201 if ( fieldShape->_is_nil() )
3202 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3203 if ( !fieldShape->IsSame( shapeToMesh ) )
3204 THROW_SALOME_CORBA_EXCEPTION
3205 ( "Field defined not on shape", SALOME::BAD_PARAM);
3206 if ( fields[i]->GetDimension() == 0 )
3209 if ( geomAssocFields )
3210 for ( int i = 0; geomAssocFields[i]; ++i )
3211 switch ( geomAssocFields[i] ) {
3212 case 'v':case 'e':case 'f':case 's': break;
3213 case 'V':case 'E':case 'F':case 'S': break;
3214 default: THROW_SALOME_CORBA_EXCEPTION
3215 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3219 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3223 string aMeshName = "Mesh";
3224 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3225 if ( CORBA::is_nil( meshPart ) ||
3226 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3228 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3229 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3230 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3231 meshDS = _impl->GetMeshDS();
3236 _preMeshInfo->FullLoadFromFile();
3238 PrepareForWriting(file, overwrite);
3240 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3241 if ( !aStudy->_is_nil() ) {
3242 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3243 if ( !SO->_is_nil() ) {
3244 CORBA::String_var name = SO->GetName();
3248 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3249 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3250 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3251 meshDS = tmpDSDeleter._obj = partDS;
3256 if ( _impl->HasShapeToMesh() )
3258 DriverMED_W_Field fieldWriter;
3259 fieldWriter.SetFile( file );
3260 fieldWriter.SetMeshName( aMeshName );
3261 fieldWriter.AddODOnVertices( have0dField );
3263 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3267 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3268 goList->length( fields.length() );
3269 for ( size_t i = 0; i < fields.length(); ++i )
3271 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3274 TPythonDump() << _this() << ".ExportPartToMED( "
3275 << meshPart << ", r'" << file << "', "
3276 << auto_groups << ", " << version << ", " << overwrite << ", "
3277 << autoDimension << ", " << goList
3278 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3280 SMESH_CATCH( SMESH::throwCorbaException );
3283 //================================================================================
3285 * Write GEOM fields to MED file
3287 //================================================================================
3289 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3290 SMESHDS_Mesh* meshDS,
3291 const GEOM::ListOfFields& fields,
3292 const char* geomAssocFields)
3294 #define METH "SMESH_Mesh_i::exportMEDFields() "
3296 if (( fields.length() < 1 ) &&
3297 ( !geomAssocFields || !geomAssocFields[0] ))
3300 std::vector< std::vector< double > > dblVals;
3301 std::vector< std::vector< int > > intVals;
3302 std::vector< int > subIdsByDim[ 4 ];
3303 const double noneDblValue = 0.;
3304 const double noneIntValue = 0;
3306 for ( size_t iF = 0; iF < fields.length(); ++iF )
3310 int dim = fields[ iF ]->GetDimension();
3311 SMDSAbs_ElementType elemType;
3312 TopAbs_ShapeEnum shapeType;
3314 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3315 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3316 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3317 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3319 continue; // skip fields on whole shape
3321 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3322 if ( dataType == GEOM::FDT_String )
3324 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3325 if ( stepIDs->length() < 1 )
3327 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3328 if ( comps->length() < 1 )
3330 CORBA::String_var name = fields[ iF ]->GetName();
3332 if ( !fieldWriter.Set( meshDS,
3336 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3339 for ( size_t iC = 0; iC < comps->length(); ++iC )
3340 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3342 dblVals.resize( comps->length() );
3343 intVals.resize( comps->length() );
3345 // find sub-shape IDs
3347 std::vector< int >& subIds = subIdsByDim[ dim ];
3348 if ( subIds.empty() )
3349 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3350 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3351 subIds.push_back( id );
3355 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3359 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3361 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3362 if ( step->_is_nil() )
3365 CORBA::Long stamp = step->GetStamp();
3366 CORBA::Long id = step->GetID();
3367 fieldWriter.SetDtIt( int( stamp ), int( id ));
3369 // fill dblVals or intVals
3370 for ( size_t iC = 0; iC < comps->length(); ++iC )
3371 if ( dataType == GEOM::FDT_Double )
3373 dblVals[ iC ].clear();
3374 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3378 intVals[ iC ].clear();
3379 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3383 case GEOM::FDT_Double:
3385 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3386 if ( dblStep->_is_nil() ) continue;
3387 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3388 if ( vv->length() != subIds.size() * comps->length() )
3389 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3390 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3391 for ( size_t iC = 0; iC < comps->length(); ++iC )
3392 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3397 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3398 if ( intStep->_is_nil() ) continue;
3399 GEOM::ListOfLong_var vv = intStep->GetValues();
3400 if ( vv->length() != subIds.size() * comps->length() )
3401 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3402 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3403 for ( size_t iC = 0; iC < comps->length(); ++iC )
3404 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3407 case GEOM::FDT_Bool:
3409 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3410 if ( boolStep->_is_nil() ) continue;
3411 GEOM::short_array_var vv = boolStep->GetValues();
3412 if ( vv->length() != subIds.size() * comps->length() )
3413 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3414 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3415 for ( size_t iC = 0; iC < comps->length(); ++iC )
3416 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3422 // pass values to fieldWriter
3423 elemIt = fieldWriter.GetOrderedElems();
3424 if ( dataType == GEOM::FDT_Double )
3425 while ( elemIt->more() )
3427 const SMDS_MeshElement* e = elemIt->next();
3428 const int shapeID = e->getshapeId();
3429 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3430 for ( size_t iC = 0; iC < comps->length(); ++iC )
3431 fieldWriter.AddValue( noneDblValue );
3433 for ( size_t iC = 0; iC < comps->length(); ++iC )
3434 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3437 while ( elemIt->more() )
3439 const SMDS_MeshElement* e = elemIt->next();
3440 const int shapeID = e->getshapeId();
3441 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3442 for ( size_t iC = 0; iC < comps->length(); ++iC )
3443 fieldWriter.AddValue( (double) noneIntValue );
3445 for ( size_t iC = 0; iC < comps->length(); ++iC )
3446 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3450 fieldWriter.Perform();
3451 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3452 if ( res && res->IsKO() )
3454 if ( res->myComment.empty() )
3455 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3457 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3463 if ( !geomAssocFields || !geomAssocFields[0] )
3466 // write geomAssocFields
3468 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3469 shapeDim[ TopAbs_COMPOUND ] = 3;
3470 shapeDim[ TopAbs_COMPSOLID ] = 3;
3471 shapeDim[ TopAbs_SOLID ] = 3;
3472 shapeDim[ TopAbs_SHELL ] = 2;
3473 shapeDim[ TopAbs_FACE ] = 2;
3474 shapeDim[ TopAbs_WIRE ] = 1;
3475 shapeDim[ TopAbs_EDGE ] = 1;
3476 shapeDim[ TopAbs_VERTEX ] = 0;
3477 shapeDim[ TopAbs_SHAPE ] = 3;
3479 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3481 std::vector< std::string > compNames;
3482 switch ( geomAssocFields[ iF ]) {
3484 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3485 compNames.push_back( "dim" );
3488 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3491 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3494 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3498 compNames.push_back( "id" );
3499 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3500 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3502 fieldWriter.SetDtIt( -1, -1 );
3504 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3508 if ( compNames.size() == 2 ) // _vertices_
3509 while ( elemIt->more() )
3511 const SMDS_MeshElement* e = elemIt->next();
3512 const int shapeID = e->getshapeId();
3515 fieldWriter.AddValue( (double) -1 );
3516 fieldWriter.AddValue( (double) -1 );
3520 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3521 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3522 fieldWriter.AddValue( (double) shapeID );
3526 while ( elemIt->more() )
3528 const SMDS_MeshElement* e = elemIt->next();
3529 const int shapeID = e->getshapeId();
3531 fieldWriter.AddValue( (double) -1 );
3533 fieldWriter.AddValue( (double) shapeID );
3537 fieldWriter.Perform();
3538 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3539 if ( res && res->IsKO() )
3541 if ( res->myComment.empty() )
3542 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3544 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3547 } // loop on geomAssocFields
3552 //================================================================================
3554 * \brief Export a part of mesh to a DAT file
3556 //================================================================================
3558 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3560 throw (SALOME::SALOME_Exception)
3562 Unexpect aCatch(SALOME_SalomeException);
3564 _preMeshInfo->FullLoadFromFile();
3566 PrepareForWriting(file);
3568 SMESH_MeshPartDS partDS( meshPart );
3569 _impl->ExportDAT(file,&partDS);
3571 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3572 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3574 //================================================================================
3576 * \brief Export a part of mesh to an UNV file
3578 //================================================================================
3580 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3582 throw (SALOME::SALOME_Exception)
3584 Unexpect aCatch(SALOME_SalomeException);
3586 _preMeshInfo->FullLoadFromFile();
3588 PrepareForWriting(file);
3590 SMESH_MeshPartDS partDS( meshPart );
3591 _impl->ExportUNV(file, &partDS);
3593 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3594 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3596 //================================================================================
3598 * \brief Export a part of mesh to an STL file
3600 //================================================================================
3602 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3604 ::CORBA::Boolean isascii)
3605 throw (SALOME::SALOME_Exception)
3607 Unexpect aCatch(SALOME_SalomeException);
3609 _preMeshInfo->FullLoadFromFile();
3611 PrepareForWriting(file);
3613 CORBA::String_var name;
3614 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3615 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3616 if ( !so->_is_nil() )
3617 name = so->GetName();
3619 SMESH_MeshPartDS partDS( meshPart );
3620 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3622 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3623 << meshPart<< ", r'" << file << "', " << isascii << ")";
3626 //================================================================================
3628 * \brief Export a part of mesh to an STL file
3630 //================================================================================
3632 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3634 CORBA::Boolean overwrite,
3635 CORBA::Boolean groupElemsByType)
3636 throw (SALOME::SALOME_Exception)
3639 Unexpect aCatch(SALOME_SalomeException);
3641 _preMeshInfo->FullLoadFromFile();
3643 PrepareForWriting(file,overwrite);
3645 std::string meshName("");
3646 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3647 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3648 if ( !so->_is_nil() )
3650 CORBA::String_var name = so->GetName();
3651 meshName = name.in();
3655 SMESH_MeshPartDS partDS( meshPart );
3656 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3658 SMESH_CATCH( SMESH::throwCorbaException );
3660 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3661 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3663 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3667 //================================================================================
3669 * \brief Export a part of mesh to a GMF file
3671 //================================================================================
3673 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3675 bool withRequiredGroups)
3676 throw (SALOME::SALOME_Exception)
3678 Unexpect aCatch(SALOME_SalomeException);
3680 _preMeshInfo->FullLoadFromFile();
3682 PrepareForWriting(file,/*overwrite=*/true);
3684 SMESH_MeshPartDS partDS( meshPart );
3685 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3687 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3688 << meshPart<< ", r'"
3690 << withRequiredGroups << ")";
3693 //=============================================================================
3695 * Return computation progress [0.,1]
3697 //=============================================================================
3699 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3703 return _impl->GetComputeProgress();
3705 SMESH_CATCH( SMESH::doNothing );
3709 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3711 Unexpect aCatch(SALOME_SalomeException);
3713 return _preMeshInfo->NbNodes();
3715 return _impl->NbNodes();
3718 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3720 Unexpect aCatch(SALOME_SalomeException);
3722 return _preMeshInfo->NbElements();
3724 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3727 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3729 Unexpect aCatch(SALOME_SalomeException);
3731 return _preMeshInfo->Nb0DElements();
3733 return _impl->Nb0DElements();
3736 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3738 Unexpect aCatch(SALOME_SalomeException);
3740 return _preMeshInfo->NbBalls();
3742 return _impl->NbBalls();
3745 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3747 Unexpect aCatch(SALOME_SalomeException);
3749 return _preMeshInfo->NbEdges();
3751 return _impl->NbEdges();
3754 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3755 throw(SALOME::SALOME_Exception)
3757 Unexpect aCatch(SALOME_SalomeException);
3759 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3761 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3764 //=============================================================================
3766 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3768 Unexpect aCatch(SALOME_SalomeException);
3770 return _preMeshInfo->NbFaces();
3772 return _impl->NbFaces();
3775 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3777 Unexpect aCatch(SALOME_SalomeException);
3779 return _preMeshInfo->NbTriangles();
3781 return _impl->NbTriangles();
3784 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3786 Unexpect aCatch(SALOME_SalomeException);
3788 return _preMeshInfo->NbBiQuadTriangles();
3790 return _impl->NbBiQuadTriangles();
3793 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3795 Unexpect aCatch(SALOME_SalomeException);
3797 return _preMeshInfo->NbQuadrangles();
3799 return _impl->NbQuadrangles();
3802 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3804 Unexpect aCatch(SALOME_SalomeException);
3806 return _preMeshInfo->NbBiQuadQuadrangles();
3808 return _impl->NbBiQuadQuadrangles();
3811 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3813 Unexpect aCatch(SALOME_SalomeException);
3815 return _preMeshInfo->NbPolygons();
3817 return _impl->NbPolygons();
3820 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3822 Unexpect aCatch(SALOME_SalomeException);
3824 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3826 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3829 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3830 throw(SALOME::SALOME_Exception)
3832 Unexpect aCatch(SALOME_SalomeException);
3834 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3836 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3839 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3840 throw(SALOME::SALOME_Exception)
3842 Unexpect aCatch(SALOME_SalomeException);
3844 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3846 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3849 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3850 throw(SALOME::SALOME_Exception)
3852 Unexpect aCatch(SALOME_SalomeException);
3854 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3856 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3859 //=============================================================================
3861 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3863 Unexpect aCatch(SALOME_SalomeException);
3865 return _preMeshInfo->NbVolumes();
3867 return _impl->NbVolumes();
3870 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3872 Unexpect aCatch(SALOME_SalomeException);
3874 return _preMeshInfo->NbTetras();
3876 return _impl->NbTetras();
3879 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3881 Unexpect aCatch(SALOME_SalomeException);
3883 return _preMeshInfo->NbHexas();
3885 return _impl->NbHexas();
3888 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3890 Unexpect aCatch(SALOME_SalomeException);
3892 return _preMeshInfo->NbTriQuadHexas();
3894 return _impl->NbTriQuadraticHexas();
3897 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3899 Unexpect aCatch(SALOME_SalomeException);
3901 return _preMeshInfo->NbPyramids();
3903 return _impl->NbPyramids();
3906 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3908 Unexpect aCatch(SALOME_SalomeException);
3910 return _preMeshInfo->NbPrisms();
3912 return _impl->NbPrisms();
3915 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3917 Unexpect aCatch(SALOME_SalomeException);
3919 return _preMeshInfo->NbHexPrisms();
3921 return _impl->NbHexagonalPrisms();
3924 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3926 Unexpect aCatch(SALOME_SalomeException);
3928 return _preMeshInfo->NbPolyhedrons();
3930 return _impl->NbPolyhedrons();
3933 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3934 throw(SALOME::SALOME_Exception)
3936 Unexpect aCatch(SALOME_SalomeException);
3938 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3940 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3943 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3944 throw(SALOME::SALOME_Exception)
3946 Unexpect aCatch(SALOME_SalomeException);
3948 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3950 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3953 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3954 throw(SALOME::SALOME_Exception)
3956 Unexpect aCatch(SALOME_SalomeException);
3958 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3960 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3963 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3964 throw(SALOME::SALOME_Exception)
3966 Unexpect aCatch(SALOME_SalomeException);
3968 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3970 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3973 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3974 throw(SALOME::SALOME_Exception)
3976 Unexpect aCatch(SALOME_SalomeException);
3978 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3980 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3983 //=============================================================================
3985 * Returns nb of published sub-meshes
3987 //=============================================================================
3989 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3991 Unexpect aCatch(SALOME_SalomeException);
3992 return _mapSubMesh_i.size();
3995 //=============================================================================
3997 * Dumps mesh into a string
3999 //=============================================================================
4001 char* SMESH_Mesh_i::Dump()
4005 return CORBA::string_dup( os.str().c_str() );
4008 //=============================================================================
4010 * Method of SMESH_IDSource interface
4012 //=============================================================================
4014 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4016 return GetElementsId();
4019 //=============================================================================
4021 * Returns ids of all elements
4023 //=============================================================================
4025 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4026 throw (SALOME::SALOME_Exception)
4028 Unexpect aCatch(SALOME_SalomeException);
4030 _preMeshInfo->FullLoadFromFile();
4032 SMESH::long_array_var aResult = new SMESH::long_array();
4033 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4035 if ( aSMESHDS_Mesh == NULL )
4036 return aResult._retn();
4038 long nbElements = NbElements();
4039 aResult->length( nbElements );
4040 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4041 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4042 aResult[i] = anIt->next()->GetID();
4044 return aResult._retn();
4048 //=============================================================================
4050 * Returns ids of all elements of given type
4052 //=============================================================================
4054 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4055 throw (SALOME::SALOME_Exception)
4057 Unexpect aCatch(SALOME_SalomeException);
4059 _preMeshInfo->FullLoadFromFile();
4061 SMESH::long_array_var aResult = new SMESH::long_array();
4062 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4064 if ( aSMESHDS_Mesh == NULL )
4065 return aResult._retn();
4067 long nbElements = NbElements();
4069 // No sense in returning ids of elements along with ids of nodes:
4070 // when theElemType == SMESH::ALL, return node ids only if
4071 // there are no elements
4072 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4073 return GetNodesId();
4075 aResult->length( nbElements );
4079 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4080 while ( i < nbElements && anIt->more() )
4081 aResult[i++] = anIt->next()->GetID();
4083 aResult->length( i );
4085 return aResult._retn();
4088 //=============================================================================
4090 * Returns ids of all nodes
4092 //=============================================================================
4094 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4095 throw (SALOME::SALOME_Exception)
4097 Unexpect aCatch(SALOME_SalomeException);
4099 _preMeshInfo->FullLoadFromFile();
4101 SMESH::long_array_var aResult = new SMESH::long_array();
4102 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4104 if ( aSMESHDS_Mesh == NULL )
4105 return aResult._retn();
4107 long nbNodes = NbNodes();
4108 aResult->length( nbNodes );
4109 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4110 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4111 aResult[i] = anIt->next()->GetID();
4113 return aResult._retn();
4116 //=============================================================================
4120 //=============================================================================
4122 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4123 throw (SALOME::SALOME_Exception)
4125 SMESH::ElementType type = SMESH::ALL;
4129 _preMeshInfo->FullLoadFromFile();
4131 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4133 SMESH_CATCH( SMESH::throwCorbaException );
4138 //=============================================================================
4142 //=============================================================================
4144 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4145 throw (SALOME::SALOME_Exception)
4148 _preMeshInfo->FullLoadFromFile();
4150 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4152 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4154 return ( SMESH::EntityType ) e->GetEntityType();
4157 //=============================================================================
4161 //=============================================================================
4163 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4164 throw (SALOME::SALOME_Exception)
4167 _preMeshInfo->FullLoadFromFile();
4169 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4171 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4173 return ( SMESH::GeometryType ) e->GetGeomType();
4176 //=============================================================================
4178 * Returns ID of elements for given submesh
4180 //=============================================================================
4181 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4182 throw (SALOME::SALOME_Exception)
4184 SMESH::long_array_var aResult = new SMESH::long_array();
4188 _preMeshInfo->FullLoadFromFile();
4190 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4191 if(!SM) return aResult._retn();
4193 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4194 if(!SDSM) return aResult._retn();
4196 aResult->length(SDSM->NbElements());
4198 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4200 while ( eIt->more() ) {
4201 aResult[i++] = eIt->next()->GetID();
4204 SMESH_CATCH( SMESH::throwCorbaException );
4206 return aResult._retn();
4209 //=============================================================================
4211 * Returns ID of nodes for given submesh
4212 * If param all==true - returns all nodes, else -
4213 * returns only nodes on shapes.
4215 //=============================================================================
4217 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4219 throw (SALOME::SALOME_Exception)
4221 SMESH::long_array_var aResult = new SMESH::long_array();
4225 _preMeshInfo->FullLoadFromFile();
4227 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4228 if(!SM) return aResult._retn();
4230 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4231 if(!SDSM) return aResult._retn();
4234 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4235 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4236 while ( nIt->more() ) {
4237 const SMDS_MeshNode* elem = nIt->next();
4238 theElems.insert( elem->GetID() );
4241 else { // all nodes of submesh elements
4242 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4243 while ( eIt->more() ) {
4244 const SMDS_MeshElement* anElem = eIt->next();
4245 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4246 while ( nIt->more() ) {
4247 const SMDS_MeshElement* elem = nIt->next();
4248 theElems.insert( elem->GetID() );
4253 aResult->length(theElems.size());
4254 set<int>::iterator itElem;
4256 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4257 aResult[i++] = *itElem;
4259 SMESH_CATCH( SMESH::throwCorbaException );
4261 return aResult._retn();
4264 //=============================================================================
4266 * Returns type of elements for given submesh
4268 //=============================================================================
4270 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4271 throw (SALOME::SALOME_Exception)
4273 SMESH::ElementType type = SMESH::ALL;
4277 _preMeshInfo->FullLoadFromFile();
4279 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4280 if(!SM) return SMESH::ALL;
4282 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4283 if(!SDSM) return SMESH::ALL;
4285 if(SDSM->NbElements()==0)
4286 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4288 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4289 const SMDS_MeshElement* anElem = eIt->next();
4291 type = ( SMESH::ElementType ) anElem->GetType();
4293 SMESH_CATCH( SMESH::throwCorbaException );
4299 //=============================================================================
4301 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4303 //=============================================================================
4305 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4308 _preMeshInfo->FullLoadFromFile();
4310 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4311 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4316 //=============================================================================
4318 * Get XYZ coordinates of node as list of double
4319 * If there is not node for given ID - returns empty list
4321 //=============================================================================
4323 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4326 _preMeshInfo->FullLoadFromFile();
4328 SMESH::double_array_var aResult = new SMESH::double_array();
4329 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4330 if ( aSMESHDS_Mesh == NULL )
4331 return aResult._retn();
4334 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4336 return aResult._retn();
4340 aResult[0] = aNode->X();
4341 aResult[1] = aNode->Y();
4342 aResult[2] = aNode->Z();
4343 return aResult._retn();
4347 //=============================================================================
4349 * For given node returns list of IDs of inverse elements
4350 * If there is not node for given ID - returns empty list
4352 //=============================================================================
4354 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4357 _preMeshInfo->FullLoadFromFile();
4359 SMESH::long_array_var aResult = new SMESH::long_array();
4360 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4361 if ( aSMESHDS_Mesh == NULL )
4362 return aResult._retn();
4365 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4367 return aResult._retn();
4369 // find inverse elements
4370 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4371 aResult->length( aNode->NbInverseElements() );
4372 for( int i = 0; eIt->more(); ++i )
4374 const SMDS_MeshElement* elem = eIt->next();
4375 aResult[ i ] = elem->GetID();
4377 return aResult._retn();
4380 //=============================================================================
4382 * \brief Return position of a node on shape
4384 //=============================================================================
4386 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4389 _preMeshInfo->FullLoadFromFile();
4391 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4392 aNodePosition->shapeID = 0;
4393 aNodePosition->shapeType = GEOM::SHAPE;
4395 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4396 if ( !mesh ) return aNodePosition;
4398 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4400 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4402 aNodePosition->shapeID = aNode->getshapeId();
4403 switch ( pos->GetTypeOfPosition() ) {
4405 aNodePosition->shapeType = GEOM::EDGE;
4406 aNodePosition->params.length(1);
4407 aNodePosition->params[0] =
4408 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4411 aNodePosition->shapeType = GEOM::FACE;
4412 aNodePosition->params.length(2);
4413 aNodePosition->params[0] =
4414 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4415 aNodePosition->params[1] =
4416 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4418 case SMDS_TOP_VERTEX:
4419 aNodePosition->shapeType = GEOM::VERTEX;
4421 case SMDS_TOP_3DSPACE:
4422 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4423 aNodePosition->shapeType = GEOM::SOLID;
4424 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4425 aNodePosition->shapeType = GEOM::SHELL;
4431 return aNodePosition;
4434 //=============================================================================
4436 * \brief Return position of an element on shape
4438 //=============================================================================
4440 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4443 _preMeshInfo->FullLoadFromFile();
4445 SMESH::ElementPosition anElementPosition;
4446 anElementPosition.shapeID = 0;
4447 anElementPosition.shapeType = GEOM::SHAPE;
4449 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4450 if ( !mesh ) return anElementPosition;
4452 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4454 anElementPosition.shapeID = anElem->getshapeId();
4455 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4456 if ( !aSp.IsNull() ) {
4457 switch ( aSp.ShapeType() ) {
4459 anElementPosition.shapeType = GEOM::EDGE;
4462 anElementPosition.shapeType = GEOM::FACE;
4465 anElementPosition.shapeType = GEOM::VERTEX;
4468 anElementPosition.shapeType = GEOM::SOLID;
4471 anElementPosition.shapeType = GEOM::SHELL;
4477 return anElementPosition;
4480 //=============================================================================
4482 * If given element is node returns IDs of shape from position
4483 * If there is not node for given ID - returns -1
4485 //=============================================================================
4487 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4490 _preMeshInfo->FullLoadFromFile();
4492 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4493 if ( aSMESHDS_Mesh == NULL )
4497 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4499 return aNode->getshapeId();
4506 //=============================================================================
4508 * For given element returns ID of result shape after
4509 * ::FindShape() from SMESH_MeshEditor
4510 * If there is not element for given ID - returns -1
4512 //=============================================================================
4514 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4517 _preMeshInfo->FullLoadFromFile();
4519 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4520 if ( aSMESHDS_Mesh == NULL )
4523 // try to find element
4524 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4528 ::SMESH_MeshEditor aMeshEditor(_impl);
4529 int index = aMeshEditor.FindShape( elem );
4537 //=============================================================================
4539 * Returns number of nodes for given element
4540 * If there is not element for given ID - returns -1
4542 //=============================================================================
4544 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4547 _preMeshInfo->FullLoadFromFile();
4549 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4550 if ( aSMESHDS_Mesh == NULL ) return -1;
4551 // try to find element
4552 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4553 if(!elem) return -1;
4554 return elem->NbNodes();
4558 //=============================================================================
4560 * Returns ID of node by given index for given element
4561 * If there is not element for given ID - returns -1
4562 * If there is not node for given index - returns -2
4564 //=============================================================================
4566 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4569 _preMeshInfo->FullLoadFromFile();
4571 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4572 if ( aSMESHDS_Mesh == NULL ) return -1;
4573 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4574 if(!elem) return -1;
4575 if( index>=elem->NbNodes() || index<0 ) return -1;
4576 return elem->GetNode(index)->GetID();
4579 //=============================================================================
4581 * Returns IDs of nodes of given element
4583 //=============================================================================
4585 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4588 _preMeshInfo->FullLoadFromFile();
4590 SMESH::long_array_var aResult = new SMESH::long_array();
4591 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4593 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4595 aResult->length( elem->NbNodes() );
4596 for ( int i = 0; i < elem->NbNodes(); ++i )
4597 aResult[ i ] = elem->GetNode( i )->GetID();
4600 return aResult._retn();
4603 //=============================================================================
4605 * Returns true if given node is medium node
4606 * in given quadratic element
4608 //=============================================================================
4610 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4613 _preMeshInfo->FullLoadFromFile();
4615 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4616 if ( aSMESHDS_Mesh == NULL ) return false;
4618 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4619 if(!aNode) return false;
4620 // try to find element
4621 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4622 if(!elem) return false;
4624 return elem->IsMediumNode(aNode);
4628 //=============================================================================
4630 * Returns true if given node is medium node
4631 * in one of quadratic elements
4633 //=============================================================================
4635 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4636 SMESH::ElementType theElemType)
4639 _preMeshInfo->FullLoadFromFile();
4641 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4642 if ( aSMESHDS_Mesh == NULL ) return false;
4645 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4646 if(!aNode) return false;
4648 SMESH_MesherHelper aHelper( *(_impl) );
4650 SMDSAbs_ElementType aType;
4651 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4652 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4653 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4654 else aType = SMDSAbs_All;
4656 return aHelper.IsMedium(aNode,aType);
4660 //=============================================================================
4662 * Returns number of edges for given element
4664 //=============================================================================
4666 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4669 _preMeshInfo->FullLoadFromFile();
4671 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4672 if ( aSMESHDS_Mesh == NULL ) return -1;
4673 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4674 if(!elem) return -1;
4675 return elem->NbEdges();
4679 //=============================================================================
4681 * Returns number of faces for given element
4683 //=============================================================================
4685 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4688 _preMeshInfo->FullLoadFromFile();
4690 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4691 if ( aSMESHDS_Mesh == NULL ) return -1;
4692 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4693 if(!elem) return -1;
4694 return elem->NbFaces();
4697 //=======================================================================
4698 //function : GetElemFaceNodes
4699 //purpose : Returns nodes of given face (counted from zero) for given element.
4700 //=======================================================================
4702 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4703 CORBA::Short faceIndex)
4706 _preMeshInfo->FullLoadFromFile();
4708 SMESH::long_array_var aResult = new SMESH::long_array();
4709 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4711 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4713 SMDS_VolumeTool vtool( elem );
4714 if ( faceIndex < vtool.NbFaces() )
4716 aResult->length( vtool.NbFaceNodes( faceIndex ));
4717 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4718 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4719 aResult[ i ] = nn[ i ]->GetID();
4723 return aResult._retn();
4726 //=======================================================================
4727 //function : GetElemFaceNodes
4728 //purpose : Returns three components of normal of given mesh face.
4729 //=======================================================================
4731 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4732 CORBA::Boolean normalized)
4735 _preMeshInfo->FullLoadFromFile();
4737 SMESH::double_array_var aResult = new SMESH::double_array();
4739 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4742 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4744 aResult->length( 3 );
4745 aResult[ 0 ] = normal.X();
4746 aResult[ 1 ] = normal.Y();
4747 aResult[ 2 ] = normal.Z();
4750 return aResult._retn();
4753 //=======================================================================
4754 //function : FindElementByNodes
4755 //purpose : Returns an element based on all given nodes.
4756 //=======================================================================
4758 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4761 _preMeshInfo->FullLoadFromFile();
4763 CORBA::Long elemID(0);
4764 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4766 vector< const SMDS_MeshNode * > nn( nodes.length() );
4767 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4768 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4771 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4772 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4773 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4774 _impl->NbVolumes( ORDER_QUADRATIC )))
4775 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4777 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4782 //================================================================================
4784 * \brief Return elements including all given nodes.
4786 //================================================================================
4788 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4789 SMESH::ElementType elemType)
4792 _preMeshInfo->FullLoadFromFile();
4794 SMESH::long_array_var result = new SMESH::long_array();
4796 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4798 vector< const SMDS_MeshNode * > nn( nodes.length() );
4799 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4800 nn[i] = mesh->FindNode( nodes[i] );
4802 std::vector<const SMDS_MeshElement *> elems;
4803 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4804 result->length( elems.size() );
4805 for ( size_t i = 0; i < elems.size(); ++i )
4806 result[i] = elems[i]->GetID();
4808 return result._retn();
4811 //=============================================================================
4813 * Returns true if given element is polygon
4815 //=============================================================================
4817 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4820 _preMeshInfo->FullLoadFromFile();
4822 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4823 if ( aSMESHDS_Mesh == NULL ) return false;
4824 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4825 if(!elem) return false;
4826 return elem->IsPoly();
4830 //=============================================================================
4832 * Returns true if given element is quadratic
4834 //=============================================================================
4836 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4839 _preMeshInfo->FullLoadFromFile();
4841 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4842 if ( aSMESHDS_Mesh == NULL ) return false;
4843 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4844 if(!elem) return false;
4845 return elem->IsQuadratic();
4848 //=============================================================================
4850 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4852 //=============================================================================
4854 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4857 _preMeshInfo->FullLoadFromFile();
4859 if ( const SMDS_BallElement* ball =
4860 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4861 return ball->GetDiameter();
4866 //=============================================================================
4868 * Returns bary center for given element
4870 //=============================================================================
4872 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4875 _preMeshInfo->FullLoadFromFile();
4877 SMESH::double_array_var aResult = new SMESH::double_array();
4878 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4879 if ( aSMESHDS_Mesh == NULL )
4880 return aResult._retn();
4882 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4884 return aResult._retn();
4886 if(elem->GetType()==SMDSAbs_Volume) {
4887 SMDS_VolumeTool aTool;
4888 if(aTool.Set(elem)) {
4890 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4895 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4897 double x=0., y=0., z=0.;
4898 for(; anIt->more(); ) {
4900 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4914 return aResult._retn();
4917 //================================================================================
4919 * \brief Create a group of elements preventing computation of a sub-shape
4921 //================================================================================
4923 SMESH::ListOfGroups*
4924 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4925 const char* theGroupName )
4926 throw ( SALOME::SALOME_Exception )
4928 Unexpect aCatch(SALOME_SalomeException);
4930 if ( !theGroupName || strlen( theGroupName) == 0 )
4931 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4933 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4934 ::SMESH_MeshEditor::ElemFeatures elemType;
4936 // submesh by subshape id
4937 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4938 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4941 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4942 if ( error && !error->myBadElements.empty())
4944 // sort bad elements by type
4945 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4946 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4947 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4948 for ( ; elemIt != elemEnd; ++elemIt )
4950 const SMDS_MeshElement* elem = *elemIt;
4951 if ( !elem ) continue;
4953 if ( elem->GetID() < 1 )
4955 // elem is a temporary element, make a real element
4956 vector< const SMDS_MeshNode* > nodes;
4957 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4958 while ( nIt->more() && elem )
4960 nodes.push_back( nIt->next() );
4961 if ( nodes.back()->GetID() < 1 )
4962 elem = 0; // a temporary element on temporary nodes
4966 ::SMESH_MeshEditor editor( _impl );
4967 elem = editor.AddElement( nodes, elemType.Init( elem ));
4971 elemsByType[ elem->GetType() ].push_back( elem );
4974 // how many groups to create?
4976 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4977 nbTypes += int( !elemsByType[ i ].empty() );
4978 groups->length( nbTypes );
4981 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4983 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4984 if ( elems.empty() ) continue;
4986 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4987 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4989 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4990 SMESH::SMESH_Mesh_var mesh = _this();
4991 SALOMEDS::SObject_wrap aSO =
4992 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4993 GEOM::GEOM_Object::_nil(), theGroupName);
4995 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4996 if ( !grp_i ) continue;
4998 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4999 for ( size_t iE = 0; iE < elems.size(); ++iE )
5000 grpDS->SMDSGroup().Add( elems[ iE ]);
5005 return groups._retn();
5008 //=============================================================================
5010 * Create and publish group servants if any groups were imported or created anyhow
5012 //=============================================================================
5014 void SMESH_Mesh_i::CreateGroupServants()
5016 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5017 SMESH::SMESH_Mesh_var aMesh = _this();
5020 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5021 while ( groupIt->more() )
5023 ::SMESH_Group* group = groupIt->next();
5024 int anId = group->GetGroupDS()->GetID();
5026 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5027 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5029 addedIDs.insert( anId );
5031 SMESH_GroupBase_i* aGroupImpl;
5033 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5034 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5036 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5037 shape = groupOnGeom->GetShape();
5040 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5043 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5044 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5045 aGroupImpl->Register();
5047 // register CORBA object for persistence
5048 int nextId = _gen_i->RegisterObject( groupVar );
5049 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5050 else { nextId = 0; } // avoid "unused variable" warning in release mode
5052 // publishing the groups in the study
5053 if ( !aStudy->_is_nil() ) {
5054 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5055 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5058 if ( !addedIDs.empty() )
5061 set<int>::iterator id = addedIDs.begin();
5062 for ( ; id != addedIDs.end(); ++id )
5064 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5065 int i = std::distance( _mapGroups.begin(), it );
5066 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5071 //=============================================================================
5073 * \brief Return groups cantained in _mapGroups by their IDs
5075 //=============================================================================
5077 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5079 int nbGroups = groupIDs.size();
5080 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5081 aList->length( nbGroups );
5083 list<int>::const_iterator ids = groupIDs.begin();
5084 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5086 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5087 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5088 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5090 aList->length( nbGroups );
5091 return aList._retn();
5094 //=============================================================================
5096 * \brief Return information about imported file
5098 //=============================================================================
5100 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5102 SMESH::MedFileInfo_var res( _medFileInfo );
5103 if ( !res.operator->() ) {
5104 res = new SMESH::MedFileInfo;
5106 res->fileSize = res->major = res->minor = res->release = -1;
5111 //=============================================================================
5113 * \brief Pass names of mesh groups from study to mesh DS
5115 //=============================================================================
5117 void SMESH_Mesh_i::checkGroupNames()
5119 int nbGrp = NbGroups();
5123 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5124 if ( aStudy->_is_nil() )
5125 return; // nothing to do
5127 SMESH::ListOfGroups* grpList = 0;
5128 // avoid dump of "GetGroups"
5130 // store python dump into a local variable inside local scope
5131 SMESH::TPythonDump pDump; // do not delete this line of code
5132 grpList = GetGroups();
5135 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5136 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5139 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5140 if ( aGrpSO->_is_nil() )
5142 // correct name of the mesh group if necessary
5143 const char* guiName = aGrpSO->GetName();
5144 if ( strcmp(guiName, aGrp->GetName()) )
5145 aGrp->SetName( guiName );
5149 //=============================================================================
5151 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5153 //=============================================================================
5154 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5156 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5160 //=============================================================================
5162 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5164 //=============================================================================
5166 char* SMESH_Mesh_i::GetParameters()
5168 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5171 //=============================================================================
5173 * \brief Returns list of notebook variables used for last Mesh operation
5175 //=============================================================================
5176 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5178 SMESH::string_array_var aResult = new SMESH::string_array();
5179 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5181 CORBA::String_var aParameters = GetParameters();
5182 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5183 if ( !aStudy->_is_nil()) {
5184 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5185 if ( aSections->length() > 0 ) {
5186 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5187 aResult->length( aVars.length() );
5188 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5189 aResult[i] = CORBA::string_dup( aVars[i] );
5193 return aResult._retn();
5196 //=======================================================================
5197 //function : GetTypes
5198 //purpose : Returns types of elements it contains
5199 //=======================================================================
5201 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5204 return _preMeshInfo->GetTypes();
5206 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5210 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5211 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5212 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5213 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5214 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5215 if (_impl->NbNodes() &&
5216 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5217 types->length( nbTypes );
5219 return types._retn();
5222 //=======================================================================
5223 //function : GetMesh
5224 //purpose : Returns self
5225 //=======================================================================
5227 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5229 return SMESH::SMESH_Mesh::_duplicate( _this() );
5232 //=======================================================================
5233 //function : IsMeshInfoCorrect
5234 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5235 // * happen if mesh data is not yet fully loaded from the file of study.
5236 //=======================================================================
5238 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5240 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5243 //=============================================================================
5245 * \brief Returns number of mesh elements per each \a EntityType
5247 //=============================================================================
5249 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5252 return _preMeshInfo->GetMeshInfo();
5254 SMESH::long_array_var aRes = new SMESH::long_array();
5255 aRes->length(SMESH::Entity_Last);
5256 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5258 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5260 return aRes._retn();
5261 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5262 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5263 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5264 return aRes._retn();
5267 //=============================================================================
5269 * \brief Returns number of mesh elements per each \a ElementType
5271 //=============================================================================
5273 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5275 SMESH::long_array_var aRes = new SMESH::long_array();
5276 aRes->length(SMESH::NB_ELEMENT_TYPES);
5277 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5280 const SMDS_MeshInfo* meshInfo = 0;
5282 meshInfo = _preMeshInfo;
5283 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5284 meshInfo = & meshDS->GetMeshInfo();
5287 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5288 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5290 return aRes._retn();
5293 //=============================================================================
5295 * Collect statistic of mesh elements given by iterator
5297 //=============================================================================
5299 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5300 SMESH::long_array& theInfo)
5302 if (!theItr) return;
5303 while (theItr->more())
5304 theInfo[ theItr->next()->GetEntityType() ]++;
5306 //=============================================================================
5308 * Returns mesh unstructed grid information.
5310 //=============================================================================
5312 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5314 SALOMEDS::TMPFile_var SeqFile;
5315 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5316 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5318 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5319 aWriter->WriteToOutputStringOn();
5320 aWriter->SetInputData(aGrid);
5321 aWriter->SetFileTypeToBinary();
5323 char* str = aWriter->GetOutputString();
5324 int size = aWriter->GetOutputStringLength();
5326 //Allocate octect buffer of required size
5327 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5328 //Copy ostrstream content to the octect buffer
5329 memcpy(OctetBuf, str, size);
5330 //Create and return TMPFile
5331 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5335 return SeqFile._retn();
5338 //=============================================================================
5339 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5340 * SMESH::ElementType type) */
5342 using namespace SMESH::Controls;
5343 //-----------------------------------------------------------------------------
5344 struct PredicateIterator : public SMDS_ElemIterator
5346 SMDS_ElemIteratorPtr _elemIter;
5347 PredicatePtr _predicate;
5348 const SMDS_MeshElement* _elem;
5350 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5351 PredicatePtr predicate):
5352 _elemIter(iterator), _predicate(predicate)
5360 virtual const SMDS_MeshElement* next()
5362 const SMDS_MeshElement* res = _elem;
5364 while ( _elemIter->more() && !_elem )
5366 _elem = _elemIter->next();
5367 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5374 //-----------------------------------------------------------------------------
5375 struct IDSourceIterator : public SMDS_ElemIterator
5377 const CORBA::Long* _idPtr;
5378 const CORBA::Long* _idEndPtr;
5379 SMESH::long_array_var _idArray;
5380 const SMDS_Mesh* _mesh;
5381 const SMDSAbs_ElementType _type;
5382 const SMDS_MeshElement* _elem;
5384 IDSourceIterator( const SMDS_Mesh* mesh,
5385 const CORBA::Long* ids,
5387 SMDSAbs_ElementType type):
5388 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5390 if ( _idPtr && nbIds && _mesh )
5393 IDSourceIterator( const SMDS_Mesh* mesh,
5394 SMESH::long_array* idArray,
5395 SMDSAbs_ElementType type):
5396 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5398 if ( idArray && _mesh )
5400 _idPtr = &_idArray[0];
5401 _idEndPtr = _idPtr + _idArray->length();
5409 virtual const SMDS_MeshElement* next()
5411 const SMDS_MeshElement* res = _elem;
5413 while ( _idPtr < _idEndPtr && !_elem )
5415 if ( _type == SMDSAbs_Node )
5417 _elem = _mesh->FindNode( *_idPtr++ );
5419 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5420 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5428 //-----------------------------------------------------------------------------
5430 struct NodeOfElemIterator : public SMDS_ElemIterator
5432 TColStd_MapOfInteger _checkedNodeIDs;
5433 SMDS_ElemIteratorPtr _elemIter;
5434 SMDS_ElemIteratorPtr _nodeIter;
5435 const SMDS_MeshElement* _node;
5437 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5439 if ( _elemIter && _elemIter->more() )
5441 _nodeIter = _elemIter->next()->nodesIterator();
5449 virtual const SMDS_MeshElement* next()
5451 const SMDS_MeshElement* res = _node;
5453 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5455 if ( _nodeIter->more() )
5457 _node = _nodeIter->next();
5458 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5463 _nodeIter = _elemIter->next()->nodesIterator();
5471 //=============================================================================
5473 * Return iterator on elements of given type in given object
5475 //=============================================================================
5477 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5478 SMESH::ElementType theType)
5480 SMDS_ElemIteratorPtr elemIt;
5481 bool typeOK = ( theType == SMESH::ALL );
5482 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5484 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5485 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5486 if ( !mesh_i ) return elemIt;
5487 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5489 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5491 elemIt = meshDS->elementsIterator( elemType );
5494 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5496 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5499 elemIt = sm->GetElements();
5500 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5502 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5503 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5507 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5509 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5510 if ( groupDS && ( elemType == groupDS->GetType() ||
5511 elemType == SMDSAbs_Node ||
5512 elemType == SMDSAbs_All ))
5514 elemIt = groupDS->GetElements();
5515 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5518 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5520 if ( filter_i->GetElementType() == theType ||
5521 elemType == SMDSAbs_Node ||
5522 elemType == SMDSAbs_All)
5524 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5525 if ( pred_i && pred_i->GetPredicate() )
5527 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5528 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5529 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5530 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5536 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5537 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5538 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5540 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5543 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5544 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5548 SMESH::long_array_var ids = theObject->GetIDs();
5549 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5551 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5554 if ( elemIt && elemIt->more() && !typeOK )
5556 if ( elemType == SMDSAbs_Node )
5558 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5562 elemIt = SMDS_ElemIteratorPtr();
5568 //=============================================================================
5569 namespace // Finding concurrent hypotheses
5570 //=============================================================================
5574 * \brief mapping of mesh dimension into shape type
5576 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5578 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5580 case 0: aType = TopAbs_VERTEX; break;
5581 case 1: aType = TopAbs_EDGE; break;
5582 case 2: aType = TopAbs_FACE; break;
5584 default:aType = TopAbs_SOLID; break;
5589 //-----------------------------------------------------------------------------
5591 * \brief Internal structure used to find concurent submeshes
5593 * It represents a pair < submesh, concurent dimension >, where
5594 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5595 * with another submesh. In other words, it is dimension of a hypothesis assigned
5602 int _dim; //!< a dimension the algo can build (concurrent dimension)
5603 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5604 TopTools_MapOfShape _shapeMap;
5605 SMESH_subMesh* _subMesh;
5606 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5608 //-----------------------------------------------------------------------------
5609 // Return the algorithm
5610 const SMESH_Algo* GetAlgo() const
5611 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5613 //-----------------------------------------------------------------------------
5615 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5617 const TopoDS_Shape& theShape)
5619 _subMesh = (SMESH_subMesh*)theSubMesh;
5620 SetShape( theDim, theShape );
5623 //-----------------------------------------------------------------------------
5625 void SetShape(const int theDim,
5626 const TopoDS_Shape& theShape)
5629 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5630 if (_dim >= _ownDim)
5631 _shapeMap.Add( theShape );
5633 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5634 for( ; anExp.More(); anExp.Next() )
5635 _shapeMap.Add( anExp.Current() );
5639 //-----------------------------------------------------------------------------
5640 //! Check sharing of sub-shapes
5641 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5642 const TopTools_MapOfShape& theToFind,
5643 const TopAbs_ShapeEnum theType)
5645 bool isShared = false;
5646 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5647 for (; !isShared && anItr.More(); anItr.Next() )
5649 const TopoDS_Shape aSubSh = anItr.Key();
5650 // check for case when concurrent dimensions are same
5651 isShared = theToFind.Contains( aSubSh );
5652 // check for sub-shape with concurrent dimension
5653 TopExp_Explorer anExp( aSubSh, theType );
5654 for ( ; !isShared && anExp.More(); anExp.Next() )
5655 isShared = theToFind.Contains( anExp.Current() );
5660 //-----------------------------------------------------------------------------
5661 //! check algorithms
5662 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5663 const SMESHDS_Hypothesis* theA2)
5665 if ( !theA1 || !theA2 ||
5666 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5667 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5668 return false; // one of the hypothesis is not algorithm
5669 // check algorithm names (should be equal)
5670 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5674 //-----------------------------------------------------------------------------
5675 //! Check if sub-shape hypotheses are concurrent
5676 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5678 if ( _subMesh == theOther->_subMesh )
5679 return false; // same sub-shape - should not be
5681 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5682 // any of the two submeshes is not on COMPOUND shape )
5683 // -> no concurrency
5684 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5685 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5686 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5687 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5688 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5691 // bool checkSubShape = ( _dim >= theOther->_dim )
5692 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5693 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5694 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5695 if ( !checkSubShape )
5698 // check algorithms to be same
5699 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5700 return true; // different algorithms -> concurrency !
5702 // check hypothesises for concurrence (skip first as algorithm)
5704 // pointers should be same, because it is referened from mesh hypothesis partition
5705 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5706 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5707 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5708 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5710 // the submeshes are concurrent if their algorithms has different parameters
5711 return nbSame != (int)theOther->_hypotheses.size() - 1;
5714 // Return true if algorithm of this SMESH_DimHyp is used if no
5715 // sub-mesh order is imposed by the user
5716 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5718 // NeedDiscreteBoundary() algo has a higher priority
5719 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5720 theOther->GetAlgo()->NeedDiscreteBoundary() )
5721 return !this->GetAlgo()->NeedDiscreteBoundary();
5723 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5726 }; // end of SMESH_DimHyp
5727 //-----------------------------------------------------------------------------
5729 typedef list<const SMESH_DimHyp*> TDimHypList;
5731 //-----------------------------------------------------------------------------
5733 void addDimHypInstance(const int theDim,
5734 const TopoDS_Shape& theShape,
5735 const SMESH_Algo* theAlgo,
5736 const SMESH_subMesh* theSubMesh,
5737 const list <const SMESHDS_Hypothesis*>& theHypList,
5738 TDimHypList* theDimHypListArr )
5740 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5741 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5742 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5743 dimHyp->_hypotheses.push_front(theAlgo);
5744 listOfdimHyp.push_back( dimHyp );
5747 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5748 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5749 theHypList.begin(), theHypList.end() );
5752 //-----------------------------------------------------------------------------
5753 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5754 TDimHypList& theListOfConcurr)
5756 if ( theListOfConcurr.empty() )
5758 theListOfConcurr.push_back( theDimHyp );
5762 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5763 while ( hypIt != theListOfConcurr.end() &&
5764 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5766 theListOfConcurr.insert( hypIt, theDimHyp );
5770 //-----------------------------------------------------------------------------
5771 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5772 const TDimHypList& theListOfDimHyp,
5773 TDimHypList& theListOfConcurrHyp,
5774 set<int>& theSetOfConcurrId )
5776 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5777 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5779 const SMESH_DimHyp* curDimHyp = *rIt;
5780 if ( curDimHyp == theDimHyp )
5781 break; // meet own dimHyp pointer in same dimension
5783 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5784 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5786 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5791 //-----------------------------------------------------------------------------
5792 void unionLists(TListOfInt& theListOfId,
5793 TListOfListOfInt& theListOfListOfId,
5796 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5797 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5799 continue; //skip already treated lists
5800 // check if other list has any same submesh object
5801 TListOfInt& otherListOfId = *it;
5802 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5803 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5806 // union two lists (from source into target)
5807 TListOfInt::iterator it2 = otherListOfId.begin();
5808 for ( ; it2 != otherListOfId.end(); it2++ ) {
5809 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5810 theListOfId.push_back(*it2);
5812 // clear source list
5813 otherListOfId.clear();
5816 //-----------------------------------------------------------------------------
5818 //! free memory allocated for dimension-hypothesis objects
5819 void removeDimHyps( TDimHypList* theArrOfList )
5821 for (int i = 0; i < 4; i++ ) {
5822 TDimHypList& listOfdimHyp = theArrOfList[i];
5823 TDimHypList::const_iterator it = listOfdimHyp.begin();
5824 for ( ; it != listOfdimHyp.end(); it++ )
5829 //-----------------------------------------------------------------------------
5831 * \brief find common submeshes with given submesh
5832 * \param theSubMeshList list of already collected submesh to check
5833 * \param theSubMesh given submesh to intersect with other
5834 * \param theCommonSubMeshes collected common submeshes
5836 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5837 const SMESH_subMesh* theSubMesh,
5838 set<const SMESH_subMesh*>& theCommon )
5842 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5843 for ( ; it != theSubMeshList.end(); it++ )
5844 theSubMesh->FindIntersection( *it, theCommon );
5845 theSubMeshList.push_back( theSubMesh );
5846 //theCommon.insert( theSubMesh );
5849 //-----------------------------------------------------------------------------
5850 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5852 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5853 for ( ; listsIt != smLists.end(); ++listsIt )
5855 const TListOfInt& smIDs = *listsIt;
5856 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5864 //=============================================================================
5866 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5868 //=============================================================================
5870 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5872 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5873 if ( isSubMeshInList( submeshID, anOrder ))
5876 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5877 return isSubMeshInList( submeshID, allConurrent );
5880 //=============================================================================
5882 * \brief Return submesh objects list in meshing order
5884 //=============================================================================
5886 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5888 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5890 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5892 return aResult._retn();
5894 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5895 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5896 anOrder.splice( anOrder.end(), allConurrent );
5899 TListOfListOfInt::iterator listIt = anOrder.begin();
5900 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5901 unionLists( *listIt, anOrder, listIndx + 1 );
5903 // convert submesh ids into interface instances
5904 // and dump command into python
5905 convertMeshOrder( anOrder, aResult, false );
5907 return aResult._retn();
5910 //=============================================================================
5912 * \brief Finds concurrent sub-meshes
5914 //=============================================================================
5916 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5918 TListOfListOfInt anOrder;
5919 ::SMESH_Mesh& mesh = GetImpl();
5921 // collect submeshes and detect concurrent algorithms and hypothesises
5922 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5924 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5925 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5926 ::SMESH_subMesh* sm = (*i_sm).second;
5928 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5930 // list of assigned hypothesises
5931 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5932 // Find out dimensions where the submesh can be concurrent.
5933 // We define the dimensions by algo of each of hypotheses in hypList
5934 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5935 for( ; hypIt != hypList.end(); hypIt++ ) {
5936 SMESH_Algo* anAlgo = 0;
5937 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5938 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5939 // hyp it-self is algo
5940 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5942 // try to find algorithm with help of sub-shapes
5943 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5944 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5945 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5948 continue; // no algorithm assigned to a current submesh
5950 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5951 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5953 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5954 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5955 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5957 } // end iterations on submesh
5959 // iterate on created dimension-hypotheses and check for concurrents
5960 for ( int i = 0; i < 4; i++ ) {
5961 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5962 // check for concurrents in own and other dimensions (step-by-step)
5963 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5964 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5965 const SMESH_DimHyp* dimHyp = *dhIt;
5966 TDimHypList listOfConcurr;
5967 set<int> setOfConcurrIds;
5968 // looking for concurrents and collect into own list
5969 for ( int j = i; j < 4; j++ )
5970 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5971 // check if any concurrents found
5972 if ( listOfConcurr.size() > 0 ) {
5973 // add own submesh to list of concurrent
5974 addInOrderOfPriority( dimHyp, listOfConcurr );
5975 list<int> listOfConcurrIds;
5976 TDimHypList::iterator hypIt = listOfConcurr.begin();
5977 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5978 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5979 anOrder.push_back( listOfConcurrIds );
5984 removeDimHyps(dimHypListArr);
5986 // now, minimise the number of concurrent groups
5987 // Here we assume that lists of submeshes can have same submesh
5988 // in case of multi-dimension algorithms, as result
5989 // list with common submesh has to be united into one list
5991 TListOfListOfInt::iterator listIt = anOrder.begin();
5992 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5993 unionLists( *listIt, anOrder, listIndx + 1 );
5999 //=============================================================================
6001 * \brief Set submesh object order
6002 * \param theSubMeshArray submesh array order
6004 //=============================================================================
6006 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6009 _preMeshInfo->ForgetOrLoad();
6012 ::SMESH_Mesh& mesh = GetImpl();
6014 TPythonDump aPythonDump; // prevent dump of called methods
6015 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6017 TListOfListOfInt subMeshOrder;
6018 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6020 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6021 TListOfInt subMeshIds;
6023 aPythonDump << ", ";
6024 aPythonDump << "[ ";
6025 // Collect subMeshes which should be clear
6026 // do it list-by-list, because modification of submesh order
6027 // take effect between concurrent submeshes only
6028 set<const SMESH_subMesh*> subMeshToClear;
6029 list<const SMESH_subMesh*> subMeshList;
6030 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6032 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6034 aPythonDump << ", ";
6035 aPythonDump << subMesh;
6036 subMeshIds.push_back( subMesh->GetId() );
6037 // detect common parts of submeshes
6038 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6039 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6041 aPythonDump << " ]";
6042 subMeshOrder.push_back( subMeshIds );
6044 // clear collected submeshes
6045 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6046 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6047 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6048 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6050 aPythonDump << " ])";
6052 mesh.SetMeshOrder( subMeshOrder );
6058 //=============================================================================
6060 * \brief Convert submesh ids into submesh interfaces
6062 //=============================================================================
6064 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6065 SMESH::submesh_array_array& theResOrder,
6066 const bool theIsDump)
6068 int nbSet = theIdsOrder.size();
6069 TPythonDump aPythonDump; // prevent dump of called methods
6071 aPythonDump << "[ ";
6072 theResOrder.length(nbSet);
6073 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6075 for( ; it != theIdsOrder.end(); it++ ) {
6076 // translate submesh identificators into submesh objects
6077 // takeing into account real number of concurrent lists
6078 const TListOfInt& aSubOrder = (*it);
6079 if (!aSubOrder.size())
6082 aPythonDump << "[ ";
6083 // convert shape indeces into interfaces
6084 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6085 aResSubSet->length(aSubOrder.size());
6086 TListOfInt::const_iterator subIt = aSubOrder.begin();
6088 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6089 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6091 SMESH::SMESH_subMesh_var subMesh =
6092 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6095 aPythonDump << ", ";
6096 aPythonDump << subMesh;
6098 aResSubSet[ j++ ] = subMesh;
6101 aPythonDump << " ]";
6103 theResOrder[ listIndx++ ] = aResSubSet;
6105 // correct number of lists
6106 theResOrder.length( listIndx );
6109 // finilise python dump
6110 aPythonDump << " ]";
6111 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6115 //================================================================================
6117 // Implementation of SMESH_MeshPartDS
6119 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6120 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6122 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6123 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6125 _meshDS = mesh_i->GetImpl().GetMeshDS();
6127 SetPersistentId( _meshDS->GetPersistentId() );
6129 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6131 // <meshPart> is the whole mesh
6132 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6134 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6135 myGroupSet = _meshDS->GetGroups();
6140 SMESH::long_array_var anIDs = meshPart->GetIDs();
6141 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6142 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6144 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6145 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6146 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6151 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6152 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6153 if ( _elements[ e->GetType() ].insert( e ).second )
6156 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6157 while ( nIt->more() )
6159 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6160 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6167 ShapeToMesh( _meshDS->ShapeToMesh() );
6169 _meshDS = 0; // to enforce iteration on _elements and _nodes
6172 // -------------------------------------------------------------------------------------
6173 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6174 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6177 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6178 for ( ; partIt != meshPart.end(); ++partIt )
6179 if ( const SMDS_MeshElement * e = *partIt )
6180 if ( _elements[ e->GetType() ].insert( e ).second )
6183 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6184 while ( nIt->more() )
6186 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6187 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6193 // -------------------------------------------------------------------------------------
6194 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6196 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6198 typedef SMDS_SetIterator
6199 <const SMDS_MeshElement*,
6200 TIDSortedElemSet::const_iterator,
6201 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6202 SMDS_MeshElement::GeomFilter
6205 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6207 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6208 _elements[type].end(),
6209 SMDS_MeshElement::GeomFilter( geomType )));
6211 // -------------------------------------------------------------------------------------
6212 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6214 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6216 typedef SMDS_SetIterator
6217 <const SMDS_MeshElement*,
6218 TIDSortedElemSet::const_iterator,
6219 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6220 SMDS_MeshElement::EntityFilter
6223 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6225 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6226 _elements[type].end(),
6227 SMDS_MeshElement::EntityFilter( entity )));
6229 // -------------------------------------------------------------------------------------
6230 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6232 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6233 if ( type == SMDSAbs_All && !_meshDS )
6235 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6237 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6238 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6240 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6242 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6243 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6245 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6246 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6248 // -------------------------------------------------------------------------------------
6249 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6250 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6252 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6253 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6254 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6256 // -------------------------------------------------------------------------------------
6257 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6258 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6259 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6260 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6261 #undef _GET_ITER_DEFINE
6263 // END Implementation of SMESH_MeshPartDS
6265 //================================================================================