1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
113 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cashed shapes if no more meshes remain; (the cash is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
243 if ( study->_is_nil() ) break;
244 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Return false if the mesh is not yet fully loaded from the study file
262 //================================================================================
264 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
267 return !_preMeshInfo;
270 //================================================================================
272 * \brief Load full mesh data from the study file
274 //================================================================================
276 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
278 Unexpect aCatch(SALOME_SalomeException);
280 _preMeshInfo->FullLoadFromFile();
283 //================================================================================
285 * \brief Remove all nodes and elements
287 //================================================================================
289 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
291 Unexpect aCatch(SALOME_SalomeException);
293 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
297 //CheckGeomGroupModif(); // issue 20145
299 catch(SALOME_Exception & S_ex) {
300 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
303 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
306 //================================================================================
308 * \brief Remove all nodes and elements for indicated shape
310 //================================================================================
312 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
313 throw (SALOME::SALOME_Exception)
315 Unexpect aCatch(SALOME_SalomeException);
317 _preMeshInfo->FullLoadFromFile();
320 _impl->ClearSubMesh( ShapeID );
322 catch(SALOME_Exception & S_ex) {
323 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
325 _impl->GetMeshDS()->Modified();
327 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
330 //=============================================================================
332 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
334 //=============================================================================
336 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
338 SMESH::DriverMED_ReadStatus res;
341 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
342 res = SMESH::DRS_OK; break;
343 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
344 res = SMESH::DRS_EMPTY; break;
345 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
346 res = SMESH::DRS_WARN_RENUMBER; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
348 res = SMESH::DRS_WARN_SKIP_ELEM; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
350 res = SMESH::DRS_WARN_DESCENDING; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
353 res = SMESH::DRS_FAIL; break;
358 //=============================================================================
360 * Convert ::SMESH_ComputeError to SMESH::ComputeError
362 //=============================================================================
364 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
366 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
367 errVar->subShapeID = -1;
368 errVar->hasBadMesh = false;
370 if ( !errorPtr || errorPtr->IsOK() )
372 errVar->code = SMESH::COMPERR_OK;
376 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
377 errVar->comment = errorPtr->myComment.c_str();
379 return errVar._retn();
382 //=============================================================================
386 * Imports mesh data from MED file
388 //=============================================================================
390 SMESH::DriverMED_ReadStatus
391 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
392 throw ( SALOME::SALOME_Exception )
394 Unexpect aCatch(SALOME_SalomeException);
397 status = _impl->MEDToMesh( theFileName, theMeshName );
399 catch( SALOME_Exception& S_ex ) {
400 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
403 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
406 CreateGroupServants();
408 int major, minor, release;
409 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
410 major = minor = release = -1;
411 _medFileInfo = new SMESH::MedFileInfo();
412 _medFileInfo->fileName = theFileName;
413 _medFileInfo->fileSize = 0;
414 _medFileInfo->major = major;
415 _medFileInfo->minor = minor;
416 _medFileInfo->release = release;
417 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
419 return ConvertDriverMEDReadStatus(status);
422 //================================================================================
424 * \brief Imports mesh data from the CGNS file
426 //================================================================================
428 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
429 const int theMeshIndex,
430 std::string& theMeshName )
431 throw ( SALOME::SALOME_Exception )
433 Unexpect aCatch(SALOME_SalomeException);
436 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
438 catch( SALOME_Exception& S_ex ) {
439 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
442 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
445 CreateGroupServants();
447 return ConvertDriverMEDReadStatus(status);
450 //================================================================================
452 * \brief Return string representation of a MED file version comprising nbDigits
454 //================================================================================
456 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
458 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
460 return CORBA::string_dup( ver.c_str() );
463 //=============================================================================
467 * Imports mesh data from MED file
469 //=============================================================================
471 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
472 throw ( SALOME::SALOME_Exception )
476 // Read mesh with name = <theMeshName> into SMESH_Mesh
477 _impl->UNVToMesh( theFileName );
479 CreateGroupServants();
481 SMESH_CATCH( SMESH::throwCorbaException );
486 //=============================================================================
490 * Imports mesh data from STL file
492 //=============================================================================
493 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
494 throw ( SALOME::SALOME_Exception )
498 // Read mesh with name = <theMeshName> into SMESH_Mesh
499 std::string name = _impl->STLToMesh( theFileName );
502 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
503 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( study, _this() );
504 _gen_i->SetName( meshSO, name.c_str() );
507 SMESH_CATCH( SMESH::throwCorbaException );
512 //================================================================================
514 * \brief Function used in SMESH_CATCH by ImportGMFFile()
516 //================================================================================
520 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
522 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
526 //================================================================================
528 * \brief Imports data from a GMF file and returns an error description
530 //================================================================================
532 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
533 bool theMakeRequiredGroups )
534 throw (SALOME::SALOME_Exception)
536 SMESH_ComputeErrorPtr error;
539 #define SMESH_CAUGHT error =
542 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
544 SMESH_CATCH( exceptionToComputeError );
548 CreateGroupServants();
550 return ConvertComputeError( error );
553 //=============================================================================
557 //=============================================================================
559 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
561 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
562 (SMESH_Hypothesis::Hypothesis_Status theStatus)
565 RETURNCASE( HYP_OK );
566 RETURNCASE( HYP_MISSING );
567 RETURNCASE( HYP_CONCURENT );
568 RETURNCASE( HYP_BAD_PARAMETER );
569 RETURNCASE( HYP_HIDDEN_ALGO );
570 RETURNCASE( HYP_HIDING_ALGO );
571 RETURNCASE( HYP_UNKNOWN_FATAL );
572 RETURNCASE( HYP_INCOMPATIBLE );
573 RETURNCASE( HYP_NOTCONFORM );
574 RETURNCASE( HYP_ALREADY_EXIST );
575 RETURNCASE( HYP_BAD_DIM );
576 RETURNCASE( HYP_BAD_SUBSHAPE );
577 RETURNCASE( HYP_BAD_GEOMETRY );
578 RETURNCASE( HYP_NEED_SHAPE );
579 RETURNCASE( HYP_INCOMPAT_HYPS );
582 return SMESH::HYP_UNKNOWN_FATAL;
585 //=============================================================================
589 * calls internal addHypothesis() and then adds a reference to <anHyp> under
590 * the SObject actually having a reference to <aSubShape>.
591 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
593 //=============================================================================
595 SMESH::Hypothesis_Status
596 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
597 SMESH::SMESH_Hypothesis_ptr anHyp,
598 CORBA::String_out anErrorText)
599 throw(SALOME::SALOME_Exception)
601 Unexpect aCatch(SALOME_SalomeException);
603 _preMeshInfo->ForgetOrLoad();
606 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
607 anErrorText = error.c_str();
609 SMESH::SMESH_Mesh_var mesh( _this() );
610 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
612 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
613 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
615 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
617 // Update Python script
618 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
619 << aSubShape << ", " << anHyp << " )";
621 return ConvertHypothesisStatus(status);
624 //=============================================================================
628 //=============================================================================
630 SMESH_Hypothesis::Hypothesis_Status
631 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
632 SMESH::SMESH_Hypothesis_ptr anHyp,
633 std::string* anErrorText)
635 if(MYDEBUG) MESSAGE("addHypothesis");
637 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
638 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
640 if (CORBA::is_nil( anHyp ))
641 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
643 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
646 TopoDS_Shape myLocSubShape;
647 //use PseudoShape in case if mesh has no shape
649 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
651 myLocSubShape = _impl->GetShapeToMesh();
653 const int hypId = anHyp->GetId();
655 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
656 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
658 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
660 // assure there is a corresponding submesh
661 if ( !_impl->IsMainShape( myLocSubShape )) {
662 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
663 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
664 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
667 else if ( anErrorText )
669 *anErrorText = error;
672 catch(SALOME_Exception & S_ex)
674 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
679 //=============================================================================
683 //=============================================================================
685 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
686 SMESH::SMESH_Hypothesis_ptr anHyp)
687 throw(SALOME::SALOME_Exception)
689 Unexpect aCatch(SALOME_SalomeException);
691 _preMeshInfo->ForgetOrLoad();
693 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
694 SMESH::SMESH_Mesh_var mesh = _this();
696 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
698 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
699 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
701 // Update Python script
702 if(_impl->HasShapeToMesh())
703 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
704 << aSubShape << ", " << anHyp << " )";
706 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
709 return ConvertHypothesisStatus(status);
712 //=============================================================================
716 //=============================================================================
718 SMESH_Hypothesis::Hypothesis_Status
719 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
720 SMESH::SMESH_Hypothesis_ptr anHyp)
722 if(MYDEBUG) MESSAGE("removeHypothesis()");
724 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
725 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
727 if (CORBA::is_nil( anHyp ))
728 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
730 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
733 TopoDS_Shape myLocSubShape;
734 //use PseudoShape in case if mesh has no shape
735 if( _impl->HasShapeToMesh() )
736 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
738 myLocSubShape = _impl->GetShapeToMesh();
740 const int hypId = anHyp->GetId();
741 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
742 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
744 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
748 catch(SALOME_Exception & S_ex)
750 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
755 //=============================================================================
759 //=============================================================================
761 SMESH::ListOfHypothesis *
762 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
763 throw(SALOME::SALOME_Exception)
765 Unexpect aCatch(SALOME_SalomeException);
766 if (MYDEBUG) MESSAGE("GetHypothesisList");
767 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
768 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
770 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
773 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
774 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
775 myLocSubShape = _impl->GetShapeToMesh();
776 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
777 int i = 0, n = aLocalList.size();
780 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
781 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
782 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
784 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
785 if ( id_hypptr != _mapHypo.end() )
786 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
790 catch(SALOME_Exception & S_ex) {
791 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
794 return aList._retn();
797 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
799 Unexpect aCatch(SALOME_SalomeException);
800 if (MYDEBUG) MESSAGE("GetSubMeshes");
802 SMESH::submesh_array_var aList = new SMESH::submesh_array();
805 TPythonDump aPythonDump;
806 if ( !_mapSubMeshIor.empty() )
810 aList->length( _mapSubMeshIor.size() );
812 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
813 for ( ; it != _mapSubMeshIor.end(); it++ ) {
814 if ( CORBA::is_nil( it->second )) continue;
815 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
817 if (i > 1) aPythonDump << ", ";
818 aPythonDump << it->second;
822 catch(SALOME_Exception & S_ex) {
823 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
826 // Update Python script
827 if ( !_mapSubMeshIor.empty() )
828 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
830 return aList._retn();
833 //=============================================================================
837 //=============================================================================
839 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
840 const char* theName )
841 throw(SALOME::SALOME_Exception)
843 Unexpect aCatch(SALOME_SalomeException);
844 if (CORBA::is_nil(aSubShape))
845 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
847 SMESH::SMESH_subMesh_var subMesh;
848 SMESH::SMESH_Mesh_var aMesh = _this();
850 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
852 //Get or Create the SMESH_subMesh object implementation
854 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
856 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
858 TopoDS_Iterator it( myLocSubShape );
860 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
862 subMesh = getSubMesh( subMeshId );
864 // create a new subMesh object servant if there is none for the shape
865 if ( subMesh->_is_nil() )
866 subMesh = createSubMesh( aSubShape );
867 if ( _gen_i->CanPublishInStudy( subMesh ))
869 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
870 SALOMEDS::SObject_wrap aSO =
871 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
872 if ( !aSO->_is_nil()) {
873 // Update Python script
874 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
875 << aSubShape << ", '" << theName << "' )";
879 catch(SALOME_Exception & S_ex) {
880 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
882 return subMesh._retn();
885 //=============================================================================
889 //=============================================================================
891 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
892 throw (SALOME::SALOME_Exception)
896 if ( theSubMesh->_is_nil() )
899 GEOM::GEOM_Object_var aSubShape;
900 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
901 if ( !aStudy->_is_nil() ) {
902 // Remove submesh's SObject
903 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
904 if ( !anSO->_is_nil() ) {
905 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
906 SALOMEDS::SObject_wrap anObj, aRef;
907 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
908 anObj->ReferencedObject( aRef.inout() ))
910 CORBA::Object_var obj = aRef->GetObject();
911 aSubShape = GEOM::GEOM_Object::_narrow( obj );
913 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
914 // aSubShape = theSubMesh->GetSubShape();
916 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
917 builder->RemoveObjectWithChildren( anSO );
919 // Update Python script
920 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
924 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
926 _preMeshInfo->ForgetOrLoad();
928 SMESH_CATCH( SMESH::throwCorbaException );
931 //=============================================================================
935 //=============================================================================
937 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
938 const char* theName )
939 throw(SALOME::SALOME_Exception)
941 Unexpect aCatch(SALOME_SalomeException);
943 _preMeshInfo->FullLoadFromFile();
945 SMESH::SMESH_Group_var aNewGroup =
946 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
948 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
950 SMESH::SMESH_Mesh_var mesh = _this();
951 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
952 SALOMEDS::SObject_wrap aSO =
953 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
954 if ( !aSO->_is_nil())
955 // Update Python script
956 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
957 << theElemType << ", '" << theName << "' )";
959 return aNewGroup._retn();
962 //=============================================================================
966 //=============================================================================
967 SMESH::SMESH_GroupOnGeom_ptr
968 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
970 GEOM::GEOM_Object_ptr theGeomObj)
971 throw(SALOME::SALOME_Exception)
973 Unexpect aCatch(SALOME_SalomeException);
975 _preMeshInfo->FullLoadFromFile();
977 SMESH::SMESH_GroupOnGeom_var aNewGroup;
979 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
980 if ( !aShape.IsNull() )
983 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
985 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
987 SMESH::SMESH_Mesh_var mesh = _this();
988 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
989 SALOMEDS::SObject_wrap aSO =
990 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
991 if ( !aSO->_is_nil())
992 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
993 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
997 return aNewGroup._retn();
1000 //================================================================================
1002 * \brief Creates a group whose contents is defined by filter
1003 * \param theElemType - group type
1004 * \param theName - group name
1005 * \param theFilter - the filter
1006 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1008 //================================================================================
1010 SMESH::SMESH_GroupOnFilter_ptr
1011 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1012 const char* theName,
1013 SMESH::Filter_ptr theFilter )
1014 throw (SALOME::SALOME_Exception)
1016 Unexpect aCatch(SALOME_SalomeException);
1018 _preMeshInfo->FullLoadFromFile();
1020 if ( CORBA::is_nil( theFilter ))
1021 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1023 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1025 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1027 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1028 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1031 if ( !aNewGroup->_is_nil() )
1032 aNewGroup->SetFilter( theFilter );
1034 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1036 SMESH::SMESH_Mesh_var mesh = _this();
1037 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1038 SALOMEDS::SObject_wrap aSO =
1039 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1041 if ( !aSO->_is_nil())
1042 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1043 << theElemType << ", '" << theName << "', " << theFilter << " )";
1045 return aNewGroup._retn();
1048 //=============================================================================
1052 //=============================================================================
1054 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1055 throw (SALOME::SALOME_Exception)
1057 if ( theGroup->_is_nil() )
1062 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1066 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1067 if ( !aStudy->_is_nil() )
1069 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1070 if ( !aGroupSO->_is_nil() )
1072 // Update Python script
1073 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1075 // Remove group's SObject
1076 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1077 builder->RemoveObjectWithChildren( aGroupSO );
1080 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1082 // Remove the group from SMESH data structures
1083 removeGroup( aGroup->GetLocalID() );
1085 SMESH_CATCH( SMESH::throwCorbaException );
1088 //=============================================================================
1090 * Remove group with its contents
1092 //=============================================================================
1094 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1095 throw (SALOME::SALOME_Exception)
1099 _preMeshInfo->FullLoadFromFile();
1101 if ( theGroup->_is_nil() )
1104 vector<int> nodeIds; // to remove nodes becoming free
1105 if ( !theGroup->IsEmpty() )
1107 CORBA::Long elemID = theGroup->GetID( 1 );
1108 int nbElemNodes = GetElemNbNodes( elemID );
1109 if ( nbElemNodes > 0 )
1110 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1114 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1115 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1116 while ( elemIt->more() )
1118 const SMDS_MeshElement* e = elemIt->next();
1120 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1121 while ( nIt->more() )
1122 nodeIds.push_back( nIt->next()->GetID() );
1124 _impl->GetMeshDS()->RemoveElement( e );
1127 // Remove free nodes
1128 if ( theGroup->GetType() != SMESH::NODE )
1129 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1130 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1131 if ( n->NbInverseElements() == 0 )
1132 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1134 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1136 // Update Python script (theGroup must be alive for this)
1137 pyDump << SMESH::SMESH_Mesh_var(_this())
1138 << ".RemoveGroupWithContents( " << theGroup << " )";
1141 RemoveGroup( theGroup );
1143 SMESH_CATCH( SMESH::throwCorbaException );
1146 //================================================================================
1148 * \brief Get the list of groups existing in the mesh
1149 * \retval SMESH::ListOfGroups * - list of groups
1151 //================================================================================
1153 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1155 Unexpect aCatch(SALOME_SalomeException);
1156 if (MYDEBUG) MESSAGE("GetGroups");
1158 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1161 TPythonDump aPythonDump;
1162 if ( !_mapGroups.empty() )
1164 aPythonDump << "[ ";
1166 aList->length( _mapGroups.size() );
1168 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1169 for ( ; it != _mapGroups.end(); it++ ) {
1170 if ( CORBA::is_nil( it->second )) continue;
1171 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1173 if (i > 1) aPythonDump << ", ";
1174 aPythonDump << it->second;
1178 catch(SALOME_Exception & S_ex) {
1179 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1181 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1183 return aList._retn();
1186 //=============================================================================
1188 * Get number of groups existing in the mesh
1190 //=============================================================================
1192 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1194 Unexpect aCatch(SALOME_SalomeException);
1195 return _mapGroups.size();
1198 //=============================================================================
1200 * New group including all mesh elements present in initial groups is created.
1202 //=============================================================================
1204 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1205 SMESH::SMESH_GroupBase_ptr theGroup2,
1206 const char* theName )
1207 throw (SALOME::SALOME_Exception)
1209 SMESH::SMESH_Group_var aResGrp;
1213 _preMeshInfo->FullLoadFromFile();
1215 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1216 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1218 if ( theGroup1->GetType() != theGroup2->GetType() )
1219 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1224 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1225 if ( aResGrp->_is_nil() )
1226 return SMESH::SMESH_Group::_nil();
1228 aResGrp->AddFrom( theGroup1 );
1229 aResGrp->AddFrom( theGroup2 );
1231 // Update Python script
1232 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1233 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1235 SMESH_CATCH( SMESH::throwCorbaException );
1237 return aResGrp._retn();
1240 //=============================================================================
1242 * \brief New group including all mesh elements present in initial groups is created.
1243 * \param theGroups list of groups
1244 * \param theName name of group to be created
1245 * \return pointer to the new group
1247 //=============================================================================
1249 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1250 const char* theName )
1251 throw (SALOME::SALOME_Exception)
1253 SMESH::SMESH_Group_var aResGrp;
1256 _preMeshInfo->FullLoadFromFile();
1259 return SMESH::SMESH_Group::_nil();
1264 SMESH::ElementType aType = SMESH::ALL;
1265 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1267 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1268 if ( CORBA::is_nil( aGrp ) )
1270 if ( aType == SMESH::ALL )
1271 aType = aGrp->GetType();
1272 else if ( aType != aGrp->GetType() )
1273 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1276 if ( aType == SMESH::ALL )
1277 return SMESH::SMESH_Group::_nil();
1282 aResGrp = CreateGroup( aType, theName );
1283 if ( aResGrp->_is_nil() )
1284 return SMESH::SMESH_Group::_nil();
1286 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1287 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1289 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1290 if ( !CORBA::is_nil( aGrp ) )
1292 aResGrp->AddFrom( aGrp );
1293 if ( g > 0 ) pyDump << ", ";
1297 pyDump << " ], '" << theName << "' )";
1299 SMESH_CATCH( SMESH::throwCorbaException );
1301 return aResGrp._retn();
1304 //=============================================================================
1306 * New group is created. All mesh elements that are
1307 * present in both initial groups are added to the new one.
1309 //=============================================================================
1311 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1312 SMESH::SMESH_GroupBase_ptr theGroup2,
1313 const char* theName )
1314 throw (SALOME::SALOME_Exception)
1316 SMESH::SMESH_Group_var aResGrp;
1321 _preMeshInfo->FullLoadFromFile();
1323 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1324 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1326 if ( theGroup1->GetType() != theGroup2->GetType() )
1327 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1331 // Create Intersection
1332 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1333 if ( aResGrp->_is_nil() )
1334 return aResGrp._retn();
1336 SMESHDS_GroupBase* groupDS1 = 0;
1337 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1338 groupDS1 = grp_i->GetGroupDS();
1340 SMESHDS_GroupBase* groupDS2 = 0;
1341 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1342 groupDS2 = grp_i->GetGroupDS();
1344 SMESHDS_Group* resGroupDS = 0;
1345 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1346 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1348 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1350 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1351 while ( elemIt1->more() )
1353 const SMDS_MeshElement* e = elemIt1->next();
1354 if ( groupDS2->Contains( e ))
1355 resGroupDS->SMDSGroup().Add( e );
1358 // Update Python script
1359 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1360 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1362 SMESH_CATCH( SMESH::throwCorbaException );
1364 return aResGrp._retn();
1367 //=============================================================================
1369 \brief Intersect list of groups. New group is created. All mesh elements that
1370 are present in all initial groups simultaneously are added to the new one.
1371 \param theGroups list of groups
1372 \param theName name of group to be created
1373 \return pointer on the group
1375 //=============================================================================
1376 SMESH::SMESH_Group_ptr
1377 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1378 const char* theName )
1379 throw (SALOME::SALOME_Exception)
1381 SMESH::SMESH_Group_var aResGrp;
1386 _preMeshInfo->FullLoadFromFile();
1389 return SMESH::SMESH_Group::_nil();
1391 // check types and get SMESHDS_GroupBase's
1392 SMESH::ElementType aType = SMESH::ALL;
1393 vector< SMESHDS_GroupBase* > groupVec;
1394 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1396 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1397 if ( CORBA::is_nil( aGrp ) )
1399 if ( aType == SMESH::ALL )
1400 aType = aGrp->GetType();
1401 else if ( aType != aGrp->GetType() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1405 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1406 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1408 if ( grpDS->IsEmpty() )
1413 groupVec.push_back( grpDS );
1416 if ( aType == SMESH::ALL ) // all groups are nil
1417 return SMESH::SMESH_Group::_nil();
1422 aResGrp = CreateGroup( aType, theName );
1424 SMESHDS_Group* resGroupDS = 0;
1425 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1426 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1427 if ( !resGroupDS || groupVec.empty() )
1428 return aResGrp._retn();
1431 size_t i, nb = groupVec.size();
1432 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1433 while ( elemIt1->more() )
1435 const SMDS_MeshElement* e = elemIt1->next();
1437 for ( i = 1; ( i < nb && inAll ); ++i )
1438 inAll = groupVec[i]->Contains( e );
1441 resGroupDS->SMDSGroup().Add( e );
1444 // Update Python script
1445 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1446 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1448 SMESH_CATCH( SMESH::throwCorbaException );
1450 return aResGrp._retn();
1453 //=============================================================================
1455 * New group is created. All mesh elements that are present in
1456 * a main group but is not present in a tool group are added to the new one
1458 //=============================================================================
1460 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1461 SMESH::SMESH_GroupBase_ptr theGroup2,
1462 const char* theName )
1463 throw (SALOME::SALOME_Exception)
1465 SMESH::SMESH_Group_var aResGrp;
1470 _preMeshInfo->FullLoadFromFile();
1472 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1473 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1475 if ( theGroup1->GetType() != theGroup2->GetType() )
1476 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1480 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1481 if ( aResGrp->_is_nil() )
1482 return aResGrp._retn();
1484 SMESHDS_GroupBase* groupDS1 = 0;
1485 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1486 groupDS1 = grp_i->GetGroupDS();
1488 SMESHDS_GroupBase* groupDS2 = 0;
1489 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1490 groupDS2 = grp_i->GetGroupDS();
1492 SMESHDS_Group* resGroupDS = 0;
1493 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1494 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1496 if ( groupDS1 && groupDS2 && resGroupDS )
1498 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1499 while ( elemIt1->more() )
1501 const SMDS_MeshElement* e = elemIt1->next();
1502 if ( !groupDS2->Contains( e ))
1503 resGroupDS->SMDSGroup().Add( e );
1506 // Update Python script
1507 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1508 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1510 SMESH_CATCH( SMESH::throwCorbaException );
1512 return aResGrp._retn();
1515 //=============================================================================
1517 \brief Cut lists of groups. New group is created. All mesh elements that are
1518 present in main groups but do not present in tool groups are added to the new one
1519 \param theMainGroups list of main groups
1520 \param theToolGroups list of tool groups
1521 \param theName name of group to be created
1522 \return pointer on the group
1524 //=============================================================================
1525 SMESH::SMESH_Group_ptr
1526 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1527 const SMESH::ListOfGroups& theToolGroups,
1528 const char* theName )
1529 throw (SALOME::SALOME_Exception)
1531 SMESH::SMESH_Group_var aResGrp;
1536 _preMeshInfo->FullLoadFromFile();
1539 return SMESH::SMESH_Group::_nil();
1541 // check types and get SMESHDS_GroupBase's
1542 SMESH::ElementType aType = SMESH::ALL;
1543 vector< SMESHDS_GroupBase* > toolGroupVec;
1544 vector< SMDS_ElemIteratorPtr > mainIterVec;
1546 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1548 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1549 if ( CORBA::is_nil( aGrp ) )
1551 if ( aType == SMESH::ALL )
1552 aType = aGrp->GetType();
1553 else if ( aType != aGrp->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1556 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1557 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1558 if ( !grpDS->IsEmpty() )
1559 mainIterVec.push_back( grpDS->GetElements() );
1561 if ( aType == SMESH::ALL ) // all main groups are nil
1562 return SMESH::SMESH_Group::_nil();
1563 if ( mainIterVec.empty() ) // all main groups are empty
1564 return aResGrp._retn();
1566 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1568 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1569 if ( CORBA::is_nil( aGrp ) )
1571 if ( aType != aGrp->GetType() )
1572 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1574 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1575 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1576 toolGroupVec.push_back( grpDS );
1582 aResGrp = CreateGroup( aType, theName );
1584 SMESHDS_Group* resGroupDS = 0;
1585 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1586 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1588 return aResGrp._retn();
1591 size_t i, nb = toolGroupVec.size();
1592 SMDS_ElemIteratorPtr mainElemIt
1593 ( new SMDS_IteratorOnIterators
1594 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1595 while ( mainElemIt->more() )
1597 const SMDS_MeshElement* e = mainElemIt->next();
1599 for ( i = 0; ( i < nb && !isIn ); ++i )
1600 isIn = toolGroupVec[i]->Contains( e );
1603 resGroupDS->SMDSGroup().Add( e );
1606 // Update Python script
1607 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1608 << ".CutListOfGroups( " << theMainGroups << ", "
1609 << theToolGroups << ", '" << theName << "' )";
1611 SMESH_CATCH( SMESH::throwCorbaException );
1613 return aResGrp._retn();
1616 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1618 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1619 bool & toStopChecking )
1621 toStopChecking = ( nbCommon < nbChecked );
1622 return nbCommon == nbNodes;
1624 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1625 bool & toStopChecking )
1627 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1628 return nbCommon == nbCorners;
1630 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1631 bool & toStopChecking )
1633 return nbCommon > 0;
1635 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1636 bool & toStopChecking )
1638 return nbCommon >= (nbNodes+1) / 2;
1642 //=============================================================================
1644 * Create a group of entities basing on nodes of other groups.
1645 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1646 * \param [in] anElemType - a type of elements to include to the new group.
1647 * \param [in] theName - a name of the new group.
1648 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1649 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1650 * new group provided that it is based on nodes of an element of \a aListOfGroups
1651 * \return SMESH_Group - the created group
1653 // IMP 19939, bug 22010, IMP 22635
1654 //=============================================================================
1656 SMESH::SMESH_Group_ptr
1657 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1658 SMESH::ElementType theElemType,
1659 const char* theName,
1660 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1661 CORBA::Boolean theUnderlyingOnly)
1662 throw (SALOME::SALOME_Exception)
1664 SMESH::SMESH_Group_var aResGrp;
1668 _preMeshInfo->FullLoadFromFile();
1670 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1672 if ( !theName || !aMeshDS )
1673 return SMESH::SMESH_Group::_nil();
1675 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1677 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1678 SMESH_Comment nbCoNoStr( "SMESH.");
1679 switch ( theNbCommonNodes ) {
1680 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1681 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1682 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1683 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1684 default: return aResGrp._retn();
1686 int nbChecked, nbCommon, nbNodes, nbCorners;
1692 aResGrp = CreateGroup( theElemType, theName );
1693 if ( aResGrp->_is_nil() )
1694 return SMESH::SMESH_Group::_nil();
1696 SMESHDS_GroupBase* groupBaseDS =
1697 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1698 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1700 vector<bool> isNodeInGroups;
1702 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1704 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1705 if ( CORBA::is_nil( aGrp ) )
1707 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1708 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1711 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1712 if ( !elIt ) continue;
1714 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1716 while ( elIt->more() ) {
1717 const SMDS_MeshElement* el = elIt->next();
1718 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1719 while ( nIt->more() )
1720 resGroupCore.Add( nIt->next() );
1723 // get elements of theElemType based on nodes of every element of group
1724 else if ( theUnderlyingOnly )
1726 while ( elIt->more() )
1728 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1729 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1730 TIDSortedElemSet checkedElems;
1731 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1732 while ( nIt->more() )
1734 const SMDS_MeshNode* n = nIt->next();
1735 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1736 // check nodes of elements of theElemType around el
1737 while ( elOfTypeIt->more() )
1739 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1740 if ( !checkedElems.insert( elOfType ).second ) continue;
1741 nbNodes = elOfType->NbNodes();
1742 nbCorners = elOfType->NbCornerNodes();
1744 bool toStopChecking = false;
1745 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1746 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1747 if ( elNodes.count( nIt2->next() ) &&
1748 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1750 resGroupCore.Add( elOfType );
1757 // get all nodes of elements of groups
1760 while ( elIt->more() )
1762 const SMDS_MeshElement* el = elIt->next(); // an element of group
1763 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1764 while ( nIt->more() )
1766 const SMDS_MeshNode* n = nIt->next();
1767 if ( n->GetID() >= (int) isNodeInGroups.size() )
1768 isNodeInGroups.resize( n->GetID() + 1, false );
1769 isNodeInGroups[ n->GetID() ] = true;
1775 // Get elements of theElemType based on a certain number of nodes of elements of groups
1776 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1778 const SMDS_MeshNode* n;
1779 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1780 const int isNodeInGroupsSize = isNodeInGroups.size();
1781 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1783 if ( !isNodeInGroups[ iN ] ||
1784 !( n = aMeshDS->FindNode( iN )))
1787 // check nodes of elements of theElemType around n
1788 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1789 while ( elOfTypeIt->more() )
1791 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1792 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1797 nbNodes = elOfType->NbNodes();
1798 nbCorners = elOfType->NbCornerNodes();
1800 bool toStopChecking = false;
1801 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1802 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1804 const int nID = nIt->next()->GetID();
1805 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1806 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1808 resGroupCore.Add( elOfType );
1816 // Update Python script
1817 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1818 << ".CreateDimGroup( "
1819 << theGroups << ", " << theElemType << ", '" << theName << "', "
1820 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1822 SMESH_CATCH( SMESH::throwCorbaException );
1824 return aResGrp._retn();
1827 //================================================================================
1829 * \brief Remember GEOM group data
1831 //================================================================================
1833 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1834 CORBA::Object_ptr theSmeshObj)
1836 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1839 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1840 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1841 if ( groupSO->_is_nil() )
1844 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1845 GEOM::GEOM_IGroupOperations_wrap groupOp =
1846 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1847 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1850 _geomGroupData.push_back( TGeomGroupData() );
1851 TGeomGroupData & groupData = _geomGroupData.back();
1853 CORBA::String_var entry = groupSO->GetID();
1854 groupData._groupEntry = entry.in();
1856 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1857 groupData._indices.insert( ids[i] );
1859 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1860 // shape index in SMESHDS
1861 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1862 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1865 //================================================================================
1867 * Remove GEOM group data relating to removed smesh object
1869 //================================================================================
1871 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1873 list<TGeomGroupData>::iterator
1874 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1875 for ( ; data != dataEnd; ++data ) {
1876 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1877 _geomGroupData.erase( data );
1883 //================================================================================
1885 * \brief Return new group contents if it has been changed and update group data
1887 //================================================================================
1889 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1891 TopoDS_Shape newShape;
1894 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1895 if ( study->_is_nil() ) return newShape; // means "not changed"
1896 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1897 if ( !groupSO->_is_nil() )
1899 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1900 if ( CORBA::is_nil( groupObj )) return newShape;
1901 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1903 // get indices of group items
1904 set<int> curIndices;
1905 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1906 GEOM::GEOM_IGroupOperations_wrap groupOp =
1907 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1908 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1909 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1910 curIndices.insert( ids[i] );
1912 if ( groupData._indices == curIndices )
1913 return newShape; // group not changed
1916 groupData._indices = curIndices;
1918 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1919 if ( !geomClient ) return newShape;
1920 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1921 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1922 newShape = _gen_i->GeomObjectToShape( geomGroup );
1925 if ( newShape.IsNull() ) {
1926 // geom group becomes empty - return empty compound
1927 TopoDS_Compound compound;
1928 BRep_Builder().MakeCompound(compound);
1929 newShape = compound;
1936 //-----------------------------------------------------------------------------
1938 * \brief Storage of shape and index used in CheckGeomGroupModif()
1940 struct TIndexedShape
1943 TopoDS_Shape _shape;
1944 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1946 //-----------------------------------------------------------------------------
1948 * \brief Data to re-create a group on geometry
1950 struct TGroupOnGeomData
1954 SMDSAbs_ElementType _type;
1956 Quantity_Color _color;
1960 //=============================================================================
1962 * \brief Update data if geometry changes
1966 //=============================================================================
1968 void SMESH_Mesh_i::CheckGeomModif()
1970 if ( !_impl->HasShapeToMesh() ) return;
1972 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1973 if ( study->_is_nil() ) return;
1975 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1976 //if ( mainGO->_is_nil() ) return;
1978 // Update after group modification
1980 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1981 called by other mesh (IPAL52735) */
1982 mainGO->GetType() == GEOM_GROUP ||
1983 mainGO->GetTick() == _mainShapeTick )
1985 CheckGeomGroupModif();
1989 // Update after shape transformation like Translate
1991 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1992 if ( !geomClient ) return;
1993 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1994 if ( geomGen->_is_nil() ) return;
1996 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1997 geomClient->RemoveShapeFromBuffer( ior.in() );
1999 // Update data taking into account that
2000 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2003 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2004 if ( newShape.IsNull() )
2007 _mainShapeTick = mainGO->GetTick();
2009 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2011 // store data of groups on geometry
2012 vector< TGroupOnGeomData > groupsData;
2013 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2014 groupsData.reserve( groups.size() );
2015 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2016 for ( ; g != groups.end(); ++g )
2017 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2019 TGroupOnGeomData data;
2020 data._oldID = group->GetID();
2021 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2022 data._type = group->GetType();
2023 data._name = group->GetStoreName();
2024 data._color = group->GetColor();
2025 groupsData.push_back( data );
2027 // store assigned hypotheses
2028 vector< pair< int, THypList > > ids2Hyps;
2029 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2030 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2032 const TopoDS_Shape& s = s2hyps.Key();
2033 const THypList& hyps = s2hyps.ChangeValue();
2034 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2037 // change shape to mesh
2038 int oldNbSubShapes = meshDS->MaxShapeIndex();
2039 _impl->ShapeToMesh( TopoDS_Shape() );
2040 _impl->ShapeToMesh( newShape );
2042 // re-add shapes of geom groups
2043 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2044 for ( ; data != _geomGroupData.end(); ++data )
2046 TopoDS_Shape newShape = newGroupShape( *data );
2047 if ( !newShape.IsNull() )
2049 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2051 TopoDS_Compound compound;
2052 BRep_Builder().MakeCompound( compound );
2053 BRep_Builder().Add( compound, newShape );
2054 newShape = compound;
2056 _impl->GetSubMesh( newShape );
2059 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2060 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2061 SALOME::INTERNAL_ERROR );
2063 // re-assign hypotheses
2064 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2066 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2067 const THypList& hyps = ids2Hyps[i].second;
2068 THypList::const_iterator h = hyps.begin();
2069 for ( ; h != hyps.end(); ++h )
2070 _impl->AddHypothesis( s, (*h)->GetID() );
2074 for ( size_t i = 0; i < groupsData.size(); ++i )
2076 const TGroupOnGeomData& data = groupsData[i];
2078 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2079 if ( i2g == _mapGroups.end() ) continue;
2081 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2082 if ( !gr_i ) continue;
2085 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2086 meshDS->IndexToShape( data._shapeID ));
2089 _mapGroups.erase( i2g );
2093 g->GetGroupDS()->SetColor( data._color );
2094 gr_i->changeLocalId( id );
2095 _mapGroups[ id ] = i2g->second;
2096 if ( data._oldID != id )
2097 _mapGroups.erase( i2g );
2101 // update _mapSubMesh
2102 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2103 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2104 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2108 //=============================================================================
2110 * \brief Update objects depending on changed geom groups
2112 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2113 * issue 0020210: Update of a smesh group after modification of the associated geom group
2115 //=============================================================================
2117 void SMESH_Mesh_i::CheckGeomGroupModif()
2119 if ( !_impl->HasShapeToMesh() ) return;
2121 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2122 if ( study->_is_nil() ) return;
2124 CORBA::Long nbEntities = NbNodes() + NbElements();
2126 // Check if group contents changed
2128 typedef map< string, TopoDS_Shape > TEntry2Geom;
2129 TEntry2Geom newGroupContents;
2131 list<TGeomGroupData>::iterator
2132 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2133 for ( ; data != dataEnd; ++data )
2135 pair< TEntry2Geom::iterator, bool > it_new =
2136 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2137 bool processedGroup = !it_new.second;
2138 TopoDS_Shape& newShape = it_new.first->second;
2139 if ( !processedGroup )
2140 newShape = newGroupShape( *data );
2141 if ( newShape.IsNull() )
2142 continue; // no changes
2145 _preMeshInfo->ForgetOrLoad();
2147 if ( processedGroup ) { // update group indices
2148 list<TGeomGroupData>::iterator data2 = data;
2149 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2150 data->_indices = data2->_indices;
2153 // Update SMESH objects according to new GEOM group contents
2155 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2156 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2158 int oldID = submesh->GetId();
2159 if ( !_mapSubMeshIor.count( oldID ))
2161 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2163 // update hypotheses
2164 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2165 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2166 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2168 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2169 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2171 // care of submeshes
2172 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2173 int newID = newSubmesh->GetId();
2174 if ( newID != oldID ) {
2175 _mapSubMesh [ newID ] = newSubmesh;
2176 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2177 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2178 _mapSubMesh. erase(oldID);
2179 _mapSubMesh_i. erase(oldID);
2180 _mapSubMeshIor.erase(oldID);
2181 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2186 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2187 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2188 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2190 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2192 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2193 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2194 ds->SetShape( newShape );
2199 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2200 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2202 // Remove groups and submeshes basing on removed sub-shapes
2204 TopTools_MapOfShape newShapeMap;
2205 TopoDS_Iterator shapeIt( newShape );
2206 for ( ; shapeIt.More(); shapeIt.Next() )
2207 newShapeMap.Add( shapeIt.Value() );
2209 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2210 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2212 if ( newShapeMap.Contains( shapeIt.Value() ))
2214 TopTools_IndexedMapOfShape oldShapeMap;
2215 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2216 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2218 const TopoDS_Shape& oldShape = oldShapeMap(i);
2219 int oldInd = meshDS->ShapeToIndex( oldShape );
2221 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2222 if ( i_smIor != _mapSubMeshIor.end() ) {
2223 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2226 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2227 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2229 // check if a group bases on oldInd shape
2230 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2231 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2232 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2233 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2235 RemoveGroup( i_grp->second ); // several groups can base on same shape
2236 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2241 // Reassign hypotheses and update groups after setting the new shape to mesh
2243 // collect anassigned hypotheses
2244 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2245 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2246 TShapeHypList assignedHyps;
2247 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2249 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2250 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2251 if ( !hyps.empty() ) {
2252 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2253 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2254 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2257 // collect shapes supporting groups
2258 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2259 TShapeTypeList groupData;
2260 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2261 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2262 for ( ; grIt != groups.end(); ++grIt )
2264 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2266 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2268 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2270 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2271 _impl->ShapeToMesh( newShape );
2273 // reassign hypotheses
2274 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2275 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2277 TIndexedShape& geom = indS_hyps->first;
2278 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2279 int oldID = geom._index;
2280 int newID = meshDS->ShapeToIndex( geom._shape );
2281 if ( oldID == 1 ) { // main shape
2283 geom._shape = newShape;
2287 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2288 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2289 // care of sub-meshes
2290 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2291 if ( newID != oldID ) {
2292 _mapSubMesh [ newID ] = newSubmesh;
2293 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2294 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2295 _mapSubMesh. erase(oldID);
2296 _mapSubMesh_i. erase(oldID);
2297 _mapSubMeshIor.erase(oldID);
2298 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2302 TShapeTypeList::iterator geomType = groupData.begin();
2303 for ( ; geomType != groupData.end(); ++geomType )
2305 const TIndexedShape& geom = geomType->first;
2306 int oldID = geom._index;
2307 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2310 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2311 CORBA::String_var name = groupSO->GetName();
2313 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2315 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2316 group_i->changeLocalId( newID );
2319 break; // everything has been updated
2322 } // loop on group data
2326 CORBA::Long newNbEntities = NbNodes() + NbElements();
2327 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2328 if ( newNbEntities != nbEntities )
2330 // Add all SObjects with icons to soToUpdateIcons
2331 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2333 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2334 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2335 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2337 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2338 i_gr != _mapGroups.end(); ++i_gr ) // groups
2339 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2342 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2343 for ( ; so != soToUpdateIcons.end(); ++so )
2344 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2347 //=============================================================================
2349 * \brief Create standalone group from a group on geometry or filter
2351 //=============================================================================
2353 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2354 throw (SALOME::SALOME_Exception)
2356 SMESH::SMESH_Group_var aGroup;
2361 _preMeshInfo->FullLoadFromFile();
2363 if ( theGroup->_is_nil() )
2364 return aGroup._retn();
2366 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2368 return aGroup._retn();
2370 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2372 const int anId = aGroupToRem->GetLocalID();
2373 if ( !_impl->ConvertToStandalone( anId ) )
2374 return aGroup._retn();
2375 removeGeomGroupData( theGroup );
2377 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2379 // remove old instance of group from own map
2380 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2381 _mapGroups.erase( anId );
2383 SALOMEDS::StudyBuilder_var builder;
2384 SALOMEDS::SObject_wrap aGroupSO;
2385 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2386 if ( !aStudy->_is_nil() ) {
2387 builder = aStudy->NewBuilder();
2388 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2389 if ( !aGroupSO->_is_nil() )
2391 // remove reference to geometry
2392 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2393 for ( ; chItr->More(); chItr->Next() )
2394 // Remove group's child SObject
2395 builder->RemoveObject( chItr->Value() );
2397 // Update Python script
2398 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2399 << ".ConvertToStandalone( " << aGroupSO << " )";
2401 // change icon of Group on Filter
2404 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2405 const int isEmpty = ( elemTypes->length() == 0 );
2408 SALOMEDS::GenericAttribute_wrap anAttr =
2409 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2410 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2411 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2417 // remember new group in own map
2418 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2419 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2421 // register CORBA object for persistence
2422 _gen_i->RegisterObject( aGroup );
2424 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2425 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2426 //aGroup->Register();
2427 aGroupToRem->UnRegister();
2429 SMESH_CATCH( SMESH::throwCorbaException );
2431 return aGroup._retn();
2434 //=============================================================================
2438 //=============================================================================
2440 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2442 if(MYDEBUG) MESSAGE( "createSubMesh" );
2443 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2444 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2445 const int subMeshId = mySubMesh->GetId();
2447 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2448 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2450 _mapSubMesh [subMeshId] = mySubMesh;
2451 _mapSubMesh_i [subMeshId] = subMeshServant;
2452 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2454 subMeshServant->Register();
2456 // register CORBA object for persistence
2457 int nextId = _gen_i->RegisterObject( subMesh );
2458 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2459 else { nextId = 0; } // avoid "unused variable" warning
2461 // to track changes of GEOM groups
2462 addGeomGroupData( theSubShapeObject, subMesh );
2464 return subMesh._retn();
2467 //=======================================================================
2468 //function : getSubMesh
2470 //=======================================================================
2472 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2474 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2475 if ( it == _mapSubMeshIor.end() )
2476 return SMESH::SMESH_subMesh::_nil();
2478 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2481 //=============================================================================
2485 //=============================================================================
2487 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2488 GEOM::GEOM_Object_ptr theSubShapeObject )
2490 bool isHypChanged = false;
2491 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2492 return isHypChanged;
2494 const int subMeshId = theSubMesh->GetId();
2496 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2498 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2500 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2503 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2504 isHypChanged = !hyps.empty();
2505 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2506 for ( ; hyp != hyps.end(); ++hyp )
2507 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2514 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2515 isHypChanged = ( aHypList->length() > 0 );
2516 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2517 removeHypothesis( theSubShapeObject, aHypList[i] );
2520 catch( const SALOME::SALOME_Exception& ) {
2521 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2523 removeGeomGroupData( theSubShapeObject );
2527 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2528 if ( id_smi != _mapSubMesh_i.end() )
2529 id_smi->second->UnRegister();
2531 // remove a CORBA object
2532 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2533 if ( id_smptr != _mapSubMeshIor.end() )
2534 SMESH::SMESH_subMesh_var( id_smptr->second );
2536 _mapSubMesh.erase(subMeshId);
2537 _mapSubMesh_i.erase(subMeshId);
2538 _mapSubMeshIor.erase(subMeshId);
2540 return isHypChanged;
2543 //=============================================================================
2547 //=============================================================================
2549 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2550 const char* theName,
2551 const TopoDS_Shape& theShape,
2552 const SMESH_PredicatePtr& thePredicate )
2554 std::string newName;
2555 if ( !theName || strlen( theName ) == 0 )
2557 std::set< std::string > presentNames;
2558 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2559 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2561 CORBA::String_var name = i_gr->second->GetName();
2562 presentNames.insert( name.in() );
2565 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2566 } while ( !presentNames.insert( newName ).second );
2567 theName = newName.c_str();
2570 SMESH::SMESH_GroupBase_var aGroup;
2571 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2573 SMESH_GroupBase_i* aGroupImpl;
2574 if ( !theShape.IsNull() )
2575 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2576 else if ( thePredicate )
2577 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2579 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2581 aGroup = aGroupImpl->_this();
2582 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2583 aGroupImpl->Register();
2585 // register CORBA object for persistence
2586 int nextId = _gen_i->RegisterObject( aGroup );
2587 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2588 else { nextId = 0; } // avoid "unused variable" warning in release mode
2590 // to track changes of GEOM groups
2591 if ( !theShape.IsNull() ) {
2592 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2593 addGeomGroupData( geom, aGroup );
2596 return aGroup._retn();
2599 //=============================================================================
2601 * SMESH_Mesh_i::removeGroup
2603 * Should be called by ~SMESH_Group_i()
2605 //=============================================================================
2607 void SMESH_Mesh_i::removeGroup( const int theId )
2609 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2610 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2611 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2612 _mapGroups.erase( theId );
2613 removeGeomGroupData( group );
2614 if ( !_impl->RemoveGroup( theId ))
2616 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2617 RemoveGroup( group );
2619 group->UnRegister();
2623 //=============================================================================
2627 //=============================================================================
2629 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2630 throw(SALOME::SALOME_Exception)
2632 SMESH::log_array_var aLog;
2636 _preMeshInfo->FullLoadFromFile();
2638 list < SMESHDS_Command * >logDS = _impl->GetLog();
2639 aLog = new SMESH::log_array;
2641 int lg = logDS.size();
2644 list < SMESHDS_Command * >::iterator its = logDS.begin();
2645 while(its != logDS.end()){
2646 SMESHDS_Command *com = *its;
2647 int comType = com->GetType();
2649 int lgcom = com->GetNumber();
2651 const list < int >&intList = com->GetIndexes();
2652 int inum = intList.size();
2654 list < int >::const_iterator ii = intList.begin();
2655 const list < double >&coordList = com->GetCoords();
2656 int rnum = coordList.size();
2658 list < double >::const_iterator ir = coordList.begin();
2659 aLog[indexLog].commandType = comType;
2660 aLog[indexLog].number = lgcom;
2661 aLog[indexLog].coords.length(rnum);
2662 aLog[indexLog].indexes.length(inum);
2663 for(int i = 0; i < rnum; i++){
2664 aLog[indexLog].coords[i] = *ir;
2665 //MESSAGE(" "<<i<<" "<<ir.Value());
2668 for(int i = 0; i < inum; i++){
2669 aLog[indexLog].indexes[i] = *ii;
2670 //MESSAGE(" "<<i<<" "<<ii.Value());
2679 SMESH_CATCH( SMESH::throwCorbaException );
2681 return aLog._retn();
2685 //=============================================================================
2689 //=============================================================================
2691 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2695 SMESH_CATCH( SMESH::throwCorbaException );
2698 //=============================================================================
2702 //=============================================================================
2704 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2709 //=============================================================================
2713 //=============================================================================
2715 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2720 //=============================================================================
2723 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2724 // issue 0020918: groups removal is caused by hyp modification
2725 // issue 0021208: to forget not loaded mesh data at hyp modification
2726 struct TCallUp_i : public SMESH_Mesh::TCallUp
2728 SMESH_Mesh_i* _mesh;
2729 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2730 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2731 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2732 virtual void Load () { _mesh->Load(); }
2736 //================================================================================
2738 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2740 //================================================================================
2742 void SMESH_Mesh_i::onHypothesisModified()
2745 _preMeshInfo->ForgetOrLoad();
2748 //=============================================================================
2752 //=============================================================================
2754 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2756 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2759 _impl->SetCallUp( new TCallUp_i(this));
2762 //=============================================================================
2766 //=============================================================================
2768 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2770 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2774 //=============================================================================
2776 * Return mesh editor
2778 //=============================================================================
2780 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2781 throw (SALOME::SALOME_Exception)
2783 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2787 _preMeshInfo->FullLoadFromFile();
2789 // Create MeshEditor
2791 _editor = new SMESH_MeshEditor_i( this, false );
2792 aMeshEdVar = _editor->_this();
2794 // Update Python script
2795 TPythonDump() << _editor << " = "
2796 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2798 SMESH_CATCH( SMESH::throwCorbaException );
2800 return aMeshEdVar._retn();
2803 //=============================================================================
2805 * Return mesh edition previewer
2807 //=============================================================================
2809 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2810 throw (SALOME::SALOME_Exception)
2812 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2816 _preMeshInfo->FullLoadFromFile();
2818 if ( !_previewEditor )
2819 _previewEditor = new SMESH_MeshEditor_i( this, true );
2820 aMeshEdVar = _previewEditor->_this();
2822 SMESH_CATCH( SMESH::throwCorbaException );
2824 return aMeshEdVar._retn();
2827 //================================================================================
2829 * \brief Return true if the mesh has been edited since a last total re-compute
2830 * and those modifications may prevent successful partial re-compute
2832 //================================================================================
2834 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2836 Unexpect aCatch(SALOME_SalomeException);
2837 return _impl->HasModificationsToDiscard();
2840 //================================================================================
2842 * \brief Returns a random unique color
2844 //================================================================================
2846 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2848 const int MAX_ATTEMPTS = 100;
2850 double tolerance = 0.5;
2851 SALOMEDS::Color col;
2855 // generate random color
2856 double red = (double)rand() / RAND_MAX;
2857 double green = (double)rand() / RAND_MAX;
2858 double blue = (double)rand() / RAND_MAX;
2859 // check existence in the list of the existing colors
2860 bool matched = false;
2861 std::list<SALOMEDS::Color>::const_iterator it;
2862 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2863 SALOMEDS::Color color = *it;
2864 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2865 matched = tol < tolerance;
2867 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2868 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2876 //=============================================================================
2878 * Sets auto-color mode. If it is on, groups get unique random colors
2880 //=============================================================================
2882 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2884 Unexpect aCatch(SALOME_SalomeException);
2885 _impl->SetAutoColor(theAutoColor);
2887 TPythonDump pyDump; // not to dump group->SetColor() from below code
2888 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2890 std::list<SALOMEDS::Color> aReservedColors;
2891 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2892 for ( ; it != _mapGroups.end(); it++ ) {
2893 if ( CORBA::is_nil( it->second )) continue;
2894 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2895 it->second->SetColor( aColor );
2896 aReservedColors.push_back( aColor );
2900 //=============================================================================
2902 * Returns true if auto-color mode is on
2904 //=============================================================================
2906 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2908 Unexpect aCatch(SALOME_SalomeException);
2909 return _impl->GetAutoColor();
2912 //=============================================================================
2914 * Checks if there are groups with equal names
2916 //=============================================================================
2918 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2920 return _impl->HasDuplicatedGroupNamesMED();
2923 //================================================================================
2925 * \brief Care of a file before exporting mesh into it
2927 //================================================================================
2929 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2931 SMESH_File aFile( file );
2933 if (aFile.exists()) {
2934 // existing filesystem node
2935 if ( !aFile.isDirectory() ) {
2936 if ( aFile.openForWriting() ) {
2937 if ( overwrite && ! aFile.remove()) {
2938 msg << "Can't replace " << aFile.getName();
2941 msg << "Can't write into " << aFile.getName();
2944 msg << "Location " << aFile.getName() << " is not a file";
2948 // nonexisting file; check if it can be created
2949 if ( !aFile.openForWriting() ) {
2950 msg << "You cannot create the file "
2952 << ". Check the directory existence and access rights";
2960 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2964 //================================================================================
2966 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2967 * \param file - file name
2968 * \param overwrite - to erase the file or not
2969 * \retval string - mesh name
2971 //================================================================================
2973 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2974 CORBA::Boolean overwrite)
2977 PrepareForWriting(file, overwrite);
2978 string aMeshName = "Mesh";
2979 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2980 if ( !aStudy->_is_nil() ) {
2981 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2982 if ( !aMeshSO->_is_nil() ) {
2983 CORBA::String_var name = aMeshSO->GetName();
2985 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2986 if ( !aStudy->GetProperties()->IsLocked() )
2988 SALOMEDS::GenericAttribute_wrap anAttr;
2989 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2990 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2991 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2992 ASSERT(!aFileName->_is_nil());
2993 aFileName->SetValue(file);
2994 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2995 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2996 ASSERT(!aFileType->_is_nil());
2997 aFileType->SetValue("FICHIERMED");
3001 // Update Python script
3002 // set name of mesh before export
3003 TPythonDump() << _gen_i << ".SetName("
3004 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3006 // check names of groups
3012 //================================================================================
3014 * \brief Export to med file
3016 //================================================================================
3018 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3019 CORBA::Boolean auto_groups,
3020 SMESH::MED_VERSION theVersion,
3021 CORBA::Boolean overwrite,
3022 CORBA::Boolean autoDimension)
3023 throw(SALOME::SALOME_Exception)
3027 _preMeshInfo->FullLoadFromFile();
3029 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3030 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3032 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3033 << file << "', " << auto_groups << ", "
3034 << theVersion << ", " << overwrite << ", "
3035 << autoDimension << " )";
3037 SMESH_CATCH( SMESH::throwCorbaException );
3040 //================================================================================
3042 * \brief Export a mesh to a med file
3044 //================================================================================
3046 void SMESH_Mesh_i::ExportToMED (const char* file,
3047 CORBA::Boolean auto_groups,
3048 SMESH::MED_VERSION theVersion)
3049 throw(SALOME::SALOME_Exception)
3051 ExportToMEDX(file,auto_groups,theVersion,true);
3054 //================================================================================
3056 * \brief Export a mesh to a med file
3058 //================================================================================
3060 void SMESH_Mesh_i::ExportMED (const char* file,
3061 CORBA::Boolean auto_groups)
3062 throw(SALOME::SALOME_Exception)
3064 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3067 //================================================================================
3069 * \brief Export a mesh to a SAUV file
3071 //================================================================================
3073 void SMESH_Mesh_i::ExportSAUV (const char* file,
3074 CORBA::Boolean auto_groups)
3075 throw(SALOME::SALOME_Exception)
3077 Unexpect aCatch(SALOME_SalomeException);
3079 _preMeshInfo->FullLoadFromFile();
3081 string aMeshName = prepareMeshNameAndGroups(file, true);
3082 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3083 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3084 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3088 //================================================================================
3090 * \brief Export a mesh to a DAT file
3092 //================================================================================
3094 void SMESH_Mesh_i::ExportDAT (const char *file)
3095 throw(SALOME::SALOME_Exception)
3097 Unexpect aCatch(SALOME_SalomeException);
3099 _preMeshInfo->FullLoadFromFile();
3101 // Update Python script
3102 // check names of groups
3104 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3107 PrepareForWriting(file);
3108 _impl->ExportDAT(file);
3111 //================================================================================
3113 * \brief Export a mesh to an UNV file
3115 //================================================================================
3117 void SMESH_Mesh_i::ExportUNV (const char *file)
3118 throw(SALOME::SALOME_Exception)
3120 Unexpect aCatch(SALOME_SalomeException);
3122 _preMeshInfo->FullLoadFromFile();
3124 // Update Python script
3125 // check names of groups
3127 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3130 PrepareForWriting(file);
3131 _impl->ExportUNV(file);
3134 //================================================================================
3136 * \brief Export a mesh to an STL file
3138 //================================================================================
3140 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3141 throw(SALOME::SALOME_Exception)
3143 Unexpect aCatch(SALOME_SalomeException);
3145 _preMeshInfo->FullLoadFromFile();
3147 // Update Python script
3148 // check names of groups
3150 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3151 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3153 CORBA::String_var name;
3154 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3155 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, _this() );
3156 if ( !so->_is_nil() )
3157 name = so->GetName();
3160 PrepareForWriting( file );
3161 _impl->ExportSTL( file, isascii, name.in() );
3164 //================================================================================
3166 * \brief Export a part of mesh to a med file
3168 //================================================================================
3170 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3172 CORBA::Boolean auto_groups,
3173 SMESH::MED_VERSION version,
3174 CORBA::Boolean overwrite,
3175 CORBA::Boolean autoDimension,
3176 const GEOM::ListOfFields& fields,
3177 const char* geomAssocFields)
3178 throw (SALOME::SALOME_Exception)
3182 _preMeshInfo->FullLoadFromFile();
3185 bool have0dField = false;
3186 if ( fields.length() > 0 )
3188 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3189 if ( shapeToMesh->_is_nil() )
3190 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3192 for ( size_t i = 0; i < fields.length(); ++i )
3194 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3195 THROW_SALOME_CORBA_EXCEPTION
3196 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3197 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3198 if ( fieldShape->_is_nil() )
3199 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3200 if ( !fieldShape->IsSame( shapeToMesh ) )
3201 THROW_SALOME_CORBA_EXCEPTION
3202 ( "Field defined not on shape", SALOME::BAD_PARAM);
3203 if ( fields[i]->GetDimension() == 0 )
3206 if ( geomAssocFields )
3207 for ( int i = 0; geomAssocFields[i]; ++i )
3208 switch ( geomAssocFields[i] ) {
3209 case 'v':case 'e':case 'f':case 's': break;
3210 case 'V':case 'E':case 'F':case 'S': break;
3211 default: THROW_SALOME_CORBA_EXCEPTION
3212 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3216 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3220 string aMeshName = "Mesh";
3221 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3222 if ( CORBA::is_nil( meshPart ) ||
3223 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3225 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3226 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3227 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3228 meshDS = _impl->GetMeshDS();
3233 _preMeshInfo->FullLoadFromFile();
3235 PrepareForWriting(file, overwrite);
3237 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3238 if ( !aStudy->_is_nil() ) {
3239 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3240 if ( !SO->_is_nil() ) {
3241 CORBA::String_var name = SO->GetName();
3245 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3246 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3247 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3248 meshDS = tmpDSDeleter._obj = partDS;
3253 if ( _impl->HasShapeToMesh() )
3255 DriverMED_W_Field fieldWriter;
3256 fieldWriter.SetFile( file );
3257 fieldWriter.SetMeshName( aMeshName );
3258 fieldWriter.AddODOnVertices( have0dField );
3260 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3264 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3265 goList->length( fields.length() );
3266 for ( size_t i = 0; i < fields.length(); ++i )
3268 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3271 TPythonDump() << _this() << ".ExportPartToMED( "
3272 << meshPart << ", r'" << file << "', "
3273 << auto_groups << ", " << version << ", " << overwrite << ", "
3274 << autoDimension << ", " << goList
3275 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3277 SMESH_CATCH( SMESH::throwCorbaException );
3280 //================================================================================
3282 * Write GEOM fields to MED file
3284 //================================================================================
3286 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3287 SMESHDS_Mesh* meshDS,
3288 const GEOM::ListOfFields& fields,
3289 const char* geomAssocFields)
3291 #define METH "SMESH_Mesh_i::exportMEDFields() "
3293 if (( fields.length() < 1 ) &&
3294 ( !geomAssocFields || !geomAssocFields[0] ))
3297 std::vector< std::vector< double > > dblVals;
3298 std::vector< std::vector< int > > intVals;
3299 std::vector< int > subIdsByDim[ 4 ];
3300 const double noneDblValue = 0.;
3301 const double noneIntValue = 0;
3303 for ( size_t iF = 0; iF < fields.length(); ++iF )
3307 int dim = fields[ iF ]->GetDimension();
3308 SMDSAbs_ElementType elemType;
3309 TopAbs_ShapeEnum shapeType;
3311 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3312 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3313 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3314 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3316 continue; // skip fields on whole shape
3318 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3319 if ( dataType == GEOM::FDT_String )
3321 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3322 if ( stepIDs->length() < 1 )
3324 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3325 if ( comps->length() < 1 )
3327 CORBA::String_var name = fields[ iF ]->GetName();
3329 if ( !fieldWriter.Set( meshDS,
3333 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3336 for ( size_t iC = 0; iC < comps->length(); ++iC )
3337 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3339 dblVals.resize( comps->length() );
3340 intVals.resize( comps->length() );
3342 // find sub-shape IDs
3344 std::vector< int >& subIds = subIdsByDim[ dim ];
3345 if ( subIds.empty() )
3346 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3347 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3348 subIds.push_back( id );
3352 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3356 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3358 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3359 if ( step->_is_nil() )
3362 CORBA::Long stamp = step->GetStamp();
3363 CORBA::Long id = step->GetID();
3364 fieldWriter.SetDtIt( int( stamp ), int( id ));
3366 // fill dblVals or intVals
3367 for ( size_t iC = 0; iC < comps->length(); ++iC )
3368 if ( dataType == GEOM::FDT_Double )
3370 dblVals[ iC ].clear();
3371 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3375 intVals[ iC ].clear();
3376 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3380 case GEOM::FDT_Double:
3382 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3383 if ( dblStep->_is_nil() ) continue;
3384 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3385 if ( vv->length() != subIds.size() * comps->length() )
3386 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3387 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3388 for ( size_t iC = 0; iC < comps->length(); ++iC )
3389 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3394 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3395 if ( intStep->_is_nil() ) continue;
3396 GEOM::ListOfLong_var vv = intStep->GetValues();
3397 if ( vv->length() != subIds.size() * comps->length() )
3398 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3399 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3400 for ( size_t iC = 0; iC < comps->length(); ++iC )
3401 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3404 case GEOM::FDT_Bool:
3406 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3407 if ( boolStep->_is_nil() ) continue;
3408 GEOM::short_array_var vv = boolStep->GetValues();
3409 if ( vv->length() != subIds.size() * comps->length() )
3410 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3411 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3412 for ( size_t iC = 0; iC < comps->length(); ++iC )
3413 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3419 // pass values to fieldWriter
3420 elemIt = fieldWriter.GetOrderedElems();
3421 if ( dataType == GEOM::FDT_Double )
3422 while ( elemIt->more() )
3424 const SMDS_MeshElement* e = elemIt->next();
3425 const int shapeID = e->getshapeId();
3426 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3427 for ( size_t iC = 0; iC < comps->length(); ++iC )
3428 fieldWriter.AddValue( noneDblValue );
3430 for ( size_t iC = 0; iC < comps->length(); ++iC )
3431 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3434 while ( elemIt->more() )
3436 const SMDS_MeshElement* e = elemIt->next();
3437 const int shapeID = e->getshapeId();
3438 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3439 for ( size_t iC = 0; iC < comps->length(); ++iC )
3440 fieldWriter.AddValue( (double) noneIntValue );
3442 for ( size_t iC = 0; iC < comps->length(); ++iC )
3443 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3447 fieldWriter.Perform();
3448 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3449 if ( res && res->IsKO() )
3451 if ( res->myComment.empty() )
3452 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3454 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3460 if ( !geomAssocFields || !geomAssocFields[0] )
3463 // write geomAssocFields
3465 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3466 shapeDim[ TopAbs_COMPOUND ] = 3;
3467 shapeDim[ TopAbs_COMPSOLID ] = 3;
3468 shapeDim[ TopAbs_SOLID ] = 3;
3469 shapeDim[ TopAbs_SHELL ] = 2;
3470 shapeDim[ TopAbs_FACE ] = 2;
3471 shapeDim[ TopAbs_WIRE ] = 1;
3472 shapeDim[ TopAbs_EDGE ] = 1;
3473 shapeDim[ TopAbs_VERTEX ] = 0;
3474 shapeDim[ TopAbs_SHAPE ] = 3;
3476 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3478 std::vector< std::string > compNames;
3479 switch ( geomAssocFields[ iF ]) {
3481 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3482 compNames.push_back( "dim" );
3485 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3488 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3491 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3495 compNames.push_back( "id" );
3496 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3497 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3499 fieldWriter.SetDtIt( -1, -1 );
3501 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3505 if ( compNames.size() == 2 ) // _vertices_
3506 while ( elemIt->more() )
3508 const SMDS_MeshElement* e = elemIt->next();
3509 const int shapeID = e->getshapeId();
3512 fieldWriter.AddValue( (double) -1 );
3513 fieldWriter.AddValue( (double) -1 );
3517 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3518 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3519 fieldWriter.AddValue( (double) shapeID );
3523 while ( elemIt->more() )
3525 const SMDS_MeshElement* e = elemIt->next();
3526 const int shapeID = e->getshapeId();
3528 fieldWriter.AddValue( (double) -1 );
3530 fieldWriter.AddValue( (double) shapeID );
3534 fieldWriter.Perform();
3535 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3536 if ( res && res->IsKO() )
3538 if ( res->myComment.empty() )
3539 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3541 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3544 } // loop on geomAssocFields
3549 //================================================================================
3551 * \brief Export a part of mesh to a DAT file
3553 //================================================================================
3555 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3557 throw (SALOME::SALOME_Exception)
3559 Unexpect aCatch(SALOME_SalomeException);
3561 _preMeshInfo->FullLoadFromFile();
3563 PrepareForWriting(file);
3565 SMESH_MeshPartDS partDS( meshPart );
3566 _impl->ExportDAT(file,&partDS);
3568 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3569 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3571 //================================================================================
3573 * \brief Export a part of mesh to an UNV file
3575 //================================================================================
3577 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3579 throw (SALOME::SALOME_Exception)
3581 Unexpect aCatch(SALOME_SalomeException);
3583 _preMeshInfo->FullLoadFromFile();
3585 PrepareForWriting(file);
3587 SMESH_MeshPartDS partDS( meshPart );
3588 _impl->ExportUNV(file, &partDS);
3590 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3591 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3593 //================================================================================
3595 * \brief Export a part of mesh to an STL file
3597 //================================================================================
3599 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3601 ::CORBA::Boolean isascii)
3602 throw (SALOME::SALOME_Exception)
3604 Unexpect aCatch(SALOME_SalomeException);
3606 _preMeshInfo->FullLoadFromFile();
3608 PrepareForWriting(file);
3610 CORBA::String_var name;
3611 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3612 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3613 if ( !so->_is_nil() )
3614 name = so->GetName();
3616 SMESH_MeshPartDS partDS( meshPart );
3617 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3619 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3620 << meshPart<< ", r'" << file << "', " << isascii << ")";
3623 //================================================================================
3625 * \brief Export a part of mesh to an STL file
3627 //================================================================================
3629 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3631 CORBA::Boolean overwrite,
3632 CORBA::Boolean groupElemsByType)
3633 throw (SALOME::SALOME_Exception)
3636 Unexpect aCatch(SALOME_SalomeException);
3638 _preMeshInfo->FullLoadFromFile();
3640 PrepareForWriting(file,overwrite);
3642 std::string meshName("");
3643 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3644 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3645 if ( !so->_is_nil() )
3647 CORBA::String_var name = so->GetName();
3648 meshName = name.in();
3652 SMESH_MeshPartDS partDS( meshPart );
3653 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3655 SMESH_CATCH( SMESH::throwCorbaException );
3657 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3658 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3660 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3664 //================================================================================
3666 * \brief Export a part of mesh to a GMF file
3668 //================================================================================
3670 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3672 bool withRequiredGroups)
3673 throw (SALOME::SALOME_Exception)
3675 Unexpect aCatch(SALOME_SalomeException);
3677 _preMeshInfo->FullLoadFromFile();
3679 PrepareForWriting(file,/*overwrite=*/true);
3681 SMESH_MeshPartDS partDS( meshPart );
3682 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3684 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3685 << meshPart<< ", r'"
3687 << withRequiredGroups << ")";
3690 //=============================================================================
3692 * Return computation progress [0.,1]
3694 //=============================================================================
3696 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3700 return _impl->GetComputeProgress();
3702 SMESH_CATCH( SMESH::doNothing );
3706 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3708 Unexpect aCatch(SALOME_SalomeException);
3710 return _preMeshInfo->NbNodes();
3712 return _impl->NbNodes();
3715 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3717 Unexpect aCatch(SALOME_SalomeException);
3719 return _preMeshInfo->NbElements();
3721 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3724 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3726 Unexpect aCatch(SALOME_SalomeException);
3728 return _preMeshInfo->Nb0DElements();
3730 return _impl->Nb0DElements();
3733 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3735 Unexpect aCatch(SALOME_SalomeException);
3737 return _preMeshInfo->NbBalls();
3739 return _impl->NbBalls();
3742 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3744 Unexpect aCatch(SALOME_SalomeException);
3746 return _preMeshInfo->NbEdges();
3748 return _impl->NbEdges();
3751 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3752 throw(SALOME::SALOME_Exception)
3754 Unexpect aCatch(SALOME_SalomeException);
3756 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3758 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3761 //=============================================================================
3763 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3765 Unexpect aCatch(SALOME_SalomeException);
3767 return _preMeshInfo->NbFaces();
3769 return _impl->NbFaces();
3772 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3774 Unexpect aCatch(SALOME_SalomeException);
3776 return _preMeshInfo->NbTriangles();
3778 return _impl->NbTriangles();
3781 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3783 Unexpect aCatch(SALOME_SalomeException);
3785 return _preMeshInfo->NbBiQuadTriangles();
3787 return _impl->NbBiQuadTriangles();
3790 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3792 Unexpect aCatch(SALOME_SalomeException);
3794 return _preMeshInfo->NbQuadrangles();
3796 return _impl->NbQuadrangles();
3799 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3801 Unexpect aCatch(SALOME_SalomeException);
3803 return _preMeshInfo->NbBiQuadQuadrangles();
3805 return _impl->NbBiQuadQuadrangles();
3808 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3810 Unexpect aCatch(SALOME_SalomeException);
3812 return _preMeshInfo->NbPolygons();
3814 return _impl->NbPolygons();
3817 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3819 Unexpect aCatch(SALOME_SalomeException);
3821 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3823 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3826 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3827 throw(SALOME::SALOME_Exception)
3829 Unexpect aCatch(SALOME_SalomeException);
3831 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3833 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3836 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3837 throw(SALOME::SALOME_Exception)
3839 Unexpect aCatch(SALOME_SalomeException);
3841 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3843 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3846 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3847 throw(SALOME::SALOME_Exception)
3849 Unexpect aCatch(SALOME_SalomeException);
3851 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3853 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3856 //=============================================================================
3858 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3860 Unexpect aCatch(SALOME_SalomeException);
3862 return _preMeshInfo->NbVolumes();
3864 return _impl->NbVolumes();
3867 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3869 Unexpect aCatch(SALOME_SalomeException);
3871 return _preMeshInfo->NbTetras();
3873 return _impl->NbTetras();
3876 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3878 Unexpect aCatch(SALOME_SalomeException);
3880 return _preMeshInfo->NbHexas();
3882 return _impl->NbHexas();
3885 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3887 Unexpect aCatch(SALOME_SalomeException);
3889 return _preMeshInfo->NbTriQuadHexas();
3891 return _impl->NbTriQuadraticHexas();
3894 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3896 Unexpect aCatch(SALOME_SalomeException);
3898 return _preMeshInfo->NbPyramids();
3900 return _impl->NbPyramids();
3903 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3905 Unexpect aCatch(SALOME_SalomeException);
3907 return _preMeshInfo->NbPrisms();
3909 return _impl->NbPrisms();
3912 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3914 Unexpect aCatch(SALOME_SalomeException);
3916 return _preMeshInfo->NbHexPrisms();
3918 return _impl->NbHexagonalPrisms();
3921 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3923 Unexpect aCatch(SALOME_SalomeException);
3925 return _preMeshInfo->NbPolyhedrons();
3927 return _impl->NbPolyhedrons();
3930 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3931 throw(SALOME::SALOME_Exception)
3933 Unexpect aCatch(SALOME_SalomeException);
3935 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3937 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3940 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3941 throw(SALOME::SALOME_Exception)
3943 Unexpect aCatch(SALOME_SalomeException);
3945 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3947 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3950 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3951 throw(SALOME::SALOME_Exception)
3953 Unexpect aCatch(SALOME_SalomeException);
3955 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3957 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3960 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3961 throw(SALOME::SALOME_Exception)
3963 Unexpect aCatch(SALOME_SalomeException);
3965 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3967 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3970 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3971 throw(SALOME::SALOME_Exception)
3973 Unexpect aCatch(SALOME_SalomeException);
3975 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3977 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3980 //=============================================================================
3982 * Returns nb of published sub-meshes
3984 //=============================================================================
3986 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3988 Unexpect aCatch(SALOME_SalomeException);
3989 return _mapSubMesh_i.size();
3992 //=============================================================================
3994 * Dumps mesh into a string
3996 //=============================================================================
3998 char* SMESH_Mesh_i::Dump()
4002 return CORBA::string_dup( os.str().c_str() );
4005 //=============================================================================
4007 * Method of SMESH_IDSource interface
4009 //=============================================================================
4011 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4013 return GetElementsId();
4016 //=============================================================================
4018 * Returns ids of all elements
4020 //=============================================================================
4022 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4023 throw (SALOME::SALOME_Exception)
4025 Unexpect aCatch(SALOME_SalomeException);
4027 _preMeshInfo->FullLoadFromFile();
4029 SMESH::long_array_var aResult = new SMESH::long_array();
4030 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4032 if ( aSMESHDS_Mesh == NULL )
4033 return aResult._retn();
4035 long nbElements = NbElements();
4036 aResult->length( nbElements );
4037 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4038 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4039 aResult[i] = anIt->next()->GetID();
4041 return aResult._retn();
4045 //=============================================================================
4047 * Returns ids of all elements of given type
4049 //=============================================================================
4051 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4052 throw (SALOME::SALOME_Exception)
4054 Unexpect aCatch(SALOME_SalomeException);
4056 _preMeshInfo->FullLoadFromFile();
4058 SMESH::long_array_var aResult = new SMESH::long_array();
4059 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4061 if ( aSMESHDS_Mesh == NULL )
4062 return aResult._retn();
4064 long nbElements = NbElements();
4066 // No sense in returning ids of elements along with ids of nodes:
4067 // when theElemType == SMESH::ALL, return node ids only if
4068 // there are no elements
4069 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4070 return GetNodesId();
4072 aResult->length( nbElements );
4076 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4077 while ( i < nbElements && anIt->more() )
4078 aResult[i++] = anIt->next()->GetID();
4080 aResult->length( i );
4082 return aResult._retn();
4085 //=============================================================================
4087 * Returns ids of all nodes
4089 //=============================================================================
4091 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4092 throw (SALOME::SALOME_Exception)
4094 Unexpect aCatch(SALOME_SalomeException);
4096 _preMeshInfo->FullLoadFromFile();
4098 SMESH::long_array_var aResult = new SMESH::long_array();
4099 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4101 if ( aSMESHDS_Mesh == NULL )
4102 return aResult._retn();
4104 long nbNodes = NbNodes();
4105 aResult->length( nbNodes );
4106 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4107 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4108 aResult[i] = anIt->next()->GetID();
4110 return aResult._retn();
4113 //=============================================================================
4117 //=============================================================================
4119 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4120 throw (SALOME::SALOME_Exception)
4122 SMESH::ElementType type = SMESH::ALL;
4126 _preMeshInfo->FullLoadFromFile();
4128 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4130 SMESH_CATCH( SMESH::throwCorbaException );
4135 //=============================================================================
4139 //=============================================================================
4141 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4142 throw (SALOME::SALOME_Exception)
4145 _preMeshInfo->FullLoadFromFile();
4147 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4149 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4151 return ( SMESH::EntityType ) e->GetEntityType();
4154 //=============================================================================
4158 //=============================================================================
4160 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4161 throw (SALOME::SALOME_Exception)
4164 _preMeshInfo->FullLoadFromFile();
4166 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4168 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4170 return ( SMESH::GeometryType ) e->GetGeomType();
4173 //=============================================================================
4175 * Returns ID of elements for given submesh
4177 //=============================================================================
4178 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4179 throw (SALOME::SALOME_Exception)
4181 SMESH::long_array_var aResult = new SMESH::long_array();
4185 _preMeshInfo->FullLoadFromFile();
4187 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4188 if(!SM) return aResult._retn();
4190 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4191 if(!SDSM) return aResult._retn();
4193 aResult->length(SDSM->NbElements());
4195 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4197 while ( eIt->more() ) {
4198 aResult[i++] = eIt->next()->GetID();
4201 SMESH_CATCH( SMESH::throwCorbaException );
4203 return aResult._retn();
4206 //=============================================================================
4208 * Returns ID of nodes for given submesh
4209 * If param all==true - returns all nodes, else -
4210 * returns only nodes on shapes.
4212 //=============================================================================
4214 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4216 throw (SALOME::SALOME_Exception)
4218 SMESH::long_array_var aResult = new SMESH::long_array();
4222 _preMeshInfo->FullLoadFromFile();
4224 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4225 if(!SM) return aResult._retn();
4227 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4228 if(!SDSM) return aResult._retn();
4231 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4232 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4233 while ( nIt->more() ) {
4234 const SMDS_MeshNode* elem = nIt->next();
4235 theElems.insert( elem->GetID() );
4238 else { // all nodes of submesh elements
4239 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4240 while ( eIt->more() ) {
4241 const SMDS_MeshElement* anElem = eIt->next();
4242 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4243 while ( nIt->more() ) {
4244 const SMDS_MeshElement* elem = nIt->next();
4245 theElems.insert( elem->GetID() );
4250 aResult->length(theElems.size());
4251 set<int>::iterator itElem;
4253 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4254 aResult[i++] = *itElem;
4256 SMESH_CATCH( SMESH::throwCorbaException );
4258 return aResult._retn();
4261 //=============================================================================
4263 * Returns type of elements for given submesh
4265 //=============================================================================
4267 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4268 throw (SALOME::SALOME_Exception)
4270 SMESH::ElementType type = SMESH::ALL;
4274 _preMeshInfo->FullLoadFromFile();
4276 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4277 if(!SM) return SMESH::ALL;
4279 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4280 if(!SDSM) return SMESH::ALL;
4282 if(SDSM->NbElements()==0)
4283 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4285 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4286 const SMDS_MeshElement* anElem = eIt->next();
4288 type = ( SMESH::ElementType ) anElem->GetType();
4290 SMESH_CATCH( SMESH::throwCorbaException );
4296 //=============================================================================
4298 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4300 //=============================================================================
4302 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4305 _preMeshInfo->FullLoadFromFile();
4307 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4308 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4313 //=============================================================================
4315 * Get XYZ coordinates of node as list of double
4316 * If there is not node for given ID - returns empty list
4318 //=============================================================================
4320 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4323 _preMeshInfo->FullLoadFromFile();
4325 SMESH::double_array_var aResult = new SMESH::double_array();
4326 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4327 if ( aSMESHDS_Mesh == NULL )
4328 return aResult._retn();
4331 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4333 return aResult._retn();
4337 aResult[0] = aNode->X();
4338 aResult[1] = aNode->Y();
4339 aResult[2] = aNode->Z();
4340 return aResult._retn();
4344 //=============================================================================
4346 * For given node returns list of IDs of inverse elements
4347 * If there is not node for given ID - returns empty list
4349 //=============================================================================
4351 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4354 _preMeshInfo->FullLoadFromFile();
4356 SMESH::long_array_var aResult = new SMESH::long_array();
4357 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4358 if ( aSMESHDS_Mesh == NULL )
4359 return aResult._retn();
4362 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4364 return aResult._retn();
4366 // find inverse elements
4367 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4368 aResult->length( aNode->NbInverseElements() );
4369 for( int i = 0; eIt->more(); ++i )
4371 const SMDS_MeshElement* elem = eIt->next();
4372 aResult[ i ] = elem->GetID();
4374 return aResult._retn();
4377 //=============================================================================
4379 * \brief Return position of a node on shape
4381 //=============================================================================
4383 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4386 _preMeshInfo->FullLoadFromFile();
4388 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4389 aNodePosition->shapeID = 0;
4390 aNodePosition->shapeType = GEOM::SHAPE;
4392 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4393 if ( !mesh ) return aNodePosition;
4395 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4397 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4399 aNodePosition->shapeID = aNode->getshapeId();
4400 switch ( pos->GetTypeOfPosition() ) {
4402 aNodePosition->shapeType = GEOM::EDGE;
4403 aNodePosition->params.length(1);
4404 aNodePosition->params[0] =
4405 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4408 aNodePosition->shapeType = GEOM::FACE;
4409 aNodePosition->params.length(2);
4410 aNodePosition->params[0] =
4411 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4412 aNodePosition->params[1] =
4413 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4415 case SMDS_TOP_VERTEX:
4416 aNodePosition->shapeType = GEOM::VERTEX;
4418 case SMDS_TOP_3DSPACE:
4419 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4420 aNodePosition->shapeType = GEOM::SOLID;
4421 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4422 aNodePosition->shapeType = GEOM::SHELL;
4428 return aNodePosition;
4431 //=============================================================================
4433 * \brief Return position of an element on shape
4435 //=============================================================================
4437 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4440 _preMeshInfo->FullLoadFromFile();
4442 SMESH::ElementPosition anElementPosition;
4443 anElementPosition.shapeID = 0;
4444 anElementPosition.shapeType = GEOM::SHAPE;
4446 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4447 if ( !mesh ) return anElementPosition;
4449 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4451 anElementPosition.shapeID = anElem->getshapeId();
4452 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4453 if ( !aSp.IsNull() ) {
4454 switch ( aSp.ShapeType() ) {
4456 anElementPosition.shapeType = GEOM::EDGE;
4459 anElementPosition.shapeType = GEOM::FACE;
4462 anElementPosition.shapeType = GEOM::VERTEX;
4465 anElementPosition.shapeType = GEOM::SOLID;
4468 anElementPosition.shapeType = GEOM::SHELL;
4474 return anElementPosition;
4477 //=============================================================================
4479 * If given element is node returns IDs of shape from position
4480 * If there is not node for given ID - returns -1
4482 //=============================================================================
4484 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4487 _preMeshInfo->FullLoadFromFile();
4489 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4490 if ( aSMESHDS_Mesh == NULL )
4494 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4496 return aNode->getshapeId();
4503 //=============================================================================
4505 * For given element returns ID of result shape after
4506 * ::FindShape() from SMESH_MeshEditor
4507 * If there is not element for given ID - returns -1
4509 //=============================================================================
4511 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4514 _preMeshInfo->FullLoadFromFile();
4516 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4517 if ( aSMESHDS_Mesh == NULL )
4520 // try to find element
4521 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4525 ::SMESH_MeshEditor aMeshEditor(_impl);
4526 int index = aMeshEditor.FindShape( elem );
4534 //=============================================================================
4536 * Returns number of nodes for given element
4537 * If there is not element for given ID - returns -1
4539 //=============================================================================
4541 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4544 _preMeshInfo->FullLoadFromFile();
4546 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4547 if ( aSMESHDS_Mesh == NULL ) return -1;
4548 // try to find element
4549 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4550 if(!elem) return -1;
4551 return elem->NbNodes();
4555 //=============================================================================
4557 * Returns ID of node by given index for given element
4558 * If there is not element for given ID - returns -1
4559 * If there is not node for given index - returns -2
4561 //=============================================================================
4563 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4566 _preMeshInfo->FullLoadFromFile();
4568 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4569 if ( aSMESHDS_Mesh == NULL ) return -1;
4570 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4571 if(!elem) return -1;
4572 if( index>=elem->NbNodes() || index<0 ) return -1;
4573 return elem->GetNode(index)->GetID();
4576 //=============================================================================
4578 * Returns IDs of nodes of given element
4580 //=============================================================================
4582 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4585 _preMeshInfo->FullLoadFromFile();
4587 SMESH::long_array_var aResult = new SMESH::long_array();
4588 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4590 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4592 aResult->length( elem->NbNodes() );
4593 for ( int i = 0; i < elem->NbNodes(); ++i )
4594 aResult[ i ] = elem->GetNode( i )->GetID();
4597 return aResult._retn();
4600 //=============================================================================
4602 * Returns true if given node is medium node
4603 * in given quadratic element
4605 //=============================================================================
4607 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4610 _preMeshInfo->FullLoadFromFile();
4612 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4613 if ( aSMESHDS_Mesh == NULL ) return false;
4615 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4616 if(!aNode) return false;
4617 // try to find element
4618 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4619 if(!elem) return false;
4621 return elem->IsMediumNode(aNode);
4625 //=============================================================================
4627 * Returns true if given node is medium node
4628 * in one of quadratic elements
4630 //=============================================================================
4632 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4633 SMESH::ElementType theElemType)
4636 _preMeshInfo->FullLoadFromFile();
4638 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4639 if ( aSMESHDS_Mesh == NULL ) return false;
4642 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4643 if(!aNode) return false;
4645 SMESH_MesherHelper aHelper( *(_impl) );
4647 SMDSAbs_ElementType aType;
4648 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4649 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4650 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4651 else aType = SMDSAbs_All;
4653 return aHelper.IsMedium(aNode,aType);
4657 //=============================================================================
4659 * Returns number of edges for given element
4661 //=============================================================================
4663 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4666 _preMeshInfo->FullLoadFromFile();
4668 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4669 if ( aSMESHDS_Mesh == NULL ) return -1;
4670 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4671 if(!elem) return -1;
4672 return elem->NbEdges();
4676 //=============================================================================
4678 * Returns number of faces for given element
4680 //=============================================================================
4682 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4685 _preMeshInfo->FullLoadFromFile();
4687 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4688 if ( aSMESHDS_Mesh == NULL ) return -1;
4689 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4690 if(!elem) return -1;
4691 return elem->NbFaces();
4694 //=======================================================================
4695 //function : GetElemFaceNodes
4696 //purpose : Returns nodes of given face (counted from zero) for given element.
4697 //=======================================================================
4699 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4700 CORBA::Short faceIndex)
4703 _preMeshInfo->FullLoadFromFile();
4705 SMESH::long_array_var aResult = new SMESH::long_array();
4706 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4708 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4710 SMDS_VolumeTool vtool( elem );
4711 if ( faceIndex < vtool.NbFaces() )
4713 aResult->length( vtool.NbFaceNodes( faceIndex ));
4714 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4715 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4716 aResult[ i ] = nn[ i ]->GetID();
4720 return aResult._retn();
4723 //=======================================================================
4724 //function : GetElemFaceNodes
4725 //purpose : Returns three components of normal of given mesh face.
4726 //=======================================================================
4728 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4729 CORBA::Boolean normalized)
4732 _preMeshInfo->FullLoadFromFile();
4734 SMESH::double_array_var aResult = new SMESH::double_array();
4736 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4739 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4741 aResult->length( 3 );
4742 aResult[ 0 ] = normal.X();
4743 aResult[ 1 ] = normal.Y();
4744 aResult[ 2 ] = normal.Z();
4747 return aResult._retn();
4750 //=======================================================================
4751 //function : FindElementByNodes
4752 //purpose : Returns an element based on all given nodes.
4753 //=======================================================================
4755 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4758 _preMeshInfo->FullLoadFromFile();
4760 CORBA::Long elemID(0);
4761 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4763 vector< const SMDS_MeshNode * > nn( nodes.length() );
4764 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4765 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4768 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4769 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4770 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4771 _impl->NbVolumes( ORDER_QUADRATIC )))
4772 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4774 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4779 //================================================================================
4781 * \brief Return elements including all given nodes.
4783 //================================================================================
4785 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4786 SMESH::ElementType elemType)
4789 _preMeshInfo->FullLoadFromFile();
4791 SMESH::long_array_var result = new SMESH::long_array();
4793 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4795 vector< const SMDS_MeshNode * > nn( nodes.length() );
4796 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4797 nn[i] = mesh->FindNode( nodes[i] );
4799 std::vector<const SMDS_MeshElement *> elems;
4800 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4801 result->length( elems.size() );
4802 for ( size_t i = 0; i < elems.size(); ++i )
4803 result[i] = elems[i]->GetID();
4805 return result._retn();
4808 //=============================================================================
4810 * Returns true if given element is polygon
4812 //=============================================================================
4814 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4817 _preMeshInfo->FullLoadFromFile();
4819 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4820 if ( aSMESHDS_Mesh == NULL ) return false;
4821 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4822 if(!elem) return false;
4823 return elem->IsPoly();
4827 //=============================================================================
4829 * Returns true if given element is quadratic
4831 //=============================================================================
4833 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4836 _preMeshInfo->FullLoadFromFile();
4838 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4839 if ( aSMESHDS_Mesh == NULL ) return false;
4840 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4841 if(!elem) return false;
4842 return elem->IsQuadratic();
4845 //=============================================================================
4847 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4849 //=============================================================================
4851 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4854 _preMeshInfo->FullLoadFromFile();
4856 if ( const SMDS_BallElement* ball =
4857 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4858 return ball->GetDiameter();
4863 //=============================================================================
4865 * Returns bary center for given element
4867 //=============================================================================
4869 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4872 _preMeshInfo->FullLoadFromFile();
4874 SMESH::double_array_var aResult = new SMESH::double_array();
4875 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4876 if ( aSMESHDS_Mesh == NULL )
4877 return aResult._retn();
4879 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4881 return aResult._retn();
4883 if(elem->GetType()==SMDSAbs_Volume) {
4884 SMDS_VolumeTool aTool;
4885 if(aTool.Set(elem)) {
4887 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4892 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4894 double x=0., y=0., z=0.;
4895 for(; anIt->more(); ) {
4897 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4911 return aResult._retn();
4914 //================================================================================
4916 * \brief Create a group of elements preventing computation of a sub-shape
4918 //================================================================================
4920 SMESH::ListOfGroups*
4921 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4922 const char* theGroupName )
4923 throw ( SALOME::SALOME_Exception )
4925 Unexpect aCatch(SALOME_SalomeException);
4927 if ( !theGroupName || strlen( theGroupName) == 0 )
4928 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4930 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4931 ::SMESH_MeshEditor::ElemFeatures elemType;
4933 // submesh by subshape id
4934 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4935 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4938 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4939 if ( error && !error->myBadElements.empty())
4941 // sort bad elements by type
4942 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4943 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4944 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4945 for ( ; elemIt != elemEnd; ++elemIt )
4947 const SMDS_MeshElement* elem = *elemIt;
4948 if ( !elem ) continue;
4950 if ( elem->GetID() < 1 )
4952 // elem is a temporary element, make a real element
4953 vector< const SMDS_MeshNode* > nodes;
4954 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4955 while ( nIt->more() && elem )
4957 nodes.push_back( nIt->next() );
4958 if ( nodes.back()->GetID() < 1 )
4959 elem = 0; // a temporary element on temporary nodes
4963 ::SMESH_MeshEditor editor( _impl );
4964 elem = editor.AddElement( nodes, elemType.Init( elem ));
4968 elemsByType[ elem->GetType() ].push_back( elem );
4971 // how many groups to create?
4973 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4974 nbTypes += int( !elemsByType[ i ].empty() );
4975 groups->length( nbTypes );
4978 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4980 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4981 if ( elems.empty() ) continue;
4983 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4984 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4986 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4987 SMESH::SMESH_Mesh_var mesh = _this();
4988 SALOMEDS::SObject_wrap aSO =
4989 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4990 GEOM::GEOM_Object::_nil(), theGroupName);
4992 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4993 if ( !grp_i ) continue;
4995 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4996 for ( size_t iE = 0; iE < elems.size(); ++iE )
4997 grpDS->SMDSGroup().Add( elems[ iE ]);
5002 return groups._retn();
5005 //=============================================================================
5007 * Create and publish group servants if any groups were imported or created anyhow
5009 //=============================================================================
5011 void SMESH_Mesh_i::CreateGroupServants()
5013 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5014 SMESH::SMESH_Mesh_var aMesh = _this();
5017 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5018 while ( groupIt->more() )
5020 ::SMESH_Group* group = groupIt->next();
5021 int anId = group->GetGroupDS()->GetID();
5023 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5024 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5026 addedIDs.insert( anId );
5028 SMESH_GroupBase_i* aGroupImpl;
5030 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5031 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5033 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5034 shape = groupOnGeom->GetShape();
5037 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5040 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5041 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5042 aGroupImpl->Register();
5044 // register CORBA object for persistence
5045 int nextId = _gen_i->RegisterObject( groupVar );
5046 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5047 else { nextId = 0; } // avoid "unused variable" warning in release mode
5049 // publishing the groups in the study
5050 if ( !aStudy->_is_nil() ) {
5051 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5052 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
5055 if ( !addedIDs.empty() )
5058 set<int>::iterator id = addedIDs.begin();
5059 for ( ; id != addedIDs.end(); ++id )
5061 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5062 int i = std::distance( _mapGroups.begin(), it );
5063 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5068 //=============================================================================
5070 * \brief Return groups cantained in _mapGroups by their IDs
5072 //=============================================================================
5074 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5076 int nbGroups = groupIDs.size();
5077 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5078 aList->length( nbGroups );
5080 list<int>::const_iterator ids = groupIDs.begin();
5081 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5083 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5084 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5085 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5087 aList->length( nbGroups );
5088 return aList._retn();
5091 //=============================================================================
5093 * \brief Return information about imported file
5095 //=============================================================================
5097 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5099 SMESH::MedFileInfo_var res( _medFileInfo );
5100 if ( !res.operator->() ) {
5101 res = new SMESH::MedFileInfo;
5103 res->fileSize = res->major = res->minor = res->release = -1;
5108 //=============================================================================
5110 * \brief Pass names of mesh groups from study to mesh DS
5112 //=============================================================================
5114 void SMESH_Mesh_i::checkGroupNames()
5116 int nbGrp = NbGroups();
5120 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5121 if ( aStudy->_is_nil() )
5122 return; // nothing to do
5124 SMESH::ListOfGroups* grpList = 0;
5125 // avoid dump of "GetGroups"
5127 // store python dump into a local variable inside local scope
5128 SMESH::TPythonDump pDump; // do not delete this line of code
5129 grpList = GetGroups();
5132 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5133 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5136 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5137 if ( aGrpSO->_is_nil() )
5139 // correct name of the mesh group if necessary
5140 const char* guiName = aGrpSO->GetName();
5141 if ( strcmp(guiName, aGrp->GetName()) )
5142 aGrp->SetName( guiName );
5146 //=============================================================================
5148 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5150 //=============================================================================
5151 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5153 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5157 //=============================================================================
5159 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5161 //=============================================================================
5163 char* SMESH_Mesh_i::GetParameters()
5165 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5168 //=============================================================================
5170 * \brief Returns list of notebook variables used for last Mesh operation
5172 //=============================================================================
5173 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5175 SMESH::string_array_var aResult = new SMESH::string_array();
5176 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5178 CORBA::String_var aParameters = GetParameters();
5179 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5180 if ( !aStudy->_is_nil()) {
5181 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5182 if ( aSections->length() > 0 ) {
5183 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5184 aResult->length( aVars.length() );
5185 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5186 aResult[i] = CORBA::string_dup( aVars[i] );
5190 return aResult._retn();
5193 //=======================================================================
5194 //function : GetTypes
5195 //purpose : Returns types of elements it contains
5196 //=======================================================================
5198 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5201 return _preMeshInfo->GetTypes();
5203 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5207 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5208 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5209 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5210 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5211 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5212 if (_impl->NbNodes() &&
5213 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5214 types->length( nbTypes );
5216 return types._retn();
5219 //=======================================================================
5220 //function : GetMesh
5221 //purpose : Returns self
5222 //=======================================================================
5224 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5226 return SMESH::SMESH_Mesh::_duplicate( _this() );
5229 //=======================================================================
5230 //function : IsMeshInfoCorrect
5231 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5232 // * happen if mesh data is not yet fully loaded from the file of study.
5233 //=======================================================================
5235 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5237 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5240 //=============================================================================
5242 * \brief Returns number of mesh elements per each \a EntityType
5244 //=============================================================================
5246 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5249 return _preMeshInfo->GetMeshInfo();
5251 SMESH::long_array_var aRes = new SMESH::long_array();
5252 aRes->length(SMESH::Entity_Last);
5253 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5255 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5257 return aRes._retn();
5258 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5259 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5260 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5261 return aRes._retn();
5264 //=============================================================================
5266 * \brief Returns number of mesh elements per each \a ElementType
5268 //=============================================================================
5270 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5272 SMESH::long_array_var aRes = new SMESH::long_array();
5273 aRes->length(SMESH::NB_ELEMENT_TYPES);
5274 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5277 const SMDS_MeshInfo* meshInfo = 0;
5279 meshInfo = _preMeshInfo;
5280 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5281 meshInfo = & meshDS->GetMeshInfo();
5284 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5285 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5287 return aRes._retn();
5290 //=============================================================================
5292 * Collect statistic of mesh elements given by iterator
5294 //=============================================================================
5296 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5297 SMESH::long_array& theInfo)
5299 if (!theItr) return;
5300 while (theItr->more())
5301 theInfo[ theItr->next()->GetEntityType() ]++;
5303 //=============================================================================
5305 * Returns mesh unstructed grid information.
5307 //=============================================================================
5309 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5311 SALOMEDS::TMPFile_var SeqFile;
5312 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5313 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5315 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5316 aWriter->WriteToOutputStringOn();
5317 aWriter->SetInputData(aGrid);
5318 aWriter->SetFileTypeToBinary();
5320 char* str = aWriter->GetOutputString();
5321 int size = aWriter->GetOutputStringLength();
5323 //Allocate octect buffer of required size
5324 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5325 //Copy ostrstream content to the octect buffer
5326 memcpy(OctetBuf, str, size);
5327 //Create and return TMPFile
5328 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5332 return SeqFile._retn();
5335 //=============================================================================
5336 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5337 * SMESH::ElementType type) */
5339 using namespace SMESH::Controls;
5340 //-----------------------------------------------------------------------------
5341 struct PredicateIterator : public SMDS_ElemIterator
5343 SMDS_ElemIteratorPtr _elemIter;
5344 PredicatePtr _predicate;
5345 const SMDS_MeshElement* _elem;
5347 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5348 PredicatePtr predicate):
5349 _elemIter(iterator), _predicate(predicate)
5357 virtual const SMDS_MeshElement* next()
5359 const SMDS_MeshElement* res = _elem;
5361 while ( _elemIter->more() && !_elem )
5363 _elem = _elemIter->next();
5364 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5371 //-----------------------------------------------------------------------------
5372 struct IDSourceIterator : public SMDS_ElemIterator
5374 const CORBA::Long* _idPtr;
5375 const CORBA::Long* _idEndPtr;
5376 SMESH::long_array_var _idArray;
5377 const SMDS_Mesh* _mesh;
5378 const SMDSAbs_ElementType _type;
5379 const SMDS_MeshElement* _elem;
5381 IDSourceIterator( const SMDS_Mesh* mesh,
5382 const CORBA::Long* ids,
5384 SMDSAbs_ElementType type):
5385 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5387 if ( _idPtr && nbIds && _mesh )
5390 IDSourceIterator( const SMDS_Mesh* mesh,
5391 SMESH::long_array* idArray,
5392 SMDSAbs_ElementType type):
5393 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5395 if ( idArray && _mesh )
5397 _idPtr = &_idArray[0];
5398 _idEndPtr = _idPtr + _idArray->length();
5406 virtual const SMDS_MeshElement* next()
5408 const SMDS_MeshElement* res = _elem;
5410 while ( _idPtr < _idEndPtr && !_elem )
5412 if ( _type == SMDSAbs_Node )
5414 _elem = _mesh->FindNode( *_idPtr++ );
5416 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5417 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5425 //-----------------------------------------------------------------------------
5427 struct NodeOfElemIterator : public SMDS_ElemIterator
5429 TColStd_MapOfInteger _checkedNodeIDs;
5430 SMDS_ElemIteratorPtr _elemIter;
5431 SMDS_ElemIteratorPtr _nodeIter;
5432 const SMDS_MeshElement* _node;
5434 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5436 if ( _elemIter && _elemIter->more() )
5438 _nodeIter = _elemIter->next()->nodesIterator();
5446 virtual const SMDS_MeshElement* next()
5448 const SMDS_MeshElement* res = _node;
5450 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5452 if ( _nodeIter->more() )
5454 _node = _nodeIter->next();
5455 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5460 _nodeIter = _elemIter->next()->nodesIterator();
5468 //=============================================================================
5470 * Return iterator on elements of given type in given object
5472 //=============================================================================
5474 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5475 SMESH::ElementType theType)
5477 SMDS_ElemIteratorPtr elemIt;
5478 bool typeOK = ( theType == SMESH::ALL );
5479 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5481 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5482 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5483 if ( !mesh_i ) return elemIt;
5484 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5486 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5488 elemIt = meshDS->elementsIterator( elemType );
5491 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5493 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5496 elemIt = sm->GetElements();
5497 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5499 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5500 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5504 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5506 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5507 if ( groupDS && ( elemType == groupDS->GetType() ||
5508 elemType == SMDSAbs_Node ||
5509 elemType == SMDSAbs_All ))
5511 elemIt = groupDS->GetElements();
5512 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5515 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5517 if ( filter_i->GetElementType() == theType ||
5518 elemType == SMDSAbs_Node ||
5519 elemType == SMDSAbs_All)
5521 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5522 if ( pred_i && pred_i->GetPredicate() )
5524 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5525 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5526 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5527 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5533 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5534 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5535 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5537 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5540 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5541 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5545 SMESH::long_array_var ids = theObject->GetIDs();
5546 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5548 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5551 if ( elemIt && elemIt->more() && !typeOK )
5553 if ( elemType == SMDSAbs_Node )
5555 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5559 elemIt = SMDS_ElemIteratorPtr();
5565 //=============================================================================
5566 namespace // Finding concurrent hypotheses
5567 //=============================================================================
5571 * \brief mapping of mesh dimension into shape type
5573 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5575 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5577 case 0: aType = TopAbs_VERTEX; break;
5578 case 1: aType = TopAbs_EDGE; break;
5579 case 2: aType = TopAbs_FACE; break;
5581 default:aType = TopAbs_SOLID; break;
5586 //-----------------------------------------------------------------------------
5588 * \brief Internal structure used to find concurent submeshes
5590 * It represents a pair < submesh, concurent dimension >, where
5591 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5592 * with another submesh. In other words, it is dimension of a hypothesis assigned
5599 int _dim; //!< a dimension the algo can build (concurrent dimension)
5600 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5601 TopTools_MapOfShape _shapeMap;
5602 SMESH_subMesh* _subMesh;
5603 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5605 //-----------------------------------------------------------------------------
5606 // Return the algorithm
5607 const SMESH_Algo* GetAlgo() const
5608 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5610 //-----------------------------------------------------------------------------
5612 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5614 const TopoDS_Shape& theShape)
5616 _subMesh = (SMESH_subMesh*)theSubMesh;
5617 SetShape( theDim, theShape );
5620 //-----------------------------------------------------------------------------
5622 void SetShape(const int theDim,
5623 const TopoDS_Shape& theShape)
5626 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5627 if (_dim >= _ownDim)
5628 _shapeMap.Add( theShape );
5630 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5631 for( ; anExp.More(); anExp.Next() )
5632 _shapeMap.Add( anExp.Current() );
5636 //-----------------------------------------------------------------------------
5637 //! Check sharing of sub-shapes
5638 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5639 const TopTools_MapOfShape& theToFind,
5640 const TopAbs_ShapeEnum theType)
5642 bool isShared = false;
5643 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5644 for (; !isShared && anItr.More(); anItr.Next() )
5646 const TopoDS_Shape aSubSh = anItr.Key();
5647 // check for case when concurrent dimensions are same
5648 isShared = theToFind.Contains( aSubSh );
5649 // check for sub-shape with concurrent dimension
5650 TopExp_Explorer anExp( aSubSh, theType );
5651 for ( ; !isShared && anExp.More(); anExp.Next() )
5652 isShared = theToFind.Contains( anExp.Current() );
5657 //-----------------------------------------------------------------------------
5658 //! check algorithms
5659 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5660 const SMESHDS_Hypothesis* theA2)
5662 if ( !theA1 || !theA2 ||
5663 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5664 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5665 return false; // one of the hypothesis is not algorithm
5666 // check algorithm names (should be equal)
5667 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5671 //-----------------------------------------------------------------------------
5672 //! Check if sub-shape hypotheses are concurrent
5673 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5675 if ( _subMesh == theOther->_subMesh )
5676 return false; // same sub-shape - should not be
5678 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5679 // any of the two submeshes is not on COMPOUND shape )
5680 // -> no concurrency
5681 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5682 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5683 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5684 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5685 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5688 // bool checkSubShape = ( _dim >= theOther->_dim )
5689 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5690 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5691 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5692 if ( !checkSubShape )
5695 // check algorithms to be same
5696 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5697 return true; // different algorithms -> concurrency !
5699 // check hypothesises for concurrence (skip first as algorithm)
5701 // pointers should be same, because it is referened from mesh hypothesis partition
5702 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5703 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5704 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5705 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5707 // the submeshes are concurrent if their algorithms has different parameters
5708 return nbSame != (int)theOther->_hypotheses.size() - 1;
5711 // Return true if algorithm of this SMESH_DimHyp is used if no
5712 // sub-mesh order is imposed by the user
5713 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5715 // NeedDiscreteBoundary() algo has a higher priority
5716 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5717 theOther->GetAlgo()->NeedDiscreteBoundary() )
5718 return !this->GetAlgo()->NeedDiscreteBoundary();
5720 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5723 }; // end of SMESH_DimHyp
5724 //-----------------------------------------------------------------------------
5726 typedef list<const SMESH_DimHyp*> TDimHypList;
5728 //-----------------------------------------------------------------------------
5730 void addDimHypInstance(const int theDim,
5731 const TopoDS_Shape& theShape,
5732 const SMESH_Algo* theAlgo,
5733 const SMESH_subMesh* theSubMesh,
5734 const list <const SMESHDS_Hypothesis*>& theHypList,
5735 TDimHypList* theDimHypListArr )
5737 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5738 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5739 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5740 dimHyp->_hypotheses.push_front(theAlgo);
5741 listOfdimHyp.push_back( dimHyp );
5744 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5745 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5746 theHypList.begin(), theHypList.end() );
5749 //-----------------------------------------------------------------------------
5750 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5751 TDimHypList& theListOfConcurr)
5753 if ( theListOfConcurr.empty() )
5755 theListOfConcurr.push_back( theDimHyp );
5759 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5760 while ( hypIt != theListOfConcurr.end() &&
5761 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5763 theListOfConcurr.insert( hypIt, theDimHyp );
5767 //-----------------------------------------------------------------------------
5768 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5769 const TDimHypList& theListOfDimHyp,
5770 TDimHypList& theListOfConcurrHyp,
5771 set<int>& theSetOfConcurrId )
5773 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5774 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5776 const SMESH_DimHyp* curDimHyp = *rIt;
5777 if ( curDimHyp == theDimHyp )
5778 break; // meet own dimHyp pointer in same dimension
5780 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5781 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5783 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5788 //-----------------------------------------------------------------------------
5789 void unionLists(TListOfInt& theListOfId,
5790 TListOfListOfInt& theListOfListOfId,
5793 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5794 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5796 continue; //skip already treated lists
5797 // check if other list has any same submesh object
5798 TListOfInt& otherListOfId = *it;
5799 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5800 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5803 // union two lists (from source into target)
5804 TListOfInt::iterator it2 = otherListOfId.begin();
5805 for ( ; it2 != otherListOfId.end(); it2++ ) {
5806 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5807 theListOfId.push_back(*it2);
5809 // clear source list
5810 otherListOfId.clear();
5813 //-----------------------------------------------------------------------------
5815 //! free memory allocated for dimension-hypothesis objects
5816 void removeDimHyps( TDimHypList* theArrOfList )
5818 for (int i = 0; i < 4; i++ ) {
5819 TDimHypList& listOfdimHyp = theArrOfList[i];
5820 TDimHypList::const_iterator it = listOfdimHyp.begin();
5821 for ( ; it != listOfdimHyp.end(); it++ )
5826 //-----------------------------------------------------------------------------
5828 * \brief find common submeshes with given submesh
5829 * \param theSubMeshList list of already collected submesh to check
5830 * \param theSubMesh given submesh to intersect with other
5831 * \param theCommonSubMeshes collected common submeshes
5833 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5834 const SMESH_subMesh* theSubMesh,
5835 set<const SMESH_subMesh*>& theCommon )
5839 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5840 for ( ; it != theSubMeshList.end(); it++ )
5841 theSubMesh->FindIntersection( *it, theCommon );
5842 theSubMeshList.push_back( theSubMesh );
5843 //theCommon.insert( theSubMesh );
5846 //-----------------------------------------------------------------------------
5847 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5849 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5850 for ( ; listsIt != smLists.end(); ++listsIt )
5852 const TListOfInt& smIDs = *listsIt;
5853 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5861 //=============================================================================
5863 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5865 //=============================================================================
5867 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5869 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5870 if ( isSubMeshInList( submeshID, anOrder ))
5873 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5874 return isSubMeshInList( submeshID, allConurrent );
5877 //=============================================================================
5879 * \brief Return submesh objects list in meshing order
5881 //=============================================================================
5883 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5885 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5887 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5889 return aResult._retn();
5891 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5892 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5893 anOrder.splice( anOrder.end(), allConurrent );
5896 TListOfListOfInt::iterator listIt = anOrder.begin();
5897 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5898 unionLists( *listIt, anOrder, listIndx + 1 );
5900 // convert submesh ids into interface instances
5901 // and dump command into python
5902 convertMeshOrder( anOrder, aResult, false );
5904 return aResult._retn();
5907 //=============================================================================
5909 * \brief Finds concurrent sub-meshes
5911 //=============================================================================
5913 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5915 TListOfListOfInt anOrder;
5916 ::SMESH_Mesh& mesh = GetImpl();
5918 // collect submeshes and detect concurrent algorithms and hypothesises
5919 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5921 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5922 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5923 ::SMESH_subMesh* sm = (*i_sm).second;
5925 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5927 // list of assigned hypothesises
5928 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5929 // Find out dimensions where the submesh can be concurrent.
5930 // We define the dimensions by algo of each of hypotheses in hypList
5931 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5932 for( ; hypIt != hypList.end(); hypIt++ ) {
5933 SMESH_Algo* anAlgo = 0;
5934 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5935 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5936 // hyp it-self is algo
5937 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5939 // try to find algorithm with help of sub-shapes
5940 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5941 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5942 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5945 continue; // no algorithm assigned to a current submesh
5947 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5948 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5950 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5951 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5952 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5954 } // end iterations on submesh
5956 // iterate on created dimension-hypotheses and check for concurrents
5957 for ( int i = 0; i < 4; i++ ) {
5958 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5959 // check for concurrents in own and other dimensions (step-by-step)
5960 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5961 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5962 const SMESH_DimHyp* dimHyp = *dhIt;
5963 TDimHypList listOfConcurr;
5964 set<int> setOfConcurrIds;
5965 // looking for concurrents and collect into own list
5966 for ( int j = i; j < 4; j++ )
5967 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5968 // check if any concurrents found
5969 if ( listOfConcurr.size() > 0 ) {
5970 // add own submesh to list of concurrent
5971 addInOrderOfPriority( dimHyp, listOfConcurr );
5972 list<int> listOfConcurrIds;
5973 TDimHypList::iterator hypIt = listOfConcurr.begin();
5974 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5975 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5976 anOrder.push_back( listOfConcurrIds );
5981 removeDimHyps(dimHypListArr);
5983 // now, minimise the number of concurrent groups
5984 // Here we assume that lists of submeshes can have same submesh
5985 // in case of multi-dimension algorithms, as result
5986 // list with common submesh has to be united into one list
5988 TListOfListOfInt::iterator listIt = anOrder.begin();
5989 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5990 unionLists( *listIt, anOrder, listIndx + 1 );
5996 //=============================================================================
5998 * \brief Set submesh object order
5999 * \param theSubMeshArray submesh array order
6001 //=============================================================================
6003 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6006 _preMeshInfo->ForgetOrLoad();
6009 ::SMESH_Mesh& mesh = GetImpl();
6011 TPythonDump aPythonDump; // prevent dump of called methods
6012 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6014 TListOfListOfInt subMeshOrder;
6015 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6017 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6018 TListOfInt subMeshIds;
6020 aPythonDump << ", ";
6021 aPythonDump << "[ ";
6022 // Collect subMeshes which should be clear
6023 // do it list-by-list, because modification of submesh order
6024 // take effect between concurrent submeshes only
6025 set<const SMESH_subMesh*> subMeshToClear;
6026 list<const SMESH_subMesh*> subMeshList;
6027 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6029 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6031 aPythonDump << ", ";
6032 aPythonDump << subMesh;
6033 subMeshIds.push_back( subMesh->GetId() );
6034 // detect common parts of submeshes
6035 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6036 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6038 aPythonDump << " ]";
6039 subMeshOrder.push_back( subMeshIds );
6041 // clear collected submeshes
6042 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6043 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6044 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6045 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6047 aPythonDump << " ])";
6049 mesh.SetMeshOrder( subMeshOrder );
6055 //=============================================================================
6057 * \brief Convert submesh ids into submesh interfaces
6059 //=============================================================================
6061 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6062 SMESH::submesh_array_array& theResOrder,
6063 const bool theIsDump)
6065 int nbSet = theIdsOrder.size();
6066 TPythonDump aPythonDump; // prevent dump of called methods
6068 aPythonDump << "[ ";
6069 theResOrder.length(nbSet);
6070 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6072 for( ; it != theIdsOrder.end(); it++ ) {
6073 // translate submesh identificators into submesh objects
6074 // takeing into account real number of concurrent lists
6075 const TListOfInt& aSubOrder = (*it);
6076 if (!aSubOrder.size())
6079 aPythonDump << "[ ";
6080 // convert shape indeces into interfaces
6081 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6082 aResSubSet->length(aSubOrder.size());
6083 TListOfInt::const_iterator subIt = aSubOrder.begin();
6085 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6086 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6088 SMESH::SMESH_subMesh_var subMesh =
6089 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6092 aPythonDump << ", ";
6093 aPythonDump << subMesh;
6095 aResSubSet[ j++ ] = subMesh;
6098 aPythonDump << " ]";
6100 theResOrder[ listIndx++ ] = aResSubSet;
6102 // correct number of lists
6103 theResOrder.length( listIndx );
6106 // finilise python dump
6107 aPythonDump << " ]";
6108 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6112 //================================================================================
6114 // Implementation of SMESH_MeshPartDS
6116 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6117 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6119 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6120 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6123 _meshDS = mesh_i->GetImpl().GetMeshDS();
6125 SetPersistentId( _meshDS->GetPersistentId() );
6127 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6129 // <meshPart> is the whole mesh
6130 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6132 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6133 myGroupSet = _meshDS->GetGroups();
6138 SMESH::long_array_var anIDs = meshPart->GetIDs();
6139 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6140 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6142 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6143 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6144 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6149 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6150 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6151 if ( _elements[ e->GetType() ].insert( e ).second )
6154 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6155 while ( nIt->more() )
6157 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6158 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6165 ShapeToMesh( _meshDS->ShapeToMesh() );
6167 _meshDS = 0; // to enforce iteration on _elements and _nodes
6170 // -------------------------------------------------------------------------------------
6171 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6172 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6175 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6176 for ( ; partIt != meshPart.end(); ++partIt )
6177 if ( const SMDS_MeshElement * e = *partIt )
6178 if ( _elements[ e->GetType() ].insert( e ).second )
6181 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6182 while ( nIt->more() )
6184 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6185 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6191 // -------------------------------------------------------------------------------------
6192 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6194 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6196 TElemID elem( IDelem );
6197 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6198 if ( !_elements[ iType ].empty() )
6200 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6201 if ( it != _elements[ iType ].end() )
6206 // -------------------------------------------------------------------------------------
6207 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6209 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6211 typedef SMDS_SetIterator
6212 <const SMDS_MeshElement*,
6213 TIDSortedElemSet::const_iterator,
6214 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6215 SMDS_MeshElement::GeomFilter
6218 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6220 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6221 _elements[type].end(),
6222 SMDS_MeshElement::GeomFilter( geomType )));
6224 // -------------------------------------------------------------------------------------
6225 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6227 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6229 typedef SMDS_SetIterator
6230 <const SMDS_MeshElement*,
6231 TIDSortedElemSet::const_iterator,
6232 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6233 SMDS_MeshElement::EntityFilter
6236 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6238 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6239 _elements[type].end(),
6240 SMDS_MeshElement::EntityFilter( entity )));
6242 // -------------------------------------------------------------------------------------
6243 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6245 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6246 if ( type == SMDSAbs_All && !_meshDS )
6248 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6250 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6251 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6253 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6255 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6256 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6258 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6259 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6261 // -------------------------------------------------------------------------------------
6262 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6263 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6265 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6266 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6267 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6269 // -------------------------------------------------------------------------------------
6270 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6271 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6272 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6273 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6274 #undef _GET_ITER_DEFINE
6276 // END Implementation of SMESH_MeshPartDS
6278 //================================================================================