1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 : SALOME::GenericObj_i( thePOA )
114 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cached shapes if no more meshes remain; (the cache is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
243 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
244 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
250 catch(SALOME_Exception & S_ex) {
251 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
253 return aShapeObj._retn();
256 //================================================================================
258 * \brief Return false if the mesh is not yet fully loaded from the study file
260 //================================================================================
262 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
265 return !_preMeshInfo;
268 //================================================================================
270 * \brief Load full mesh data from the study file
272 //================================================================================
274 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->FullLoadFromFile();
281 //================================================================================
283 * \brief Remove all nodes and elements
285 //================================================================================
287 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
295 //CheckGeomGroupModif(); // issue 20145
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
301 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
303 SMESH::SMESH_Mesh_var mesh = _this();
304 _gen_i->UpdateIcons( mesh );
307 //================================================================================
309 * \brief Remove all nodes and elements for indicated shape
311 //================================================================================
313 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
314 throw (SALOME::SALOME_Exception)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Imports mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
393 throw ( SALOME::SALOME_Exception )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 major = minor = release = 0;
411 MED::GetMEDVersion(theFileName, major, minor, release);
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Imports mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
432 throw ( SALOME::SALOME_Exception )
434 Unexpect aCatch(SALOME_SalomeException);
437 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
439 catch( SALOME_Exception& S_ex ) {
440 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
446 CreateGroupServants();
448 _medFileInfo = new SMESH::MedFileInfo();
449 _medFileInfo->fileName = theFileName;
450 _medFileInfo->major = 0;
451 _medFileInfo->minor = 0;
452 _medFileInfo->release = 0;
453 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
455 return ConvertDriverMEDReadStatus(status);
458 //================================================================================
460 * \brief Return string representation of a MED file version comprising nbDigits
462 //================================================================================
464 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
466 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
468 return CORBA::string_dup( ver.c_str() );
471 //=============================================================================
475 * Imports mesh data from MED file
477 //=============================================================================
479 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->UNVToMesh( theFileName );
487 CreateGroupServants();
489 _medFileInfo = new SMESH::MedFileInfo();
490 _medFileInfo->fileName = theFileName;
491 _medFileInfo->major = 0;
492 _medFileInfo->minor = 0;
493 _medFileInfo->release = 0;
494 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
496 SMESH_CATCH( SMESH::throwCorbaException );
501 //=============================================================================
505 * Imports mesh data from STL file
507 //=============================================================================
508 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
509 throw ( SALOME::SALOME_Exception )
513 // Read mesh with name = <theMeshName> into SMESH_Mesh
514 std::string name = _impl->STLToMesh( theFileName );
517 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
518 _gen_i->SetName( meshSO, name.c_str() );
520 _medFileInfo = new SMESH::MedFileInfo();
521 _medFileInfo->fileName = theFileName;
522 _medFileInfo->major = 0;
523 _medFileInfo->minor = 0;
524 _medFileInfo->release = 0;
525 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
527 SMESH_CATCH( SMESH::throwCorbaException );
532 //================================================================================
534 * \brief Function used in SMESH_CATCH by ImportGMFFile()
536 //================================================================================
540 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
542 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
546 //================================================================================
548 * \brief Imports data from a GMF file and returns an error description
550 //================================================================================
552 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
553 bool theMakeRequiredGroups )
554 throw (SALOME::SALOME_Exception)
556 SMESH_ComputeErrorPtr error;
559 #define SMESH_CAUGHT error =
562 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
564 _medFileInfo = new SMESH::MedFileInfo();
565 _medFileInfo->fileName = theFileName;
566 _medFileInfo->major = 0;
567 _medFileInfo->minor = 0;
568 _medFileInfo->release = 0;
569 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
571 SMESH_CATCH( exceptionToComputeError );
575 CreateGroupServants();
577 return ConvertComputeError( error );
580 //=============================================================================
584 //=============================================================================
586 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
588 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
589 (SMESH_Hypothesis::Hypothesis_Status theStatus)
592 RETURNCASE( HYP_OK );
593 RETURNCASE( HYP_MISSING );
594 RETURNCASE( HYP_CONCURRENT );
595 RETURNCASE( HYP_BAD_PARAMETER );
596 RETURNCASE( HYP_HIDDEN_ALGO );
597 RETURNCASE( HYP_HIDING_ALGO );
598 RETURNCASE( HYP_UNKNOWN_FATAL );
599 RETURNCASE( HYP_INCOMPATIBLE );
600 RETURNCASE( HYP_NOTCONFORM );
601 RETURNCASE( HYP_ALREADY_EXIST );
602 RETURNCASE( HYP_BAD_DIM );
603 RETURNCASE( HYP_BAD_SUBSHAPE );
604 RETURNCASE( HYP_BAD_GEOMETRY );
605 RETURNCASE( HYP_NEED_SHAPE );
606 RETURNCASE( HYP_INCOMPAT_HYPS );
609 return SMESH::HYP_UNKNOWN_FATAL;
612 //=============================================================================
616 * calls internal addHypothesis() and then adds a reference to <anHyp> under
617 * the SObject actually having a reference to <aSubShape>.
618 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
620 //=============================================================================
622 SMESH::Hypothesis_Status
623 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
624 SMESH::SMESH_Hypothesis_ptr anHyp,
625 CORBA::String_out anErrorText)
626 throw(SALOME::SALOME_Exception)
628 Unexpect aCatch(SALOME_SalomeException);
630 _preMeshInfo->ForgetOrLoad();
633 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
634 anErrorText = error.c_str();
636 SMESH::SMESH_Mesh_var mesh( _this() );
637 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
639 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
640 _gen_i->UpdateIcons( mesh );
642 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
644 // Update Python script
645 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
646 << aSubShape << ", " << anHyp << " )";
648 return ConvertHypothesisStatus(status);
651 //=============================================================================
655 //=============================================================================
657 SMESH_Hypothesis::Hypothesis_Status
658 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
659 SMESH::SMESH_Hypothesis_ptr anHyp,
660 std::string* anErrorText)
662 if(MYDEBUG) MESSAGE("addHypothesis");
664 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
665 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
667 if (CORBA::is_nil( anHyp ))
668 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
670 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
673 TopoDS_Shape myLocSubShape;
674 //use PseudoShape in case if mesh has no shape
676 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
678 myLocSubShape = _impl->GetShapeToMesh();
680 const int hypId = anHyp->GetId();
682 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
683 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
685 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
687 // assure there is a corresponding submesh
688 if ( !_impl->IsMainShape( myLocSubShape )) {
689 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
690 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
691 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
694 else if ( anErrorText )
696 *anErrorText = error;
699 catch(SALOME_Exception & S_ex)
701 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
706 //=============================================================================
710 //=============================================================================
712 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
713 SMESH::SMESH_Hypothesis_ptr anHyp)
714 throw(SALOME::SALOME_Exception)
716 Unexpect aCatch(SALOME_SalomeException);
718 _preMeshInfo->ForgetOrLoad();
720 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
721 SMESH::SMESH_Mesh_var mesh = _this();
723 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
725 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
726 _gen_i->UpdateIcons( mesh );
728 // Update Python script
729 if(_impl->HasShapeToMesh())
730 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
731 << aSubShape << ", " << anHyp << " )";
733 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
736 return ConvertHypothesisStatus(status);
739 //=============================================================================
743 //=============================================================================
745 SMESH_Hypothesis::Hypothesis_Status
746 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
747 SMESH::SMESH_Hypothesis_ptr anHyp)
749 if(MYDEBUG) MESSAGE("removeHypothesis()");
751 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
752 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
754 if (CORBA::is_nil( anHyp ))
755 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
757 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
760 TopoDS_Shape myLocSubShape;
761 //use PseudoShape in case if mesh has no shape
762 if( _impl->HasShapeToMesh() )
763 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
765 myLocSubShape = _impl->GetShapeToMesh();
767 const int hypId = anHyp->GetId();
768 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
769 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
771 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
775 catch(SALOME_Exception & S_ex)
777 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
782 //=============================================================================
786 //=============================================================================
788 SMESH::ListOfHypothesis *
789 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
790 throw(SALOME::SALOME_Exception)
792 Unexpect aCatch(SALOME_SalomeException);
793 if (MYDEBUG) MESSAGE("GetHypothesisList");
794 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
795 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
797 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
800 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
801 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
802 myLocSubShape = _impl->GetShapeToMesh();
803 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
804 int i = 0, n = aLocalList.size();
807 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
808 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
809 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
811 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
812 if ( id_hypptr != _mapHypo.end() )
813 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
817 catch(SALOME_Exception & S_ex) {
818 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
821 return aList._retn();
824 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
826 Unexpect aCatch(SALOME_SalomeException);
827 if (MYDEBUG) MESSAGE("GetSubMeshes");
829 SMESH::submesh_array_var aList = new SMESH::submesh_array();
832 TPythonDump aPythonDump;
833 if ( !_mapSubMeshIor.empty() )
837 aList->length( _mapSubMeshIor.size() );
839 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
840 for ( ; it != _mapSubMeshIor.end(); it++ ) {
841 if ( CORBA::is_nil( it->second )) continue;
842 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
844 if (i > 1) aPythonDump << ", ";
845 aPythonDump << it->second;
849 catch(SALOME_Exception & S_ex) {
850 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
853 // Update Python script
854 if ( !_mapSubMeshIor.empty() )
855 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
857 return aList._retn();
860 //=============================================================================
864 //=============================================================================
866 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
867 const char* theName )
868 throw(SALOME::SALOME_Exception)
870 Unexpect aCatch(SALOME_SalomeException);
871 if (CORBA::is_nil(aSubShape))
872 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
874 SMESH::SMESH_subMesh_var subMesh;
875 SMESH::SMESH_Mesh_var aMesh = _this();
877 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
879 //Get or Create the SMESH_subMesh object implementation
881 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
883 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
885 TopoDS_Iterator it( myLocSubShape );
887 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
889 subMesh = getSubMesh( subMeshId );
891 // create a new subMesh object servant if there is none for the shape
892 if ( subMesh->_is_nil() )
893 subMesh = createSubMesh( aSubShape );
894 if ( _gen_i->CanPublishInStudy( subMesh ))
896 SALOMEDS::SObject_wrap aSO =
897 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
898 if ( !aSO->_is_nil()) {
899 // Update Python script
900 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
901 << aSubShape << ", '" << theName << "' )";
905 catch(SALOME_Exception & S_ex) {
906 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
908 return subMesh._retn();
911 //=============================================================================
915 //=============================================================================
917 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
918 throw (SALOME::SALOME_Exception)
922 if ( theSubMesh->_is_nil() )
925 GEOM::GEOM_Object_var aSubShape;
926 // Remove submesh's SObject
927 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
928 if ( !anSO->_is_nil() ) {
929 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
930 SALOMEDS::SObject_wrap anObj, aRef;
931 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
932 anObj->ReferencedObject( aRef.inout() ))
934 CORBA::Object_var obj = aRef->GetObject();
935 aSubShape = GEOM::GEOM_Object::_narrow( obj );
937 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
938 // aSubShape = theSubMesh->GetSubShape();
940 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
941 builder->RemoveObjectWithChildren( anSO );
943 // Update Python script
944 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
947 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
949 _preMeshInfo->ForgetOrLoad();
951 SMESH_CATCH( SMESH::throwCorbaException );
954 //=============================================================================
958 //=============================================================================
960 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
961 const char* theName )
962 throw(SALOME::SALOME_Exception)
964 Unexpect aCatch(SALOME_SalomeException);
966 _preMeshInfo->FullLoadFromFile();
968 SMESH::SMESH_Group_var aNewGroup =
969 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
971 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
973 SMESH::SMESH_Mesh_var mesh = _this();
974 SALOMEDS::SObject_wrap aSO =
975 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
976 if ( !aSO->_is_nil())
977 // Update Python script
978 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
979 << theElemType << ", '" << theName << "' )";
981 return aNewGroup._retn();
984 //=============================================================================
988 //=============================================================================
989 SMESH::SMESH_GroupOnGeom_ptr
990 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
992 GEOM::GEOM_Object_ptr theGeomObj)
993 throw(SALOME::SALOME_Exception)
995 Unexpect aCatch(SALOME_SalomeException);
997 _preMeshInfo->FullLoadFromFile();
999 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1001 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1002 if ( !aShape.IsNull() )
1005 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
1007 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1009 SMESH::SMESH_Mesh_var mesh = _this();
1010 SALOMEDS::SObject_wrap aSO =
1011 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1012 if ( !aSO->_is_nil())
1013 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1014 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1018 return aNewGroup._retn();
1021 //================================================================================
1023 * \brief Creates a group whose contents is defined by filter
1024 * \param theElemType - group type
1025 * \param theName - group name
1026 * \param theFilter - the filter
1027 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1029 //================================================================================
1031 SMESH::SMESH_GroupOnFilter_ptr
1032 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1033 const char* theName,
1034 SMESH::Filter_ptr theFilter )
1035 throw (SALOME::SALOME_Exception)
1037 Unexpect aCatch(SALOME_SalomeException);
1039 _preMeshInfo->FullLoadFromFile();
1041 if ( CORBA::is_nil( theFilter ))
1042 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1044 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1046 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1048 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1049 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1052 if ( !aNewGroup->_is_nil() )
1053 aNewGroup->SetFilter( theFilter );
1055 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1057 SMESH::SMESH_Mesh_var mesh = _this();
1058 SALOMEDS::SObject_wrap aSO =
1059 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1061 if ( !aSO->_is_nil())
1062 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1063 << theElemType << ", '" << theName << "', " << theFilter << " )";
1065 return aNewGroup._retn();
1068 //=============================================================================
1072 //=============================================================================
1074 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1075 throw (SALOME::SALOME_Exception)
1077 if ( theGroup->_is_nil() )
1082 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1086 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1087 if ( !aGroupSO->_is_nil() )
1089 // Update Python script
1090 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1092 // Remove group's SObject
1093 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1094 builder->RemoveObjectWithChildren( aGroupSO );
1096 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1098 // Remove the group from SMESH data structures
1099 removeGroup( aGroup->GetLocalID() );
1101 SMESH_CATCH( SMESH::throwCorbaException );
1104 //=============================================================================
1106 * Remove group with its contents
1108 //=============================================================================
1110 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1111 throw (SALOME::SALOME_Exception)
1115 _preMeshInfo->FullLoadFromFile();
1117 if ( theGroup->_is_nil() )
1120 vector<int> nodeIds; // to remove nodes becoming free
1121 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1122 if ( !isNodal && !theGroup->IsEmpty() )
1124 CORBA::Long elemID = theGroup->GetID( 1 );
1125 int nbElemNodes = GetElemNbNodes( elemID );
1126 if ( nbElemNodes > 0 )
1127 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1130 // Retrieve contents
1131 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1132 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1133 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1134 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1135 elems.assign( elemBeg, elemEnd );
1137 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1140 RemoveGroup( theGroup );
1143 for ( size_t i = 0; i < elems.size(); ++i )
1145 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1149 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1150 nodeIds.push_back( nIt->next()->GetID() );
1152 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1156 _impl->GetMeshDS()->RemoveElement( elems[i] );
1160 // Remove free nodes
1161 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1162 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1163 if ( n->NbInverseElements() == 0 )
1164 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1166 // Update Python script (theGroup must be alive for this)
1167 pyDump << SMESH::SMESH_Mesh_var(_this())
1168 << ".RemoveGroupWithContents( " << theGroup << " )";
1170 SMESH_CATCH( SMESH::throwCorbaException );
1173 //================================================================================
1175 * \brief Get the list of groups existing in the mesh
1176 * \retval SMESH::ListOfGroups * - list of groups
1178 //================================================================================
1180 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1182 Unexpect aCatch(SALOME_SalomeException);
1183 if (MYDEBUG) MESSAGE("GetGroups");
1185 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1188 TPythonDump aPythonDump;
1189 if ( !_mapGroups.empty() )
1191 aPythonDump << "[ ";
1193 aList->length( _mapGroups.size() );
1195 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1196 for ( ; it != _mapGroups.end(); it++ ) {
1197 if ( CORBA::is_nil( it->second )) continue;
1198 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1200 if (i > 1) aPythonDump << ", ";
1201 aPythonDump << it->second;
1205 catch(SALOME_Exception & S_ex) {
1206 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1208 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1210 return aList._retn();
1213 //=============================================================================
1215 * Get number of groups existing in the mesh
1217 //=============================================================================
1219 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1221 Unexpect aCatch(SALOME_SalomeException);
1222 return _mapGroups.size();
1225 //=============================================================================
1227 * New group including all mesh elements present in initial groups is created.
1229 //=============================================================================
1231 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1232 SMESH::SMESH_GroupBase_ptr theGroup2,
1233 const char* theName )
1234 throw (SALOME::SALOME_Exception)
1236 SMESH::SMESH_Group_var aResGrp;
1240 _preMeshInfo->FullLoadFromFile();
1242 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1243 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1245 if ( theGroup1->GetType() != theGroup2->GetType() )
1246 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1251 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1252 if ( aResGrp->_is_nil() )
1253 return SMESH::SMESH_Group::_nil();
1255 aResGrp->AddFrom( theGroup1 );
1256 aResGrp->AddFrom( theGroup2 );
1258 // Update Python script
1259 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1260 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1262 SMESH_CATCH( SMESH::throwCorbaException );
1264 return aResGrp._retn();
1267 //=============================================================================
1269 * \brief New group including all mesh elements present in initial groups is created.
1270 * \param theGroups list of groups
1271 * \param theName name of group to be created
1272 * \return pointer to the new group
1274 //=============================================================================
1276 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1277 const char* theName )
1278 throw (SALOME::SALOME_Exception)
1280 SMESH::SMESH_Group_var aResGrp;
1283 _preMeshInfo->FullLoadFromFile();
1286 return SMESH::SMESH_Group::_nil();
1291 SMESH::ElementType aType = SMESH::ALL;
1292 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1294 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1295 if ( CORBA::is_nil( aGrp ) )
1297 if ( aType == SMESH::ALL )
1298 aType = aGrp->GetType();
1299 else if ( aType != aGrp->GetType() )
1300 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1303 if ( aType == SMESH::ALL )
1304 return SMESH::SMESH_Group::_nil();
1309 aResGrp = CreateGroup( aType, theName );
1310 if ( aResGrp->_is_nil() )
1311 return SMESH::SMESH_Group::_nil();
1313 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1314 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1316 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1317 if ( !CORBA::is_nil( aGrp ) )
1319 aResGrp->AddFrom( aGrp );
1320 if ( g > 0 ) pyDump << ", ";
1324 pyDump << " ], '" << theName << "' )";
1326 SMESH_CATCH( SMESH::throwCorbaException );
1328 return aResGrp._retn();
1331 //=============================================================================
1333 * New group is created. All mesh elements that are
1334 * present in both initial groups are added to the new one.
1336 //=============================================================================
1338 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1339 SMESH::SMESH_GroupBase_ptr theGroup2,
1340 const char* theName )
1341 throw (SALOME::SALOME_Exception)
1343 SMESH::SMESH_Group_var aResGrp;
1348 _preMeshInfo->FullLoadFromFile();
1350 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1351 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1353 if ( theGroup1->GetType() != theGroup2->GetType() )
1354 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1358 // Create Intersection
1359 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1360 if ( aResGrp->_is_nil() )
1361 return aResGrp._retn();
1363 SMESHDS_GroupBase* groupDS1 = 0;
1364 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1365 groupDS1 = grp_i->GetGroupDS();
1367 SMESHDS_GroupBase* groupDS2 = 0;
1368 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1369 groupDS2 = grp_i->GetGroupDS();
1371 SMESHDS_Group* resGroupDS = 0;
1372 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1373 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1375 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1377 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1378 while ( elemIt1->more() )
1380 const SMDS_MeshElement* e = elemIt1->next();
1381 if ( groupDS2->Contains( e ))
1382 resGroupDS->SMDSGroup().Add( e );
1385 // Update Python script
1386 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1387 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1389 SMESH_CATCH( SMESH::throwCorbaException );
1391 return aResGrp._retn();
1394 //=============================================================================
1396 \brief Intersect list of groups. New group is created. All mesh elements that
1397 are present in all initial groups simultaneously are added to the new one.
1398 \param theGroups list of groups
1399 \param theName name of group to be created
1400 \return pointer on the group
1402 //=============================================================================
1403 SMESH::SMESH_Group_ptr
1404 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1405 const char* theName )
1406 throw (SALOME::SALOME_Exception)
1408 SMESH::SMESH_Group_var aResGrp;
1413 _preMeshInfo->FullLoadFromFile();
1416 return SMESH::SMESH_Group::_nil();
1418 // check types and get SMESHDS_GroupBase's
1419 SMESH::ElementType aType = SMESH::ALL;
1420 vector< SMESHDS_GroupBase* > groupVec;
1421 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1423 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1424 if ( CORBA::is_nil( aGrp ) )
1426 if ( aType == SMESH::ALL )
1427 aType = aGrp->GetType();
1428 else if ( aType != aGrp->GetType() )
1429 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1432 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1433 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1435 if ( grpDS->IsEmpty() )
1440 groupVec.push_back( grpDS );
1443 if ( aType == SMESH::ALL ) // all groups are nil
1444 return SMESH::SMESH_Group::_nil();
1449 aResGrp = CreateGroup( aType, theName );
1451 SMESHDS_Group* resGroupDS = 0;
1452 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1453 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1454 if ( !resGroupDS || groupVec.empty() )
1455 return aResGrp._retn();
1458 size_t i, nb = groupVec.size();
1459 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1460 while ( elemIt1->more() )
1462 const SMDS_MeshElement* e = elemIt1->next();
1464 for ( i = 1; ( i < nb && inAll ); ++i )
1465 inAll = groupVec[i]->Contains( e );
1468 resGroupDS->SMDSGroup().Add( e );
1471 // Update Python script
1472 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1473 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1475 SMESH_CATCH( SMESH::throwCorbaException );
1477 return aResGrp._retn();
1480 //=============================================================================
1482 * New group is created. All mesh elements that are present in
1483 * a main group but is not present in a tool group are added to the new one
1485 //=============================================================================
1487 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1488 SMESH::SMESH_GroupBase_ptr theGroup2,
1489 const char* theName )
1490 throw (SALOME::SALOME_Exception)
1492 SMESH::SMESH_Group_var aResGrp;
1497 _preMeshInfo->FullLoadFromFile();
1499 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1500 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1502 if ( theGroup1->GetType() != theGroup2->GetType() )
1503 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1507 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1508 if ( aResGrp->_is_nil() )
1509 return aResGrp._retn();
1511 SMESHDS_GroupBase* groupDS1 = 0;
1512 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1513 groupDS1 = grp_i->GetGroupDS();
1515 SMESHDS_GroupBase* groupDS2 = 0;
1516 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1517 groupDS2 = grp_i->GetGroupDS();
1519 SMESHDS_Group* resGroupDS = 0;
1520 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1521 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1523 if ( groupDS1 && groupDS2 && resGroupDS )
1525 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1526 while ( elemIt1->more() )
1528 const SMDS_MeshElement* e = elemIt1->next();
1529 if ( !groupDS2->Contains( e ))
1530 resGroupDS->SMDSGroup().Add( e );
1533 // Update Python script
1534 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1535 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1537 SMESH_CATCH( SMESH::throwCorbaException );
1539 return aResGrp._retn();
1542 //=============================================================================
1544 \brief Cut lists of groups. New group is created. All mesh elements that are
1545 present in main groups but do not present in tool groups are added to the new one
1546 \param theMainGroups list of main groups
1547 \param theToolGroups list of tool groups
1548 \param theName name of group to be created
1549 \return pointer on the group
1551 //=============================================================================
1552 SMESH::SMESH_Group_ptr
1553 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1554 const SMESH::ListOfGroups& theToolGroups,
1555 const char* theName )
1556 throw (SALOME::SALOME_Exception)
1558 SMESH::SMESH_Group_var aResGrp;
1563 _preMeshInfo->FullLoadFromFile();
1566 return SMESH::SMESH_Group::_nil();
1568 // check types and get SMESHDS_GroupBase's
1569 SMESH::ElementType aType = SMESH::ALL;
1570 vector< SMESHDS_GroupBase* > toolGroupVec;
1571 vector< SMDS_ElemIteratorPtr > mainIterVec;
1573 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1575 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1576 if ( CORBA::is_nil( aGrp ) )
1578 if ( aType == SMESH::ALL )
1579 aType = aGrp->GetType();
1580 else if ( aType != aGrp->GetType() )
1581 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1583 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1584 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1585 if ( !grpDS->IsEmpty() )
1586 mainIterVec.push_back( grpDS->GetElements() );
1588 if ( aType == SMESH::ALL ) // all main groups are nil
1589 return SMESH::SMESH_Group::_nil();
1590 if ( mainIterVec.empty() ) // all main groups are empty
1591 return aResGrp._retn();
1593 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1595 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1596 if ( CORBA::is_nil( aGrp ) )
1598 if ( aType != aGrp->GetType() )
1599 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1601 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1602 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1603 toolGroupVec.push_back( grpDS );
1609 aResGrp = CreateGroup( aType, theName );
1611 SMESHDS_Group* resGroupDS = 0;
1612 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1613 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1615 return aResGrp._retn();
1618 size_t i, nb = toolGroupVec.size();
1619 SMDS_ElemIteratorPtr mainElemIt
1620 ( new SMDS_IteratorOnIterators
1621 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1622 while ( mainElemIt->more() )
1624 const SMDS_MeshElement* e = mainElemIt->next();
1626 for ( i = 0; ( i < nb && !isIn ); ++i )
1627 isIn = toolGroupVec[i]->Contains( e );
1630 resGroupDS->SMDSGroup().Add( e );
1633 // Update Python script
1634 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1635 << ".CutListOfGroups( " << theMainGroups << ", "
1636 << theToolGroups << ", '" << theName << "' )";
1638 SMESH_CATCH( SMESH::throwCorbaException );
1640 return aResGrp._retn();
1643 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1645 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1646 bool & toStopChecking )
1648 toStopChecking = ( nbCommon < nbChecked );
1649 return nbCommon == nbNodes;
1651 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1652 bool & toStopChecking )
1654 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1655 return nbCommon == nbCorners;
1657 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1658 bool & toStopChecking )
1660 return nbCommon > 0;
1662 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1663 bool & toStopChecking )
1665 return nbCommon >= (nbNodes+1) / 2;
1669 //=============================================================================
1671 * Create a group of entities basing on nodes of other groups.
1672 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1673 * \param [in] anElemType - a type of elements to include to the new group.
1674 * \param [in] theName - a name of the new group.
1675 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1676 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1677 * new group provided that it is based on nodes of an element of \a aListOfGroups
1678 * \return SMESH_Group - the created group
1680 // IMP 19939, bug 22010, IMP 22635
1681 //=============================================================================
1683 SMESH::SMESH_Group_ptr
1684 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1685 SMESH::ElementType theElemType,
1686 const char* theName,
1687 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1688 CORBA::Boolean theUnderlyingOnly)
1689 throw (SALOME::SALOME_Exception)
1691 SMESH::SMESH_Group_var aResGrp;
1695 _preMeshInfo->FullLoadFromFile();
1697 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1699 if ( !theName || !aMeshDS )
1700 return SMESH::SMESH_Group::_nil();
1702 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1704 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1705 SMESH_Comment nbCoNoStr( "SMESH.");
1706 switch ( theNbCommonNodes ) {
1707 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1708 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1709 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1710 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1711 default: return aResGrp._retn();
1713 int nbChecked, nbCommon, nbNodes, nbCorners;
1719 aResGrp = CreateGroup( theElemType, theName );
1720 if ( aResGrp->_is_nil() )
1721 return SMESH::SMESH_Group::_nil();
1723 SMESHDS_GroupBase* groupBaseDS =
1724 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1725 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1727 vector<bool> isNodeInGroups;
1729 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1731 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1732 if ( CORBA::is_nil( aGrp ) )
1734 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1735 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1738 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1739 if ( !elIt ) continue;
1741 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1743 while ( elIt->more() ) {
1744 const SMDS_MeshElement* el = elIt->next();
1745 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1746 while ( nIt->more() )
1747 resGroupCore.Add( nIt->next() );
1750 // get elements of theElemType based on nodes of every element of group
1751 else if ( theUnderlyingOnly )
1753 while ( elIt->more() )
1755 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1756 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1757 TIDSortedElemSet checkedElems;
1758 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1759 while ( nIt->more() )
1761 const SMDS_MeshNode* n = nIt->next();
1762 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1763 // check nodes of elements of theElemType around el
1764 while ( elOfTypeIt->more() )
1766 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1767 if ( !checkedElems.insert( elOfType ).second ) continue;
1768 nbNodes = elOfType->NbNodes();
1769 nbCorners = elOfType->NbCornerNodes();
1771 bool toStopChecking = false;
1772 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1773 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1774 if ( elNodes.count( nIt2->next() ) &&
1775 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1777 resGroupCore.Add( elOfType );
1784 // get all nodes of elements of groups
1787 while ( elIt->more() )
1789 const SMDS_MeshElement* el = elIt->next(); // an element of group
1790 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1791 while ( nIt->more() )
1793 const SMDS_MeshNode* n = nIt->next();
1794 if ( n->GetID() >= (int) isNodeInGroups.size() )
1795 isNodeInGroups.resize( n->GetID() + 1, false );
1796 isNodeInGroups[ n->GetID() ] = true;
1802 // Get elements of theElemType based on a certain number of nodes of elements of groups
1803 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1805 const SMDS_MeshNode* n;
1806 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1807 const int isNodeInGroupsSize = isNodeInGroups.size();
1808 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1810 if ( !isNodeInGroups[ iN ] ||
1811 !( n = aMeshDS->FindNode( iN )))
1814 // check nodes of elements of theElemType around n
1815 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1816 while ( elOfTypeIt->more() )
1818 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1819 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1824 nbNodes = elOfType->NbNodes();
1825 nbCorners = elOfType->NbCornerNodes();
1827 bool toStopChecking = false;
1828 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1829 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1831 const int nID = nIt->next()->GetID();
1832 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1833 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1835 resGroupCore.Add( elOfType );
1843 // Update Python script
1844 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1845 << ".CreateDimGroup( "
1846 << theGroups << ", " << theElemType << ", '" << theName << "', "
1847 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1849 SMESH_CATCH( SMESH::throwCorbaException );
1851 return aResGrp._retn();
1854 //================================================================================
1856 * \brief Remember GEOM group data
1858 //================================================================================
1860 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1861 CORBA::Object_ptr theSmeshObj)
1863 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1866 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1867 if ( groupSO->_is_nil() )
1870 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1871 GEOM::GEOM_IGroupOperations_wrap groupOp =
1872 geomGen->GetIGroupOperations();
1873 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1876 _geomGroupData.push_back( TGeomGroupData() );
1877 TGeomGroupData & groupData = _geomGroupData.back();
1879 CORBA::String_var entry = groupSO->GetID();
1880 groupData._groupEntry = entry.in();
1882 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1883 groupData._indices.insert( ids[i] );
1885 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1886 // shape index in SMESHDS
1887 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1888 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1891 //================================================================================
1893 * Remove GEOM group data relating to removed smesh object
1895 //================================================================================
1897 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1899 list<TGeomGroupData>::iterator
1900 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1901 for ( ; data != dataEnd; ++data ) {
1902 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1903 _geomGroupData.erase( data );
1909 //================================================================================
1911 * \brief Return new group contents if it has been changed and update group data
1913 //================================================================================
1915 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1917 TopoDS_Shape newShape;
1920 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1921 if ( !groupSO->_is_nil() )
1923 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1924 if ( CORBA::is_nil( groupObj )) return newShape;
1925 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1927 // get indices of group items
1928 set<int> curIndices;
1929 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1930 GEOM::GEOM_IGroupOperations_wrap groupOp =
1931 geomGen->GetIGroupOperations();
1932 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1933 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1934 curIndices.insert( ids[i] );
1936 if ( groupData._indices == curIndices )
1937 return newShape; // group not changed
1940 groupData._indices = curIndices;
1942 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1943 if ( !geomClient ) return newShape;
1944 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1945 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1946 newShape = _gen_i->GeomObjectToShape( geomGroup );
1949 if ( newShape.IsNull() ) {
1950 // geom group becomes empty - return empty compound
1951 TopoDS_Compound compound;
1952 BRep_Builder().MakeCompound(compound);
1953 newShape = compound;
1960 //-----------------------------------------------------------------------------
1962 * \brief Storage of shape and index used in CheckGeomGroupModif()
1964 struct TIndexedShape
1967 TopoDS_Shape _shape;
1968 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1970 //-----------------------------------------------------------------------------
1972 * \brief Data to re-create a group on geometry
1974 struct TGroupOnGeomData
1978 SMDSAbs_ElementType _type;
1980 Quantity_Color _color;
1984 //=============================================================================
1986 * \brief Update data if geometry changes
1990 //=============================================================================
1992 void SMESH_Mesh_i::CheckGeomModif()
1994 if ( !_impl->HasShapeToMesh() ) return;
1996 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1997 //if ( mainGO->_is_nil() ) return;
1999 // Update after group modification
2001 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
2002 called by other mesh (IPAL52735) */
2003 mainGO->GetType() == GEOM_GROUP ||
2004 mainGO->GetTick() == _mainShapeTick )
2006 CheckGeomGroupModif();
2010 // Update after shape transformation like Translate
2012 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2013 if ( !geomClient ) return;
2014 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2015 if ( geomGen->_is_nil() ) return;
2017 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2018 geomClient->RemoveShapeFromBuffer( ior.in() );
2020 // Update data taking into account that
2021 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2024 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2025 if ( newShape.IsNull() )
2028 _mainShapeTick = mainGO->GetTick();
2030 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2032 // store data of groups on geometry
2033 vector< TGroupOnGeomData > groupsData;
2034 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2035 groupsData.reserve( groups.size() );
2036 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2037 for ( ; g != groups.end(); ++g )
2038 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2040 TGroupOnGeomData data;
2041 data._oldID = group->GetID();
2042 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2043 data._type = group->GetType();
2044 data._name = group->GetStoreName();
2045 data._color = group->GetColor();
2046 groupsData.push_back( data );
2048 // store assigned hypotheses
2049 vector< pair< int, THypList > > ids2Hyps;
2050 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2051 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2053 const TopoDS_Shape& s = s2hyps.Key();
2054 const THypList& hyps = s2hyps.ChangeValue();
2055 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2058 // change shape to mesh
2059 int oldNbSubShapes = meshDS->MaxShapeIndex();
2060 _impl->ShapeToMesh( TopoDS_Shape() );
2061 _impl->ShapeToMesh( newShape );
2063 // re-add shapes of geom groups
2064 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2065 for ( ; data != _geomGroupData.end(); ++data )
2067 TopoDS_Shape newShape = newGroupShape( *data );
2068 if ( !newShape.IsNull() )
2070 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2072 TopoDS_Compound compound;
2073 BRep_Builder().MakeCompound( compound );
2074 BRep_Builder().Add( compound, newShape );
2075 newShape = compound;
2077 _impl->GetSubMesh( newShape );
2080 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2081 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2082 SALOME::INTERNAL_ERROR );
2084 // re-assign hypotheses
2085 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2087 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2088 const THypList& hyps = ids2Hyps[i].second;
2089 THypList::const_iterator h = hyps.begin();
2090 for ( ; h != hyps.end(); ++h )
2091 _impl->AddHypothesis( s, (*h)->GetID() );
2095 for ( size_t i = 0; i < groupsData.size(); ++i )
2097 const TGroupOnGeomData& data = groupsData[i];
2099 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2100 if ( i2g == _mapGroups.end() ) continue;
2102 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2103 if ( !gr_i ) continue;
2106 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2107 meshDS->IndexToShape( data._shapeID ));
2110 _mapGroups.erase( i2g );
2114 g->GetGroupDS()->SetColor( data._color );
2115 gr_i->changeLocalId( id );
2116 _mapGroups[ id ] = i2g->second;
2117 if ( data._oldID != id )
2118 _mapGroups.erase( i2g );
2122 // update _mapSubMesh
2123 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2124 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2125 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2129 //=============================================================================
2131 * \brief Update objects depending on changed geom groups
2133 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2134 * issue 0020210: Update of a smesh group after modification of the associated geom group
2136 //=============================================================================
2138 void SMESH_Mesh_i::CheckGeomGroupModif()
2140 if ( !_impl->HasShapeToMesh() ) return;
2142 CORBA::Long nbEntities = NbNodes() + NbElements();
2144 // Check if group contents changed
2146 typedef map< string, TopoDS_Shape > TEntry2Geom;
2147 TEntry2Geom newGroupContents;
2149 list<TGeomGroupData>::iterator
2150 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2151 for ( ; data != dataEnd; ++data )
2153 pair< TEntry2Geom::iterator, bool > it_new =
2154 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2155 bool processedGroup = !it_new.second;
2156 TopoDS_Shape& newShape = it_new.first->second;
2157 if ( !processedGroup )
2158 newShape = newGroupShape( *data );
2159 if ( newShape.IsNull() )
2160 continue; // no changes
2163 _preMeshInfo->ForgetOrLoad();
2165 if ( processedGroup ) { // update group indices
2166 list<TGeomGroupData>::iterator data2 = data;
2167 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2168 data->_indices = data2->_indices;
2171 // Update SMESH objects according to new GEOM group contents
2173 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2174 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2176 int oldID = submesh->GetId();
2177 if ( !_mapSubMeshIor.count( oldID ))
2179 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2181 // update hypotheses
2182 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2183 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2184 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2186 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2187 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2189 // care of submeshes
2190 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2191 int newID = newSubmesh->GetId();
2192 if ( newID != oldID ) {
2193 _mapSubMesh [ newID ] = newSubmesh;
2194 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2195 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2196 _mapSubMesh. erase(oldID);
2197 _mapSubMesh_i. erase(oldID);
2198 _mapSubMeshIor.erase(oldID);
2199 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2204 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2205 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2206 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2208 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2210 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2211 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2212 ds->SetShape( newShape );
2217 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2218 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2220 // Remove groups and submeshes basing on removed sub-shapes
2222 TopTools_MapOfShape newShapeMap;
2223 TopoDS_Iterator shapeIt( newShape );
2224 for ( ; shapeIt.More(); shapeIt.Next() )
2225 newShapeMap.Add( shapeIt.Value() );
2227 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2228 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2230 if ( newShapeMap.Contains( shapeIt.Value() ))
2232 TopTools_IndexedMapOfShape oldShapeMap;
2233 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2234 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2236 const TopoDS_Shape& oldShape = oldShapeMap(i);
2237 int oldInd = meshDS->ShapeToIndex( oldShape );
2239 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2240 if ( i_smIor != _mapSubMeshIor.end() ) {
2241 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2244 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2245 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2247 // check if a group bases on oldInd shape
2248 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2249 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2250 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2251 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2253 RemoveGroup( i_grp->second ); // several groups can base on same shape
2254 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2259 // Reassign hypotheses and update groups after setting the new shape to mesh
2261 // collect anassigned hypotheses
2262 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2263 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2264 TShapeHypList assignedHyps;
2265 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2267 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2268 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2269 if ( !hyps.empty() ) {
2270 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2271 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2272 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2275 // collect shapes supporting groups
2276 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2277 TShapeTypeList groupData;
2278 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2279 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2280 for ( ; grIt != groups.end(); ++grIt )
2282 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2284 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2286 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2288 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2289 _impl->ShapeToMesh( newShape );
2291 // reassign hypotheses
2292 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2293 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2295 TIndexedShape& geom = indS_hyps->first;
2296 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2297 int oldID = geom._index;
2298 int newID = meshDS->ShapeToIndex( geom._shape );
2299 if ( oldID == 1 ) { // main shape
2301 geom._shape = newShape;
2305 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2306 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2307 // care of sub-meshes
2308 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2309 if ( newID != oldID ) {
2310 _mapSubMesh [ newID ] = newSubmesh;
2311 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2312 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2313 _mapSubMesh. erase(oldID);
2314 _mapSubMesh_i. erase(oldID);
2315 _mapSubMeshIor.erase(oldID);
2316 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2320 TShapeTypeList::iterator geomType = groupData.begin();
2321 for ( ; geomType != groupData.end(); ++geomType )
2323 const TIndexedShape& geom = geomType->first;
2324 int oldID = geom._index;
2325 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2328 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2329 CORBA::String_var name = groupSO->GetName();
2331 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2333 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2334 group_i->changeLocalId( newID );
2337 break; // everything has been updated
2340 } // loop on group data
2344 CORBA::Long newNbEntities = NbNodes() + NbElements();
2345 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2346 if ( newNbEntities != nbEntities )
2348 // Add all SObjects with icons to soToUpdateIcons
2349 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2351 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2352 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2353 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2355 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2356 i_gr != _mapGroups.end(); ++i_gr ) // groups
2357 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2360 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2361 for ( ; so != soToUpdateIcons.end(); ++so )
2362 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2365 //=============================================================================
2367 * \brief Create standalone group from a group on geometry or filter
2369 //=============================================================================
2371 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2372 throw (SALOME::SALOME_Exception)
2374 SMESH::SMESH_Group_var aGroup;
2379 _preMeshInfo->FullLoadFromFile();
2381 if ( theGroup->_is_nil() )
2382 return aGroup._retn();
2384 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2386 return aGroup._retn();
2388 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2390 const int anId = aGroupToRem->GetLocalID();
2391 if ( !_impl->ConvertToStandalone( anId ) )
2392 return aGroup._retn();
2393 removeGeomGroupData( theGroup );
2395 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2397 // remove old instance of group from own map
2398 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2399 _mapGroups.erase( anId );
2401 SALOMEDS::StudyBuilder_var builder;
2402 SALOMEDS::SObject_wrap aGroupSO;
2403 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2404 if ( !aStudy->_is_nil() ) {
2405 builder = aStudy->NewBuilder();
2406 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2407 if ( !aGroupSO->_is_nil() )
2409 // remove reference to geometry
2410 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2411 for ( ; chItr->More(); chItr->Next() )
2412 // Remove group's child SObject
2413 builder->RemoveObject( chItr->Value() );
2415 // Update Python script
2416 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2417 << ".ConvertToStandalone( " << aGroupSO << " )";
2419 // change icon of Group on Filter
2422 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2423 const int isEmpty = ( elemTypes->length() == 0 );
2426 SALOMEDS::GenericAttribute_wrap anAttr =
2427 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2428 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2429 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2435 // remember new group in own map
2436 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2437 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2439 // register CORBA object for persistence
2440 _gen_i->RegisterObject( aGroup );
2442 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2443 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2444 //aGroup->Register();
2445 aGroupToRem->UnRegister();
2447 SMESH_CATCH( SMESH::throwCorbaException );
2449 return aGroup._retn();
2452 //=============================================================================
2456 //=============================================================================
2458 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2460 if(MYDEBUG) MESSAGE( "createSubMesh" );
2461 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2462 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2463 const int subMeshId = mySubMesh->GetId();
2465 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2466 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2468 _mapSubMesh [subMeshId] = mySubMesh;
2469 _mapSubMesh_i [subMeshId] = subMeshServant;
2470 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2472 subMeshServant->Register();
2474 // register CORBA object for persistence
2475 int nextId = _gen_i->RegisterObject( subMesh );
2476 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2477 else { nextId = 0; } // avoid "unused variable" warning
2479 // to track changes of GEOM groups
2480 addGeomGroupData( theSubShapeObject, subMesh );
2482 return subMesh._retn();
2485 //=======================================================================
2486 //function : getSubMesh
2488 //=======================================================================
2490 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2492 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2493 if ( it == _mapSubMeshIor.end() )
2494 return SMESH::SMESH_subMesh::_nil();
2496 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2499 //=============================================================================
2503 //=============================================================================
2505 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2506 GEOM::GEOM_Object_ptr theSubShapeObject )
2508 bool isHypChanged = false;
2509 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2510 return isHypChanged;
2512 const int subMeshId = theSubMesh->GetId();
2514 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2516 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2518 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2521 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2522 isHypChanged = !hyps.empty();
2523 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2524 for ( ; hyp != hyps.end(); ++hyp )
2525 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2532 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2533 isHypChanged = ( aHypList->length() > 0 );
2534 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2535 removeHypothesis( theSubShapeObject, aHypList[i] );
2538 catch( const SALOME::SALOME_Exception& ) {
2539 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2541 removeGeomGroupData( theSubShapeObject );
2545 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2546 if ( id_smi != _mapSubMesh_i.end() )
2547 id_smi->second->UnRegister();
2549 // remove a CORBA object
2550 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2551 if ( id_smptr != _mapSubMeshIor.end() )
2552 SMESH::SMESH_subMesh_var( id_smptr->second );
2554 _mapSubMesh.erase(subMeshId);
2555 _mapSubMesh_i.erase(subMeshId);
2556 _mapSubMeshIor.erase(subMeshId);
2558 return isHypChanged;
2561 //=============================================================================
2565 //=============================================================================
2567 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2568 const char* theName,
2569 const TopoDS_Shape& theShape,
2570 const SMESH_PredicatePtr& thePredicate )
2572 std::string newName;
2573 if ( !theName || !theName[0] )
2575 std::set< std::string > presentNames;
2576 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2577 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2579 CORBA::String_var name = i_gr->second->GetName();
2580 presentNames.insert( name.in() );
2583 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2584 } while ( !presentNames.insert( newName ).second );
2585 theName = newName.c_str();
2588 SMESH::SMESH_GroupBase_var aGroup;
2589 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2591 SMESH_GroupBase_i* aGroupImpl;
2592 if ( !theShape.IsNull() )
2593 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2594 else if ( thePredicate )
2595 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2597 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2599 aGroup = aGroupImpl->_this();
2600 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2601 aGroupImpl->Register();
2603 // register CORBA object for persistence
2604 int nextId = _gen_i->RegisterObject( aGroup );
2605 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2606 else { nextId = 0; } // avoid "unused variable" warning in release mode
2608 // to track changes of GEOM groups
2609 if ( !theShape.IsNull() ) {
2610 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2611 addGeomGroupData( geom, aGroup );
2614 return aGroup._retn();
2617 //=============================================================================
2619 * SMESH_Mesh_i::removeGroup
2621 * Should be called by ~SMESH_Group_i()
2623 //=============================================================================
2625 void SMESH_Mesh_i::removeGroup( const int theId )
2627 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2628 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2629 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2630 _mapGroups.erase( theId );
2631 removeGeomGroupData( group );
2632 if ( !_impl->RemoveGroup( theId ))
2634 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2635 RemoveGroup( group );
2637 group->UnRegister();
2641 //=============================================================================
2645 //=============================================================================
2647 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2648 throw(SALOME::SALOME_Exception)
2650 SMESH::log_array_var aLog;
2654 _preMeshInfo->FullLoadFromFile();
2656 list < SMESHDS_Command * >logDS = _impl->GetLog();
2657 aLog = new SMESH::log_array;
2659 int lg = logDS.size();
2662 list < SMESHDS_Command * >::iterator its = logDS.begin();
2663 while(its != logDS.end()){
2664 SMESHDS_Command *com = *its;
2665 int comType = com->GetType();
2667 int lgcom = com->GetNumber();
2669 const list < int >&intList = com->GetIndexes();
2670 int inum = intList.size();
2672 list < int >::const_iterator ii = intList.begin();
2673 const list < double >&coordList = com->GetCoords();
2674 int rnum = coordList.size();
2676 list < double >::const_iterator ir = coordList.begin();
2677 aLog[indexLog].commandType = comType;
2678 aLog[indexLog].number = lgcom;
2679 aLog[indexLog].coords.length(rnum);
2680 aLog[indexLog].indexes.length(inum);
2681 for(int i = 0; i < rnum; i++){
2682 aLog[indexLog].coords[i] = *ir;
2683 //MESSAGE(" "<<i<<" "<<ir.Value());
2686 for(int i = 0; i < inum; i++){
2687 aLog[indexLog].indexes[i] = *ii;
2688 //MESSAGE(" "<<i<<" "<<ii.Value());
2697 SMESH_CATCH( SMESH::throwCorbaException );
2699 return aLog._retn();
2703 //=============================================================================
2707 //=============================================================================
2709 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2713 SMESH_CATCH( SMESH::throwCorbaException );
2716 //=============================================================================
2720 //=============================================================================
2722 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2727 //=============================================================================
2730 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2731 // issue 0020918: groups removal is caused by hyp modification
2732 // issue 0021208: to forget not loaded mesh data at hyp modification
2733 struct TCallUp_i : public SMESH_Mesh::TCallUp
2735 SMESH_Mesh_i* _mesh;
2736 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2737 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2738 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2739 virtual void Load () { _mesh->Load(); }
2743 //================================================================================
2745 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2747 //================================================================================
2749 void SMESH_Mesh_i::onHypothesisModified()
2752 _preMeshInfo->ForgetOrLoad();
2754 SMESH::SMESH_Mesh_var mesh = _this();
2755 _gen_i->UpdateIcons( mesh );
2758 //=============================================================================
2762 //=============================================================================
2764 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2766 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2769 _impl->SetCallUp( new TCallUp_i(this));
2772 //=============================================================================
2776 //=============================================================================
2778 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2780 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2784 //=============================================================================
2786 * Return mesh editor
2788 //=============================================================================
2790 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2791 throw (SALOME::SALOME_Exception)
2793 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2797 _preMeshInfo->FullLoadFromFile();
2799 // Create MeshEditor
2801 _editor = new SMESH_MeshEditor_i( this, false );
2802 aMeshEdVar = _editor->_this();
2804 // Update Python script
2805 TPythonDump() << _editor << " = "
2806 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2808 SMESH_CATCH( SMESH::throwCorbaException );
2810 return aMeshEdVar._retn();
2813 //=============================================================================
2815 * Return mesh edition previewer
2817 //=============================================================================
2819 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2820 throw (SALOME::SALOME_Exception)
2822 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2826 _preMeshInfo->FullLoadFromFile();
2828 if ( !_previewEditor )
2829 _previewEditor = new SMESH_MeshEditor_i( this, true );
2830 aMeshEdVar = _previewEditor->_this();
2832 SMESH_CATCH( SMESH::throwCorbaException );
2834 return aMeshEdVar._retn();
2837 //================================================================================
2839 * \brief Return true if the mesh has been edited since a last total re-compute
2840 * and those modifications may prevent successful partial re-compute
2842 //================================================================================
2844 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2846 Unexpect aCatch(SALOME_SalomeException);
2847 return _impl->HasModificationsToDiscard();
2850 //================================================================================
2852 * \brief Returns a random unique color
2854 //================================================================================
2856 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2858 const int MAX_ATTEMPTS = 100;
2860 double tolerance = 0.5;
2861 SALOMEDS::Color col;
2865 // generate random color
2866 double red = (double)rand() / RAND_MAX;
2867 double green = (double)rand() / RAND_MAX;
2868 double blue = (double)rand() / RAND_MAX;
2869 // check existence in the list of the existing colors
2870 bool matched = false;
2871 std::list<SALOMEDS::Color>::const_iterator it;
2872 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2873 SALOMEDS::Color color = *it;
2874 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2875 matched = tol < tolerance;
2877 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2878 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2886 //=============================================================================
2888 * Sets auto-color mode. If it is on, groups get unique random colors
2890 //=============================================================================
2892 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2894 Unexpect aCatch(SALOME_SalomeException);
2895 _impl->SetAutoColor(theAutoColor);
2897 TPythonDump pyDump; // not to dump group->SetColor() from below code
2898 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2900 std::list<SALOMEDS::Color> aReservedColors;
2901 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2902 for ( ; it != _mapGroups.end(); it++ ) {
2903 if ( CORBA::is_nil( it->second )) continue;
2904 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2905 it->second->SetColor( aColor );
2906 aReservedColors.push_back( aColor );
2910 //=============================================================================
2912 * Returns true if auto-color mode is on
2914 //=============================================================================
2916 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2918 Unexpect aCatch(SALOME_SalomeException);
2919 return _impl->GetAutoColor();
2922 //=============================================================================
2924 * Checks if there are groups with equal names
2926 //=============================================================================
2928 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2930 return _impl->HasDuplicatedGroupNamesMED();
2933 //================================================================================
2935 * \brief Care of a file before exporting mesh into it
2937 //================================================================================
2939 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2941 SMESH_File aFile( file );
2943 if (aFile.exists()) {
2944 // existing filesystem node
2945 if ( !aFile.isDirectory() ) {
2946 if ( aFile.openForWriting() ) {
2947 if ( overwrite && ! aFile.remove()) {
2948 msg << "Can't replace " << aFile.getName();
2951 msg << "Can't write into " << aFile.getName();
2954 msg << "Location " << aFile.getName() << " is not a file";
2958 // nonexisting file; check if it can be created
2959 if ( !aFile.openForWriting() ) {
2960 msg << "You cannot create the file "
2962 << ". Check the directory existence and access rights";
2970 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2974 //================================================================================
2976 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2977 * \param file - file name
2978 * \param overwrite - to erase the file or not
2979 * \retval string - mesh name
2981 //================================================================================
2983 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2984 CORBA::Boolean overwrite)
2987 PrepareForWriting(file, overwrite);
2988 string aMeshName = "Mesh";
2989 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2990 if ( !aStudy->_is_nil() ) {
2991 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
2992 if ( !aMeshSO->_is_nil() ) {
2993 CORBA::String_var name = aMeshSO->GetName();
2995 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2996 if ( !aStudy->GetProperties()->IsLocked() )
2998 SALOMEDS::GenericAttribute_wrap anAttr;
2999 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3000 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3001 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3002 ASSERT(!aFileName->_is_nil());
3003 aFileName->SetValue(file);
3004 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3005 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3006 ASSERT(!aFileType->_is_nil());
3007 aFileType->SetValue("FICHIERMED");
3011 // Update Python script
3012 // set name of mesh before export
3013 TPythonDump() << _gen_i << ".SetName("
3014 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3016 // check names of groups
3022 //================================================================================
3024 * \brief Export to MED file
3026 //================================================================================
3028 void SMESH_Mesh_i::ExportMED(const char* file,
3029 CORBA::Boolean auto_groups,
3031 CORBA::Boolean overwrite,
3032 CORBA::Boolean autoDimension)
3033 throw(SALOME::SALOME_Exception)
3035 //MESSAGE("MED minor version: "<< minor);
3038 _preMeshInfo->FullLoadFromFile();
3040 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3041 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, 0, autoDimension );
3043 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3045 << "auto_groups=" <<auto_groups << ", "
3046 << "minor=" << minor << ", "
3047 << "overwrite=" << overwrite << ", "
3048 << "meshPart=None, "
3049 << "autoDimension=" << autoDimension << " )";
3051 SMESH_CATCH( SMESH::throwCorbaException );
3054 //================================================================================
3056 * \brief Export a mesh to a SAUV file
3058 //================================================================================
3060 void SMESH_Mesh_i::ExportSAUV (const char* file,
3061 CORBA::Boolean auto_groups)
3062 throw(SALOME::SALOME_Exception)
3064 Unexpect aCatch(SALOME_SalomeException);
3066 _preMeshInfo->FullLoadFromFile();
3068 string aMeshName = prepareMeshNameAndGroups(file, true);
3069 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3070 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3071 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3075 //================================================================================
3077 * \brief Export a mesh to a DAT file
3079 //================================================================================
3081 void SMESH_Mesh_i::ExportDAT (const char *file)
3082 throw(SALOME::SALOME_Exception)
3084 Unexpect aCatch(SALOME_SalomeException);
3086 _preMeshInfo->FullLoadFromFile();
3088 // Update Python script
3089 // check names of groups
3091 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3094 PrepareForWriting(file);
3095 _impl->ExportDAT(file);
3098 //================================================================================
3100 * \brief Export a mesh to an UNV file
3102 //================================================================================
3104 void SMESH_Mesh_i::ExportUNV (const char *file)
3105 throw(SALOME::SALOME_Exception)
3107 Unexpect aCatch(SALOME_SalomeException);
3109 _preMeshInfo->FullLoadFromFile();
3111 // Update Python script
3112 // check names of groups
3114 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3117 PrepareForWriting(file);
3118 _impl->ExportUNV(file);
3121 //================================================================================
3123 * \brief Export a mesh to an STL file
3125 //================================================================================
3127 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3128 throw(SALOME::SALOME_Exception)
3130 Unexpect aCatch(SALOME_SalomeException);
3132 _preMeshInfo->FullLoadFromFile();
3134 // Update Python script
3135 // check names of groups
3137 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3138 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3140 CORBA::String_var name;
3141 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3142 if ( !so->_is_nil() )
3143 name = so->GetName();
3146 PrepareForWriting( file );
3147 _impl->ExportSTL( file, isascii, name.in() );
3150 //================================================================================
3152 * \brief Export a part of mesh to a med file
3154 //================================================================================
3156 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3158 CORBA::Boolean auto_groups,
3160 CORBA::Boolean overwrite,
3161 CORBA::Boolean autoDimension,
3162 const GEOM::ListOfFields& fields,
3163 const char* geomAssocFields)
3164 throw (SALOME::SALOME_Exception)
3166 //MESSAGE("MED minor version: "<< minor);
3169 _preMeshInfo->FullLoadFromFile();
3172 bool have0dField = false;
3173 if ( fields.length() > 0 )
3175 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3176 if ( shapeToMesh->_is_nil() )
3177 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3179 for ( size_t i = 0; i < fields.length(); ++i )
3181 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3182 THROW_SALOME_CORBA_EXCEPTION
3183 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3184 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3185 if ( fieldShape->_is_nil() )
3186 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3187 if ( !fieldShape->IsSame( shapeToMesh ) )
3188 THROW_SALOME_CORBA_EXCEPTION
3189 ( "Field defined not on shape", SALOME::BAD_PARAM);
3190 if ( fields[i]->GetDimension() == 0 )
3193 if ( geomAssocFields )
3194 for ( int i = 0; geomAssocFields[i]; ++i )
3195 switch ( geomAssocFields[i] ) {
3196 case 'v':case 'e':case 'f':case 's': break;
3197 case 'V':case 'E':case 'F':case 'S': break;
3198 default: THROW_SALOME_CORBA_EXCEPTION
3199 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3203 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3207 string aMeshName = "Mesh";
3208 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3209 if ( CORBA::is_nil( meshPart ) ||
3210 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3212 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3213 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
3214 0, autoDimension, /*addODOnVertices=*/have0dField);
3215 meshDS = _impl->GetMeshDS();
3220 _preMeshInfo->FullLoadFromFile();
3222 PrepareForWriting(file, overwrite);
3224 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3225 if ( !SO->_is_nil() ) {
3226 CORBA::String_var name = SO->GetName();
3230 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3231 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
3232 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3233 meshDS = tmpDSDeleter._obj = partDS;
3238 if ( _impl->HasShapeToMesh() )
3240 DriverMED_W_Field fieldWriter;
3241 fieldWriter.SetFile( file );
3242 fieldWriter.SetMeshName( aMeshName );
3243 fieldWriter.AddODOnVertices( have0dField );
3245 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3249 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3250 goList->length( fields.length() );
3251 for ( size_t i = 0; i < fields.length(); ++i )
3253 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3256 TPythonDump() << _this() << ".ExportPartToMED( r'"
3258 << "auto_groups=" << auto_groups << ", "
3259 << "minor=" << minor << ", "
3260 << "overwrite=" << overwrite << ", "
3261 << "meshPart=" << meshPart << ", "
3262 << "autoDimension=" << autoDimension << ", "
3263 << "fields=" << goList << ", geomAssocFields='"
3264 << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3266 SMESH_CATCH( SMESH::throwCorbaException );
3269 //================================================================================
3271 * Write GEOM fields to MED file
3273 //================================================================================
3275 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3276 SMESHDS_Mesh* meshDS,
3277 const GEOM::ListOfFields& fields,
3278 const char* geomAssocFields)
3280 #define METH "SMESH_Mesh_i::exportMEDFields() "
3282 if (( fields.length() < 1 ) &&
3283 ( !geomAssocFields || !geomAssocFields[0] ))
3286 std::vector< std::vector< double > > dblVals;
3287 std::vector< std::vector< int > > intVals;
3288 std::vector< int > subIdsByDim[ 4 ];
3289 const double noneDblValue = 0.;
3290 const double noneIntValue = 0;
3292 for ( size_t iF = 0; iF < fields.length(); ++iF )
3296 int dim = fields[ iF ]->GetDimension();
3297 SMDSAbs_ElementType elemType;
3298 TopAbs_ShapeEnum shapeType;
3300 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3301 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3302 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3303 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3305 continue; // skip fields on whole shape
3307 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3308 if ( dataType == GEOM::FDT_String )
3310 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3311 if ( stepIDs->length() < 1 )
3313 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3314 if ( comps->length() < 1 )
3316 CORBA::String_var name = fields[ iF ]->GetName();
3318 if ( !fieldWriter.Set( meshDS,
3322 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3325 for ( size_t iC = 0; iC < comps->length(); ++iC )
3326 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3328 dblVals.resize( comps->length() );
3329 intVals.resize( comps->length() );
3331 // find sub-shape IDs
3333 std::vector< int >& subIds = subIdsByDim[ dim ];
3334 if ( subIds.empty() )
3335 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3336 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3337 subIds.push_back( id );
3341 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3345 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3347 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3348 if ( step->_is_nil() )
3351 CORBA::Long stamp = step->GetStamp();
3352 CORBA::Long id = step->GetID();
3353 fieldWriter.SetDtIt( int( stamp ), int( id ));
3355 // fill dblVals or intVals
3356 for ( size_t iC = 0; iC < comps->length(); ++iC )
3357 if ( dataType == GEOM::FDT_Double )
3359 dblVals[ iC ].clear();
3360 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3364 intVals[ iC ].clear();
3365 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3369 case GEOM::FDT_Double:
3371 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3372 if ( dblStep->_is_nil() ) continue;
3373 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3374 if ( vv->length() != subIds.size() * comps->length() )
3375 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3376 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3377 for ( size_t iC = 0; iC < comps->length(); ++iC )
3378 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3383 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3384 if ( intStep->_is_nil() ) continue;
3385 GEOM::ListOfLong_var vv = intStep->GetValues();
3386 if ( vv->length() != subIds.size() * comps->length() )
3387 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3388 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3389 for ( size_t iC = 0; iC < comps->length(); ++iC )
3390 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3393 case GEOM::FDT_Bool:
3395 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3396 if ( boolStep->_is_nil() ) continue;
3397 GEOM::short_array_var vv = boolStep->GetValues();
3398 if ( vv->length() != subIds.size() * comps->length() )
3399 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3400 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3401 for ( size_t iC = 0; iC < comps->length(); ++iC )
3402 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3408 // pass values to fieldWriter
3409 elemIt = fieldWriter.GetOrderedElems();
3410 if ( dataType == GEOM::FDT_Double )
3411 while ( elemIt->more() )
3413 const SMDS_MeshElement* e = elemIt->next();
3414 const int shapeID = e->getshapeId();
3415 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3416 for ( size_t iC = 0; iC < comps->length(); ++iC )
3417 fieldWriter.AddValue( noneDblValue );
3419 for ( size_t iC = 0; iC < comps->length(); ++iC )
3420 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3423 while ( elemIt->more() )
3425 const SMDS_MeshElement* e = elemIt->next();
3426 const int shapeID = e->getshapeId();
3427 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3428 for ( size_t iC = 0; iC < comps->length(); ++iC )
3429 fieldWriter.AddValue( (double) noneIntValue );
3431 for ( size_t iC = 0; iC < comps->length(); ++iC )
3432 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3436 fieldWriter.Perform();
3437 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3438 if ( res && res->IsKO() )
3440 if ( res->myComment.empty() )
3441 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3443 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3449 if ( !geomAssocFields || !geomAssocFields[0] )
3452 // write geomAssocFields
3454 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3455 shapeDim[ TopAbs_COMPOUND ] = 3;
3456 shapeDim[ TopAbs_COMPSOLID ] = 3;
3457 shapeDim[ TopAbs_SOLID ] = 3;
3458 shapeDim[ TopAbs_SHELL ] = 2;
3459 shapeDim[ TopAbs_FACE ] = 2;
3460 shapeDim[ TopAbs_WIRE ] = 1;
3461 shapeDim[ TopAbs_EDGE ] = 1;
3462 shapeDim[ TopAbs_VERTEX ] = 0;
3463 shapeDim[ TopAbs_SHAPE ] = 3;
3465 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3467 std::vector< std::string > compNames;
3468 switch ( geomAssocFields[ iF ]) {
3470 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3471 compNames.push_back( "dim" );
3474 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3477 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3480 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3484 compNames.push_back( "id" );
3485 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3486 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3488 fieldWriter.SetDtIt( -1, -1 );
3490 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3494 if ( compNames.size() == 2 ) // _vertices_
3495 while ( elemIt->more() )
3497 const SMDS_MeshElement* e = elemIt->next();
3498 const int shapeID = e->getshapeId();
3501 fieldWriter.AddValue( (double) -1 );
3502 fieldWriter.AddValue( (double) -1 );
3506 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3507 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3508 fieldWriter.AddValue( (double) shapeID );
3512 while ( elemIt->more() )
3514 const SMDS_MeshElement* e = elemIt->next();
3515 const int shapeID = e->getshapeId();
3517 fieldWriter.AddValue( (double) -1 );
3519 fieldWriter.AddValue( (double) shapeID );
3523 fieldWriter.Perform();
3524 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3525 if ( res && res->IsKO() )
3527 if ( res->myComment.empty() )
3528 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3530 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3533 } // loop on geomAssocFields
3538 //================================================================================
3540 * \brief Export a part of mesh to a DAT file
3542 //================================================================================
3544 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3546 throw (SALOME::SALOME_Exception)
3548 Unexpect aCatch(SALOME_SalomeException);
3550 _preMeshInfo->FullLoadFromFile();
3552 PrepareForWriting(file);
3554 SMESH_MeshPartDS partDS( meshPart );
3555 _impl->ExportDAT(file,&partDS);
3557 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3558 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3560 //================================================================================
3562 * \brief Export a part of mesh to an UNV file
3564 //================================================================================
3566 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3568 throw (SALOME::SALOME_Exception)
3570 Unexpect aCatch(SALOME_SalomeException);
3572 _preMeshInfo->FullLoadFromFile();
3574 PrepareForWriting(file);
3576 SMESH_MeshPartDS partDS( meshPart );
3577 _impl->ExportUNV(file, &partDS);
3579 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3580 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3582 //================================================================================
3584 * \brief Export a part of mesh to an STL file
3586 //================================================================================
3588 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3590 ::CORBA::Boolean isascii)
3591 throw (SALOME::SALOME_Exception)
3593 Unexpect aCatch(SALOME_SalomeException);
3595 _preMeshInfo->FullLoadFromFile();
3597 PrepareForWriting(file);
3599 CORBA::String_var name;
3600 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3601 if ( !so->_is_nil() )
3602 name = so->GetName();
3604 SMESH_MeshPartDS partDS( meshPart );
3605 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3607 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3608 << meshPart<< ", r'" << file << "', " << isascii << ")";
3611 //================================================================================
3613 * \brief Export a part of mesh to an STL file
3615 //================================================================================
3617 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3619 CORBA::Boolean overwrite,
3620 CORBA::Boolean groupElemsByType)
3621 throw (SALOME::SALOME_Exception)
3624 Unexpect aCatch(SALOME_SalomeException);
3626 _preMeshInfo->FullLoadFromFile();
3628 PrepareForWriting(file,overwrite);
3630 std::string meshName("");
3631 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3632 if ( !so->_is_nil() )
3634 CORBA::String_var name = so->GetName();
3635 meshName = name.in();
3639 SMESH_MeshPartDS partDS( meshPart );
3640 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3642 SMESH_CATCH( SMESH::throwCorbaException );
3644 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3645 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3647 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3651 //================================================================================
3653 * \brief Export a part of mesh to a GMF file
3655 //================================================================================
3657 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3659 bool withRequiredGroups)
3660 throw (SALOME::SALOME_Exception)
3662 Unexpect aCatch(SALOME_SalomeException);
3664 _preMeshInfo->FullLoadFromFile();
3666 PrepareForWriting(file,/*overwrite=*/true);
3668 SMESH_MeshPartDS partDS( meshPart );
3669 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3671 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3672 << meshPart<< ", r'"
3674 << withRequiredGroups << ")";
3677 //=============================================================================
3679 * Return computation progress [0.,1]
3681 //=============================================================================
3683 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3687 return _impl->GetComputeProgress();
3689 SMESH_CATCH( SMESH::doNothing );
3693 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3695 Unexpect aCatch(SALOME_SalomeException);
3697 return _preMeshInfo->NbNodes();
3699 return _impl->NbNodes();
3702 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3704 Unexpect aCatch(SALOME_SalomeException);
3706 return _preMeshInfo->NbElements();
3708 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3711 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3713 Unexpect aCatch(SALOME_SalomeException);
3715 return _preMeshInfo->Nb0DElements();
3717 return _impl->Nb0DElements();
3720 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3722 Unexpect aCatch(SALOME_SalomeException);
3724 return _preMeshInfo->NbBalls();
3726 return _impl->NbBalls();
3729 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3731 Unexpect aCatch(SALOME_SalomeException);
3733 return _preMeshInfo->NbEdges();
3735 return _impl->NbEdges();
3738 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3739 throw(SALOME::SALOME_Exception)
3741 Unexpect aCatch(SALOME_SalomeException);
3743 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3745 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3748 //=============================================================================
3750 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 return _preMeshInfo->NbFaces();
3756 return _impl->NbFaces();
3759 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3763 return _preMeshInfo->NbTriangles();
3765 return _impl->NbTriangles();
3768 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbBiQuadTriangles();
3774 return _impl->NbBiQuadTriangles();
3777 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbQuadrangles();
3783 return _impl->NbQuadrangles();
3786 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3788 Unexpect aCatch(SALOME_SalomeException);
3790 return _preMeshInfo->NbBiQuadQuadrangles();
3792 return _impl->NbBiQuadQuadrangles();
3795 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbPolygons();
3801 return _impl->NbPolygons();
3804 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3806 Unexpect aCatch(SALOME_SalomeException);
3808 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3810 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3813 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3814 throw(SALOME::SALOME_Exception)
3816 Unexpect aCatch(SALOME_SalomeException);
3818 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3820 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3823 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3824 throw(SALOME::SALOME_Exception)
3826 Unexpect aCatch(SALOME_SalomeException);
3828 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3830 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3833 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3834 throw(SALOME::SALOME_Exception)
3836 Unexpect aCatch(SALOME_SalomeException);
3838 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3840 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3843 //=============================================================================
3845 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3847 Unexpect aCatch(SALOME_SalomeException);
3849 return _preMeshInfo->NbVolumes();
3851 return _impl->NbVolumes();
3854 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3856 Unexpect aCatch(SALOME_SalomeException);
3858 return _preMeshInfo->NbTetras();
3860 return _impl->NbTetras();
3863 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbHexas();
3869 return _impl->NbHexas();
3872 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 return _preMeshInfo->NbTriQuadHexas();
3878 return _impl->NbTriQuadraticHexas();
3881 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbPyramids();
3887 return _impl->NbPyramids();
3890 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3892 Unexpect aCatch(SALOME_SalomeException);
3894 return _preMeshInfo->NbPrisms();
3896 return _impl->NbPrisms();
3899 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3901 Unexpect aCatch(SALOME_SalomeException);
3903 return _preMeshInfo->NbHexPrisms();
3905 return _impl->NbHexagonalPrisms();
3908 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbPolyhedrons();
3914 return _impl->NbPolyhedrons();
3917 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3918 throw(SALOME::SALOME_Exception)
3920 Unexpect aCatch(SALOME_SalomeException);
3922 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3924 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3927 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3928 throw(SALOME::SALOME_Exception)
3930 Unexpect aCatch(SALOME_SalomeException);
3932 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3934 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3937 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3938 throw(SALOME::SALOME_Exception)
3940 Unexpect aCatch(SALOME_SalomeException);
3942 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3944 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3947 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3948 throw(SALOME::SALOME_Exception)
3950 Unexpect aCatch(SALOME_SalomeException);
3952 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3954 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3957 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3958 throw(SALOME::SALOME_Exception)
3960 Unexpect aCatch(SALOME_SalomeException);
3962 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3964 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3967 //=============================================================================
3969 * Returns nb of published sub-meshes
3971 //=============================================================================
3973 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3975 Unexpect aCatch(SALOME_SalomeException);
3976 return _mapSubMesh_i.size();
3979 //=============================================================================
3981 * Dumps mesh into a string
3983 //=============================================================================
3985 char* SMESH_Mesh_i::Dump()
3989 return CORBA::string_dup( os.str().c_str() );
3992 //=============================================================================
3994 * Method of SMESH_IDSource interface
3996 //=============================================================================
3998 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4000 return GetElementsId();
4003 //=============================================================================
4005 * Returns ids of all elements
4007 //=============================================================================
4009 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4010 throw (SALOME::SALOME_Exception)
4012 Unexpect aCatch(SALOME_SalomeException);
4014 _preMeshInfo->FullLoadFromFile();
4016 SMESH::long_array_var aResult = new SMESH::long_array();
4017 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4019 if ( aSMESHDS_Mesh == NULL )
4020 return aResult._retn();
4022 long nbElements = NbElements();
4023 aResult->length( nbElements );
4024 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4025 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4026 aResult[i] = anIt->next()->GetID();
4028 return aResult._retn();
4032 //=============================================================================
4034 * Returns ids of all elements of given type
4036 //=============================================================================
4038 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4039 throw (SALOME::SALOME_Exception)
4041 Unexpect aCatch(SALOME_SalomeException);
4043 _preMeshInfo->FullLoadFromFile();
4045 SMESH::long_array_var aResult = new SMESH::long_array();
4046 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4048 if ( aSMESHDS_Mesh == NULL )
4049 return aResult._retn();
4051 long nbElements = NbElements();
4053 // No sense in returning ids of elements along with ids of nodes:
4054 // when theElemType == SMESH::ALL, return node ids only if
4055 // there are no elements
4056 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4057 return GetNodesId();
4059 aResult->length( nbElements );
4063 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4064 while ( i < nbElements && anIt->more() )
4065 aResult[i++] = anIt->next()->GetID();
4067 aResult->length( i );
4069 return aResult._retn();
4072 //=============================================================================
4074 * Returns ids of all nodes
4076 //=============================================================================
4078 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4079 throw (SALOME::SALOME_Exception)
4081 Unexpect aCatch(SALOME_SalomeException);
4083 _preMeshInfo->FullLoadFromFile();
4085 SMESH::long_array_var aResult = new SMESH::long_array();
4086 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4088 if ( aMeshDS == NULL )
4089 return aResult._retn();
4091 long nbNodes = NbNodes();
4092 aResult->length( nbNodes );
4093 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4094 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4095 aResult[i] = anIt->next()->GetID();
4097 return aResult._retn();
4100 //=============================================================================
4104 //=============================================================================
4106 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4107 throw (SALOME::SALOME_Exception)
4109 SMESH::ElementType type = SMESH::ALL;
4113 _preMeshInfo->FullLoadFromFile();
4115 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4117 SMESH_CATCH( SMESH::throwCorbaException );
4122 //=============================================================================
4126 //=============================================================================
4128 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4129 throw (SALOME::SALOME_Exception)
4132 _preMeshInfo->FullLoadFromFile();
4134 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4136 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4138 return ( SMESH::EntityType ) e->GetEntityType();
4141 //=============================================================================
4145 //=============================================================================
4147 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4148 throw (SALOME::SALOME_Exception)
4151 _preMeshInfo->FullLoadFromFile();
4153 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4155 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4157 return ( SMESH::GeometryType ) e->GetGeomType();
4160 //=============================================================================
4162 * Returns ID of elements for given submesh
4164 //=============================================================================
4165 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4166 throw (SALOME::SALOME_Exception)
4168 SMESH::long_array_var aResult = new SMESH::long_array();
4172 _preMeshInfo->FullLoadFromFile();
4174 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4175 if(!SM) return aResult._retn();
4177 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4178 if(!SDSM) return aResult._retn();
4180 aResult->length(SDSM->NbElements());
4182 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4184 while ( eIt->more() ) {
4185 aResult[i++] = eIt->next()->GetID();
4188 SMESH_CATCH( SMESH::throwCorbaException );
4190 return aResult._retn();
4193 //=============================================================================
4195 * Returns ID of nodes for given submesh
4196 * If param all==true - returns all nodes, else -
4197 * returns only nodes on shapes.
4199 //=============================================================================
4201 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4203 throw (SALOME::SALOME_Exception)
4205 SMESH::long_array_var aResult = new SMESH::long_array();
4209 _preMeshInfo->FullLoadFromFile();
4211 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4212 if(!SM) return aResult._retn();
4214 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4215 if(!SDSM) return aResult._retn();
4218 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4219 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4220 while ( nIt->more() ) {
4221 const SMDS_MeshNode* elem = nIt->next();
4222 theElems.insert( elem->GetID() );
4225 else { // all nodes of submesh elements
4226 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4227 while ( eIt->more() ) {
4228 const SMDS_MeshElement* anElem = eIt->next();
4229 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4230 while ( nIt->more() ) {
4231 const SMDS_MeshElement* elem = nIt->next();
4232 theElems.insert( elem->GetID() );
4237 aResult->length(theElems.size());
4238 set<int>::iterator itElem;
4240 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4241 aResult[i++] = *itElem;
4243 SMESH_CATCH( SMESH::throwCorbaException );
4245 return aResult._retn();
4248 //=============================================================================
4250 * Returns type of elements for given submesh
4252 //=============================================================================
4254 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4255 throw (SALOME::SALOME_Exception)
4257 SMESH::ElementType type = SMESH::ALL;
4261 _preMeshInfo->FullLoadFromFile();
4263 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4264 if(!SM) return SMESH::ALL;
4266 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4267 if(!SDSM) return SMESH::ALL;
4269 if(SDSM->NbElements()==0)
4270 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4272 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4273 const SMDS_MeshElement* anElem = eIt->next();
4275 type = ( SMESH::ElementType ) anElem->GetType();
4277 SMESH_CATCH( SMESH::throwCorbaException );
4283 //=============================================================================
4285 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4287 //=============================================================================
4289 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4292 _preMeshInfo->FullLoadFromFile();
4294 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4295 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4300 //=============================================================================
4302 * Get XYZ coordinates of node as list of double
4303 * If there is not node for given ID - returns empty list
4305 //=============================================================================
4307 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4310 _preMeshInfo->FullLoadFromFile();
4312 SMESH::double_array_var aResult = new SMESH::double_array();
4313 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4314 if ( aMeshDS == NULL )
4315 return aResult._retn();
4318 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4320 return aResult._retn();
4324 aResult[0] = aNode->X();
4325 aResult[1] = aNode->Y();
4326 aResult[2] = aNode->Z();
4327 return aResult._retn();
4331 //=============================================================================
4333 * For given node returns list of IDs of inverse elements
4334 * If there is not node for given ID - returns empty list
4336 //=============================================================================
4338 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4341 _preMeshInfo->FullLoadFromFile();
4343 SMESH::long_array_var aResult = new SMESH::long_array();
4344 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4345 if ( aMeshDS == NULL )
4346 return aResult._retn();
4349 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4351 return aResult._retn();
4353 // find inverse elements
4354 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4355 aResult->length( aNode->NbInverseElements() );
4356 for( int i = 0; eIt->more(); ++i )
4358 const SMDS_MeshElement* elem = eIt->next();
4359 aResult[ i ] = elem->GetID();
4361 return aResult._retn();
4364 //=============================================================================
4366 * \brief Return position of a node on shape
4368 //=============================================================================
4370 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4373 _preMeshInfo->FullLoadFromFile();
4375 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4376 aNodePosition->shapeID = 0;
4377 aNodePosition->shapeType = GEOM::SHAPE;
4379 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4380 if ( !mesh ) return aNodePosition;
4382 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4384 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4386 aNodePosition->shapeID = aNode->getshapeId();
4387 switch ( pos->GetTypeOfPosition() ) {
4389 aNodePosition->shapeType = GEOM::EDGE;
4390 aNodePosition->params.length(1);
4391 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4393 case SMDS_TOP_FACE: {
4394 SMDS_FacePositionPtr fPos = pos;
4395 aNodePosition->shapeType = GEOM::FACE;
4396 aNodePosition->params.length(2);
4397 aNodePosition->params[0] = fPos->GetUParameter();
4398 aNodePosition->params[1] = fPos->GetVParameter();
4401 case SMDS_TOP_VERTEX:
4402 aNodePosition->shapeType = GEOM::VERTEX;
4404 case SMDS_TOP_3DSPACE:
4405 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4406 aNodePosition->shapeType = GEOM::SOLID;
4407 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4408 aNodePosition->shapeType = GEOM::SHELL;
4414 return aNodePosition;
4417 //=============================================================================
4419 * \brief Return position of an element on shape
4421 //=============================================================================
4423 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4426 _preMeshInfo->FullLoadFromFile();
4428 SMESH::ElementPosition anElementPosition;
4429 anElementPosition.shapeID = 0;
4430 anElementPosition.shapeType = GEOM::SHAPE;
4432 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4433 if ( !mesh ) return anElementPosition;
4435 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4437 anElementPosition.shapeID = anElem->getshapeId();
4438 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4439 if ( !aSp.IsNull() ) {
4440 switch ( aSp.ShapeType() ) {
4442 anElementPosition.shapeType = GEOM::EDGE;
4445 anElementPosition.shapeType = GEOM::FACE;
4448 anElementPosition.shapeType = GEOM::VERTEX;
4451 anElementPosition.shapeType = GEOM::SOLID;
4454 anElementPosition.shapeType = GEOM::SHELL;
4460 return anElementPosition;
4463 //=============================================================================
4465 * If given element is node returns IDs of shape from position
4466 * If there is not node for given ID - returns -1
4468 //=============================================================================
4470 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4473 _preMeshInfo->FullLoadFromFile();
4475 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4476 if ( aMeshDS == NULL )
4480 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4482 return aNode->getshapeId();
4489 //=============================================================================
4491 * For given element returns ID of result shape after
4492 * ::FindShape() from SMESH_MeshEditor
4493 * If there is not element for given ID - returns -1
4495 //=============================================================================
4497 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4500 _preMeshInfo->FullLoadFromFile();
4502 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4503 if ( aMeshDS == NULL )
4506 // try to find element
4507 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4511 ::SMESH_MeshEditor aMeshEditor(_impl);
4512 int index = aMeshEditor.FindShape( elem );
4520 //=============================================================================
4522 * Returns number of nodes for given element
4523 * If there is not element for given ID - returns -1
4525 //=============================================================================
4527 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4530 _preMeshInfo->FullLoadFromFile();
4532 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4533 if ( aMeshDS == NULL ) return -1;
4534 // try to find element
4535 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4536 if(!elem) return -1;
4537 return elem->NbNodes();
4541 //=============================================================================
4543 * Returns ID of node by given index for given element
4544 * If there is not element for given ID - returns -1
4545 * If there is not node for given index - returns -2
4547 //=============================================================================
4549 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4552 _preMeshInfo->FullLoadFromFile();
4554 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4555 if ( aMeshDS == NULL ) return -1;
4556 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4557 if(!elem) return -1;
4558 if( index>=elem->NbNodes() || index<0 ) return -1;
4559 return elem->GetNode(index)->GetID();
4562 //=============================================================================
4564 * Returns IDs of nodes of given element
4566 //=============================================================================
4568 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4571 _preMeshInfo->FullLoadFromFile();
4573 SMESH::long_array_var aResult = new SMESH::long_array();
4574 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4576 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4578 aResult->length( elem->NbNodes() );
4579 for ( int i = 0; i < elem->NbNodes(); ++i )
4580 aResult[ i ] = elem->GetNode( i )->GetID();
4583 return aResult._retn();
4586 //=============================================================================
4588 * Returns true if given node is medium node
4589 * in given quadratic element
4591 //=============================================================================
4593 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4596 _preMeshInfo->FullLoadFromFile();
4598 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4599 if ( aMeshDS == NULL ) return false;
4601 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4602 if(!aNode) return false;
4603 // try to find element
4604 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4605 if(!elem) return false;
4607 return elem->IsMediumNode(aNode);
4611 //=============================================================================
4613 * Returns true if given node is medium node
4614 * in one of quadratic elements
4616 //=============================================================================
4618 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4619 SMESH::ElementType theElemType)
4622 _preMeshInfo->FullLoadFromFile();
4624 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4625 if ( aMeshDS == NULL ) return false;
4628 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4629 if(!aNode) return false;
4631 SMESH_MesherHelper aHelper( *(_impl) );
4633 SMDSAbs_ElementType aType;
4634 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4635 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4636 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4637 else aType = SMDSAbs_All;
4639 return aHelper.IsMedium(aNode,aType);
4643 //=============================================================================
4645 * Returns number of edges for given element
4647 //=============================================================================
4649 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4652 _preMeshInfo->FullLoadFromFile();
4654 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4655 if ( aMeshDS == NULL ) return -1;
4656 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4657 if(!elem) return -1;
4658 return elem->NbEdges();
4662 //=============================================================================
4664 * Returns number of faces for given element
4666 //=============================================================================
4668 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4671 _preMeshInfo->FullLoadFromFile();
4673 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4674 if ( aMeshDS == NULL ) return -1;
4675 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4676 if(!elem) return -1;
4677 return elem->NbFaces();
4680 //=======================================================================
4681 //function : GetElemFaceNodes
4682 //purpose : Returns nodes of given face (counted from zero) for given element.
4683 //=======================================================================
4685 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4686 CORBA::Short faceIndex)
4689 _preMeshInfo->FullLoadFromFile();
4691 SMESH::long_array_var aResult = new SMESH::long_array();
4692 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4694 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4696 SMDS_VolumeTool vtool( elem );
4697 if ( faceIndex < vtool.NbFaces() )
4699 aResult->length( vtool.NbFaceNodes( faceIndex ));
4700 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4701 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4702 aResult[ i ] = nn[ i ]->GetID();
4706 return aResult._retn();
4709 //=======================================================================
4710 //function : GetElemFaceNodes
4711 //purpose : Returns three components of normal of given mesh face.
4712 //=======================================================================
4714 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4715 CORBA::Boolean normalized)
4718 _preMeshInfo->FullLoadFromFile();
4720 SMESH::double_array_var aResult = new SMESH::double_array();
4722 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4725 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4727 aResult->length( 3 );
4728 aResult[ 0 ] = normal.X();
4729 aResult[ 1 ] = normal.Y();
4730 aResult[ 2 ] = normal.Z();
4733 return aResult._retn();
4736 //=======================================================================
4737 //function : FindElementByNodes
4738 //purpose : Returns an element based on all given nodes.
4739 //=======================================================================
4741 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4744 _preMeshInfo->FullLoadFromFile();
4746 CORBA::Long elemID(0);
4747 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4749 vector< const SMDS_MeshNode * > nn( nodes.length() );
4750 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4751 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4754 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4755 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4756 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4757 _impl->NbVolumes( ORDER_QUADRATIC )))
4758 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4760 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4765 //================================================================================
4767 * \brief Return elements including all given nodes.
4769 //================================================================================
4771 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4772 SMESH::ElementType elemType)
4775 _preMeshInfo->FullLoadFromFile();
4777 SMESH::long_array_var result = new SMESH::long_array();
4779 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4781 vector< const SMDS_MeshNode * > nn( nodes.length() );
4782 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4783 nn[i] = mesh->FindNode( nodes[i] );
4785 std::vector<const SMDS_MeshElement *> elems;
4786 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4787 result->length( elems.size() );
4788 for ( size_t i = 0; i < elems.size(); ++i )
4789 result[i] = elems[i]->GetID();
4791 return result._retn();
4794 //=============================================================================
4796 * Returns true if given element is polygon
4798 //=============================================================================
4800 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4803 _preMeshInfo->FullLoadFromFile();
4805 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4806 if ( aMeshDS == NULL ) return false;
4807 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4808 if(!elem) return false;
4809 return elem->IsPoly();
4813 //=============================================================================
4815 * Returns true if given element is quadratic
4817 //=============================================================================
4819 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4822 _preMeshInfo->FullLoadFromFile();
4824 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4825 if ( aMeshDS == NULL ) return false;
4826 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4827 if(!elem) return false;
4828 return elem->IsQuadratic();
4831 //=============================================================================
4833 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4835 //=============================================================================
4837 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4840 _preMeshInfo->FullLoadFromFile();
4842 if ( const SMDS_BallElement* ball =
4843 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4844 return ball->GetDiameter();
4849 //=============================================================================
4851 * Returns bary center for given element
4853 //=============================================================================
4855 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4858 _preMeshInfo->FullLoadFromFile();
4860 SMESH::double_array_var aResult = new SMESH::double_array();
4861 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4862 if ( aMeshDS == NULL )
4863 return aResult._retn();
4865 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4867 return aResult._retn();
4869 if(elem->GetType()==SMDSAbs_Volume) {
4870 SMDS_VolumeTool aTool;
4871 if(aTool.Set(elem)) {
4873 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4878 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4880 double x=0., y=0., z=0.;
4881 for(; anIt->more(); ) {
4883 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4897 return aResult._retn();
4900 //================================================================================
4902 * \brief Create a group of elements preventing computation of a sub-shape
4904 //================================================================================
4906 SMESH::ListOfGroups*
4907 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4908 const char* theGroupName )
4909 throw ( SALOME::SALOME_Exception )
4911 Unexpect aCatch(SALOME_SalomeException);
4913 if ( !theGroupName || strlen( theGroupName) == 0 )
4914 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4916 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4917 ::SMESH_MeshEditor::ElemFeatures elemType;
4919 // submesh by subshape id
4920 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4921 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4924 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4925 if ( error && error->HasBadElems() )
4927 // sort bad elements by type
4928 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4929 const list<const SMDS_MeshElement*>& badElems =
4930 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4931 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4932 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4933 for ( ; elemIt != elemEnd; ++elemIt )
4935 const SMDS_MeshElement* elem = *elemIt;
4936 if ( !elem ) continue;
4938 if ( elem->GetID() < 1 )
4940 // elem is a temporary element, make a real element
4941 vector< const SMDS_MeshNode* > nodes;
4942 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4943 while ( nIt->more() && elem )
4945 nodes.push_back( nIt->next() );
4946 if ( nodes.back()->GetID() < 1 )
4947 elem = 0; // a temporary element on temporary nodes
4951 ::SMESH_MeshEditor editor( _impl );
4952 elem = editor.AddElement( nodes, elemType.Init( elem ));
4956 elemsByType[ elem->GetType() ].push_back( elem );
4959 // how many groups to create?
4961 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4962 nbTypes += int( !elemsByType[ i ].empty() );
4963 groups->length( nbTypes );
4966 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4968 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4969 if ( elems.empty() ) continue;
4971 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4972 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4974 SMESH::SMESH_Mesh_var mesh = _this();
4975 SALOMEDS::SObject_wrap aSO =
4976 _gen_i->PublishGroup( mesh, groups[ iG ],
4977 GEOM::GEOM_Object::_nil(), theGroupName);
4979 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4980 if ( !grp_i ) continue;
4982 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4983 for ( size_t iE = 0; iE < elems.size(); ++iE )
4984 grpDS->SMDSGroup().Add( elems[ iE ]);
4989 return groups._retn();
4992 //=============================================================================
4994 * Create and publish group servants if any groups were imported or created anyhow
4996 //=============================================================================
4998 void SMESH_Mesh_i::CreateGroupServants()
5000 SMESH::SMESH_Mesh_var aMesh = _this();
5003 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5004 while ( groupIt->more() )
5006 ::SMESH_Group* group = groupIt->next();
5007 int anId = group->GetGroupDS()->GetID();
5009 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5010 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5012 addedIDs.insert( anId );
5014 SMESH_GroupBase_i* aGroupImpl;
5016 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5017 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5019 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5020 shape = groupOnGeom->GetShape();
5023 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5026 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5027 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5028 aGroupImpl->Register();
5030 // register CORBA object for persistence
5031 int nextId = _gen_i->RegisterObject( groupVar );
5032 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5033 else { nextId = 0; } // avoid "unused variable" warning in release mode
5035 // publishing the groups in the study
5036 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5037 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5039 if ( !addedIDs.empty() )
5042 set<int>::iterator id = addedIDs.begin();
5043 for ( ; id != addedIDs.end(); ++id )
5045 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5046 int i = std::distance( _mapGroups.begin(), it );
5047 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5052 //=============================================================================
5054 * \brief Return true if all sub-meshes are computed OK - to update an icon
5056 //=============================================================================
5058 bool SMESH_Mesh_i::IsComputedOK()
5060 return _impl->IsComputedOK();
5063 //=============================================================================
5065 * \brief Return groups cantained in _mapGroups by their IDs
5067 //=============================================================================
5069 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5071 int nbGroups = groupIDs.size();
5072 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5073 aList->length( nbGroups );
5075 list<int>::const_iterator ids = groupIDs.begin();
5076 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5078 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5079 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5080 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5082 aList->length( nbGroups );
5083 return aList._retn();
5086 //=============================================================================
5088 * \brief Return information about imported file
5090 //=============================================================================
5092 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5094 SMESH::MedFileInfo_var res( _medFileInfo );
5095 if ( !res.operator->() ) {
5096 res = new SMESH::MedFileInfo;
5098 res->fileSize = res->major = res->minor = res->release = -1;
5103 //=======================================================================
5104 //function : FileInfoToString
5105 //purpose : Persistence of file info
5106 //=======================================================================
5108 std::string SMESH_Mesh_i::FileInfoToString()
5111 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5113 s = SMESH_Comment( _medFileInfo->fileSize )
5114 << " " << _medFileInfo->major
5115 << " " << _medFileInfo->minor
5116 << " " << _medFileInfo->release
5117 << " " << _medFileInfo->fileName;
5122 //=======================================================================
5123 //function : FileInfoFromString
5124 //purpose : Persistence of file info
5125 //=======================================================================
5127 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5129 std::string size, major, minor, release, fileName;
5130 std::istringstream is(info);
5131 is >> size >> major >> minor >> release;
5132 fileName = info.data() + ( size.size() + 1 +
5135 release.size()+ 1 );
5137 _medFileInfo = new SMESH::MedFileInfo();
5138 _medFileInfo->fileName = fileName.c_str();
5139 _medFileInfo->fileSize = atoi( size.c_str() );
5140 _medFileInfo->major = atoi( major.c_str() );
5141 _medFileInfo->minor = atoi( minor.c_str() );
5142 _medFileInfo->release = atoi( release.c_str() );
5145 //=============================================================================
5147 * \brief Pass names of mesh groups from study to mesh DS
5149 //=============================================================================
5151 void SMESH_Mesh_i::checkGroupNames()
5153 int nbGrp = NbGroups();
5157 SMESH::ListOfGroups* grpList = 0;
5158 // avoid dump of "GetGroups"
5160 // store python dump into a local variable inside local scope
5161 SMESH::TPythonDump pDump; // do not delete this line of code
5162 grpList = GetGroups();
5165 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5166 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5169 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5170 if ( aGrpSO->_is_nil() )
5172 // correct name of the mesh group if necessary
5173 const char* guiName = aGrpSO->GetName();
5174 if ( strcmp(guiName, aGrp->GetName()) )
5175 aGrp->SetName( guiName );
5179 //=============================================================================
5181 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5183 //=============================================================================
5184 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5186 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5190 //=============================================================================
5192 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5194 //=============================================================================
5196 char* SMESH_Mesh_i::GetParameters()
5198 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5201 //=============================================================================
5203 * \brief Returns list of notebook variables used for last Mesh operation
5205 //=============================================================================
5206 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5208 SMESH::string_array_var aResult = new SMESH::string_array();
5209 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5211 CORBA::String_var aParameters = GetParameters();
5212 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5213 if ( aSections->length() > 0 ) {
5214 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5215 aResult->length( aVars.length() );
5216 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5217 aResult[i] = CORBA::string_dup( aVars[i] );
5220 return aResult._retn();
5223 //=======================================================================
5224 //function : GetTypes
5225 //purpose : Returns types of elements it contains
5226 //=======================================================================
5228 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5231 return _preMeshInfo->GetTypes();
5233 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5237 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5238 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5239 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5240 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5241 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5242 if (_impl->NbNodes() &&
5243 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5244 types->length( nbTypes );
5246 return types._retn();
5249 //=======================================================================
5250 //function : GetMesh
5251 //purpose : Returns self
5252 //=======================================================================
5254 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5256 return SMESH::SMESH_Mesh::_duplicate( _this() );
5259 //=======================================================================
5260 //function : IsMeshInfoCorrect
5261 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5262 // * happen if mesh data is not yet fully loaded from the file of study.
5263 //=======================================================================
5265 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5267 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5270 //=============================================================================
5272 * \brief Returns number of mesh elements per each \a EntityType
5274 //=============================================================================
5276 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5279 return _preMeshInfo->GetMeshInfo();
5281 SMESH::long_array_var aRes = new SMESH::long_array();
5282 aRes->length(SMESH::Entity_Last);
5283 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5285 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5287 return aRes._retn();
5288 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5289 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5290 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5291 return aRes._retn();
5294 //=============================================================================
5296 * \brief Returns number of mesh elements per each \a ElementType
5298 //=============================================================================
5300 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5302 SMESH::long_array_var aRes = new SMESH::long_array();
5303 aRes->length(SMESH::NB_ELEMENT_TYPES);
5304 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5307 const SMDS_MeshInfo* meshInfo = 0;
5309 meshInfo = _preMeshInfo;
5310 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5311 meshInfo = & meshDS->GetMeshInfo();
5314 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5315 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5317 return aRes._retn();
5320 //=============================================================================
5322 * Collect statistic of mesh elements given by iterator
5324 //=============================================================================
5326 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5327 SMESH::long_array& theInfo)
5329 if (!theItr) return;
5330 while (theItr->more())
5331 theInfo[ theItr->next()->GetEntityType() ]++;
5333 //=============================================================================
5335 * Returns mesh unstructed grid information.
5337 //=============================================================================
5339 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5341 SALOMEDS::TMPFile_var SeqFile;
5342 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5343 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5345 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5346 aWriter->WriteToOutputStringOn();
5347 aWriter->SetInputData(aGrid);
5348 aWriter->SetFileTypeToBinary();
5350 char* str = aWriter->GetOutputString();
5351 int size = aWriter->GetOutputStringLength();
5353 //Allocate octect buffer of required size
5354 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5355 //Copy ostrstream content to the octect buffer
5356 memcpy(OctetBuf, str, size);
5357 //Create and return TMPFile
5358 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5362 return SeqFile._retn();
5365 //=============================================================================
5366 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5367 * SMESH::ElementType type) */
5369 using namespace SMESH::Controls;
5370 //-----------------------------------------------------------------------------
5371 struct PredicateIterator : public SMDS_ElemIterator
5373 SMDS_ElemIteratorPtr _elemIter;
5374 PredicatePtr _predicate;
5375 const SMDS_MeshElement* _elem;
5377 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5378 PredicatePtr predicate):
5379 _elemIter(iterator), _predicate(predicate)
5387 virtual const SMDS_MeshElement* next()
5389 const SMDS_MeshElement* res = _elem;
5391 while ( _elemIter->more() && !_elem )
5393 _elem = _elemIter->next();
5394 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5401 //-----------------------------------------------------------------------------
5402 struct IDSourceIterator : public SMDS_ElemIterator
5404 const CORBA::Long* _idPtr;
5405 const CORBA::Long* _idEndPtr;
5406 SMESH::long_array_var _idArray;
5407 const SMDS_Mesh* _mesh;
5408 const SMDSAbs_ElementType _type;
5409 const SMDS_MeshElement* _elem;
5411 IDSourceIterator( const SMDS_Mesh* mesh,
5412 const CORBA::Long* ids,
5414 SMDSAbs_ElementType type):
5415 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5417 if ( _idPtr && nbIds && _mesh )
5420 IDSourceIterator( const SMDS_Mesh* mesh,
5421 SMESH::long_array* idArray,
5422 SMDSAbs_ElementType type):
5423 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5425 if ( idArray && _mesh )
5427 _idPtr = &_idArray[0];
5428 _idEndPtr = _idPtr + _idArray->length();
5436 virtual const SMDS_MeshElement* next()
5438 const SMDS_MeshElement* res = _elem;
5440 while ( _idPtr < _idEndPtr && !_elem )
5442 if ( _type == SMDSAbs_Node )
5444 _elem = _mesh->FindNode( *_idPtr++ );
5446 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5447 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5455 //-----------------------------------------------------------------------------
5457 struct NodeOfElemIterator : public SMDS_ElemIterator
5459 TColStd_MapOfInteger _checkedNodeIDs;
5460 SMDS_ElemIteratorPtr _elemIter;
5461 SMDS_ElemIteratorPtr _nodeIter;
5462 const SMDS_MeshElement* _node;
5464 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5466 if ( _elemIter && _elemIter->more() )
5468 _nodeIter = _elemIter->next()->nodesIterator();
5476 virtual const SMDS_MeshElement* next()
5478 const SMDS_MeshElement* res = _node;
5480 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5482 if ( _nodeIter->more() )
5484 _node = _nodeIter->next();
5485 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5490 _nodeIter = _elemIter->next()->nodesIterator();
5498 //=============================================================================
5500 * Return iterator on elements of given type in given object
5502 //=============================================================================
5504 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5505 SMESH::ElementType theType)
5507 SMDS_ElemIteratorPtr elemIt;
5508 bool typeOK = ( theType == SMESH::ALL );
5509 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5511 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5512 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5513 if ( !mesh_i ) return elemIt;
5514 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5516 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5518 elemIt = meshDS->elementsIterator( elemType );
5521 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5523 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5526 elemIt = sm->GetElements();
5527 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5529 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5530 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5534 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5536 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5537 if ( groupDS && ( elemType == groupDS->GetType() ||
5538 elemType == SMDSAbs_Node ||
5539 elemType == SMDSAbs_All ))
5541 elemIt = groupDS->GetElements();
5542 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5545 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5547 if ( filter_i->GetElementType() == theType ||
5548 elemType == SMDSAbs_Node ||
5549 elemType == SMDSAbs_All)
5551 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5552 if ( pred_i && pred_i->GetPredicate() )
5554 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5555 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5556 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5557 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5563 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5564 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5565 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5567 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5570 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5571 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5575 SMESH::long_array_var ids = theObject->GetIDs();
5576 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5578 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5581 if ( elemIt && elemIt->more() && !typeOK )
5583 if ( elemType == SMDSAbs_Node )
5585 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5589 elemIt = SMDS_ElemIteratorPtr();
5595 //=============================================================================
5596 namespace // Finding concurrent hypotheses
5597 //=============================================================================
5601 * \brief mapping of mesh dimension into shape type
5603 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5605 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5607 case 0: aType = TopAbs_VERTEX; break;
5608 case 1: aType = TopAbs_EDGE; break;
5609 case 2: aType = TopAbs_FACE; break;
5611 default:aType = TopAbs_SOLID; break;
5616 //-----------------------------------------------------------------------------
5618 * \brief Internal structure used to find concurrent submeshes
5620 * It represents a pair < submesh, concurrent dimension >, where
5621 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5622 * with another submesh. In other words, it is dimension of a hypothesis assigned
5629 int _dim; //!< a dimension the algo can build (concurrent dimension)
5630 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5631 TopTools_MapOfShape _shapeMap;
5632 SMESH_subMesh* _subMesh;
5633 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5635 //-----------------------------------------------------------------------------
5636 // Return the algorithm
5637 const SMESH_Algo* GetAlgo() const
5638 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5640 //-----------------------------------------------------------------------------
5642 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5644 const TopoDS_Shape& theShape)
5646 _subMesh = (SMESH_subMesh*)theSubMesh;
5647 SetShape( theDim, theShape );
5650 //-----------------------------------------------------------------------------
5652 void SetShape(const int theDim,
5653 const TopoDS_Shape& theShape)
5656 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5657 if (_dim >= _ownDim)
5658 _shapeMap.Add( theShape );
5660 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5661 for( ; anExp.More(); anExp.Next() )
5662 _shapeMap.Add( anExp.Current() );
5666 //-----------------------------------------------------------------------------
5667 //! Check sharing of sub-shapes
5668 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5669 const TopTools_MapOfShape& theToFind,
5670 const TopAbs_ShapeEnum theType)
5672 bool isShared = false;
5673 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5674 for (; !isShared && anItr.More(); anItr.Next() )
5676 const TopoDS_Shape aSubSh = anItr.Key();
5677 // check for case when concurrent dimensions are same
5678 isShared = theToFind.Contains( aSubSh );
5679 // check for sub-shape with concurrent dimension
5680 TopExp_Explorer anExp( aSubSh, theType );
5681 for ( ; !isShared && anExp.More(); anExp.Next() )
5682 isShared = theToFind.Contains( anExp.Current() );
5687 //-----------------------------------------------------------------------------
5688 //! check algorithms
5689 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5690 const SMESHDS_Hypothesis* theA2)
5692 if ( !theA1 || !theA2 ||
5693 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5694 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5695 return false; // one of the hypothesis is not algorithm
5696 // check algorithm names (should be equal)
5697 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5701 //-----------------------------------------------------------------------------
5702 //! Check if sub-shape hypotheses are concurrent
5703 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5705 if ( _subMesh == theOther->_subMesh )
5706 return false; // same sub-shape - should not be
5708 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5709 // any of the two submeshes is not on COMPOUND shape )
5710 // -> no concurrency
5711 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5712 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5713 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5714 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5715 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5718 // bool checkSubShape = ( _dim >= theOther->_dim )
5719 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5720 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5721 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5722 if ( !checkSubShape )
5725 // check algorithms to be same
5726 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5727 return true; // different algorithms -> concurrency !
5729 // check hypothesises for concurrence (skip first as algorithm)
5731 // pointers should be same, because it is referened from mesh hypothesis partition
5732 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5733 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5734 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5735 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5737 // the submeshes are concurrent if their algorithms has different parameters
5738 return nbSame != (int)theOther->_hypotheses.size() - 1;
5741 // Return true if algorithm of this SMESH_DimHyp is used if no
5742 // sub-mesh order is imposed by the user
5743 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5745 // NeedDiscreteBoundary() algo has a higher priority
5746 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5747 theOther->GetAlgo()->NeedDiscreteBoundary() )
5748 return !this->GetAlgo()->NeedDiscreteBoundary();
5750 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5753 }; // end of SMESH_DimHyp
5754 //-----------------------------------------------------------------------------
5756 typedef list<const SMESH_DimHyp*> TDimHypList;
5758 //-----------------------------------------------------------------------------
5760 void addDimHypInstance(const int theDim,
5761 const TopoDS_Shape& theShape,
5762 const SMESH_Algo* theAlgo,
5763 const SMESH_subMesh* theSubMesh,
5764 const list <const SMESHDS_Hypothesis*>& theHypList,
5765 TDimHypList* theDimHypListArr )
5767 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5768 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5769 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5770 dimHyp->_hypotheses.push_front(theAlgo);
5771 listOfdimHyp.push_back( dimHyp );
5774 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5775 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5776 theHypList.begin(), theHypList.end() );
5779 //-----------------------------------------------------------------------------
5780 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5781 TDimHypList& theListOfConcurr)
5783 if ( theListOfConcurr.empty() )
5785 theListOfConcurr.push_back( theDimHyp );
5789 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5790 while ( hypIt != theListOfConcurr.end() &&
5791 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5793 theListOfConcurr.insert( hypIt, theDimHyp );
5797 //-----------------------------------------------------------------------------
5798 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5799 const TDimHypList& theListOfDimHyp,
5800 TDimHypList& theListOfConcurrHyp,
5801 set<int>& theSetOfConcurrId )
5803 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5804 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5806 const SMESH_DimHyp* curDimHyp = *rIt;
5807 if ( curDimHyp == theDimHyp )
5808 break; // meet own dimHyp pointer in same dimension
5810 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5811 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5813 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5818 //-----------------------------------------------------------------------------
5819 void unionLists(TListOfInt& theListOfId,
5820 TListOfListOfInt& theListOfListOfId,
5823 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5824 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5826 continue; //skip already treated lists
5827 // check if other list has any same submesh object
5828 TListOfInt& otherListOfId = *it;
5829 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5830 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5833 // union two lists (from source into target)
5834 TListOfInt::iterator it2 = otherListOfId.begin();
5835 for ( ; it2 != otherListOfId.end(); it2++ ) {
5836 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5837 theListOfId.push_back(*it2);
5839 // clear source list
5840 otherListOfId.clear();
5843 //-----------------------------------------------------------------------------
5845 //! free memory allocated for dimension-hypothesis objects
5846 void removeDimHyps( TDimHypList* theArrOfList )
5848 for (int i = 0; i < 4; i++ ) {
5849 TDimHypList& listOfdimHyp = theArrOfList[i];
5850 TDimHypList::const_iterator it = listOfdimHyp.begin();
5851 for ( ; it != listOfdimHyp.end(); it++ )
5856 //-----------------------------------------------------------------------------
5858 * \brief find common submeshes with given submesh
5859 * \param theSubMeshList list of already collected submesh to check
5860 * \param theSubMesh given submesh to intersect with other
5861 * \param theCommonSubMeshes collected common submeshes
5863 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5864 const SMESH_subMesh* theSubMesh,
5865 set<const SMESH_subMesh*>& theCommon )
5869 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5870 for ( ; it != theSubMeshList.end(); it++ )
5871 theSubMesh->FindIntersection( *it, theCommon );
5872 theSubMeshList.push_back( theSubMesh );
5873 //theCommon.insert( theSubMesh );
5876 //-----------------------------------------------------------------------------
5877 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5879 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5880 for ( ; listsIt != smLists.end(); ++listsIt )
5882 const TListOfInt& smIDs = *listsIt;
5883 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5891 //=============================================================================
5893 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5895 //=============================================================================
5897 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5899 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5900 if ( isSubMeshInList( submeshID, anOrder ))
5903 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5904 return isSubMeshInList( submeshID, allConurrent );
5907 //=============================================================================
5909 * \brief Return submesh objects list in meshing order
5911 //=============================================================================
5913 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5915 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5917 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5919 return aResult._retn();
5921 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5922 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5923 anOrder.splice( anOrder.end(), allConurrent );
5926 TListOfListOfInt::iterator listIt = anOrder.begin();
5927 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5928 unionLists( *listIt, anOrder, listIndx + 1 );
5930 // convert submesh ids into interface instances
5931 // and dump command into python
5932 convertMeshOrder( anOrder, aResult, false );
5934 return aResult._retn();
5937 //=============================================================================
5939 * \brief Finds concurrent sub-meshes
5941 //=============================================================================
5943 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5945 TListOfListOfInt anOrder;
5946 ::SMESH_Mesh& mesh = GetImpl();
5948 // collect submeshes and detect concurrent algorithms and hypothesises
5949 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5951 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5952 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5953 ::SMESH_subMesh* sm = (*i_sm).second;
5955 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5957 // list of assigned hypothesises
5958 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5959 // Find out dimensions where the submesh can be concurrent.
5960 // We define the dimensions by algo of each of hypotheses in hypList
5961 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5962 for( ; hypIt != hypList.end(); hypIt++ ) {
5963 SMESH_Algo* anAlgo = 0;
5964 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5965 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5966 // hyp it-self is algo
5967 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5969 // try to find algorithm with help of sub-shapes
5970 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5971 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5972 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5975 continue; // no algorithm assigned to a current submesh
5977 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5978 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5980 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5981 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5982 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5984 } // end iterations on submesh
5986 // iterate on created dimension-hypotheses and check for concurrents
5987 for ( int i = 0; i < 4; i++ ) {
5988 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5989 // check for concurrents in own and other dimensions (step-by-step)
5990 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5991 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5992 const SMESH_DimHyp* dimHyp = *dhIt;
5993 TDimHypList listOfConcurr;
5994 set<int> setOfConcurrIds;
5995 // looking for concurrents and collect into own list
5996 for ( int j = i; j < 4; j++ )
5997 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5998 // check if any concurrents found
5999 if ( listOfConcurr.size() > 0 ) {
6000 // add own submesh to list of concurrent
6001 addInOrderOfPriority( dimHyp, listOfConcurr );
6002 list<int> listOfConcurrIds;
6003 TDimHypList::iterator hypIt = listOfConcurr.begin();
6004 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6005 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6006 anOrder.push_back( listOfConcurrIds );
6011 removeDimHyps(dimHypListArr);
6013 // now, minimize the number of concurrent groups
6014 // Here we assume that lists of submeshes can have same submesh
6015 // in case of multi-dimension algorithms, as result
6016 // list with common submesh has to be united into one list
6018 TListOfListOfInt::iterator listIt = anOrder.begin();
6019 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6020 unionLists( *listIt, anOrder, listIndx + 1 );
6026 //=============================================================================
6028 * \brief Set submesh object order
6029 * \param theSubMeshArray submesh array order
6031 //=============================================================================
6033 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6036 _preMeshInfo->ForgetOrLoad();
6039 ::SMESH_Mesh& mesh = GetImpl();
6041 TPythonDump aPythonDump; // prevent dump of called methods
6042 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6044 TListOfListOfInt subMeshOrder;
6045 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6047 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6048 TListOfInt subMeshIds;
6050 aPythonDump << ", ";
6051 aPythonDump << "[ ";
6052 // Collect subMeshes which should be clear
6053 // do it list-by-list, because modification of submesh order
6054 // take effect between concurrent submeshes only
6055 set<const SMESH_subMesh*> subMeshToClear;
6056 list<const SMESH_subMesh*> subMeshList;
6057 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6059 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6061 aPythonDump << ", ";
6062 aPythonDump << subMesh;
6063 subMeshIds.push_back( subMesh->GetId() );
6064 // detect common parts of submeshes
6065 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6066 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6068 aPythonDump << " ]";
6069 subMeshOrder.push_back( subMeshIds );
6071 // clear collected submeshes
6072 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6073 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6074 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6075 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6077 aPythonDump << " ])";
6079 mesh.SetMeshOrder( subMeshOrder );
6082 SMESH::SMESH_Mesh_var me = _this();
6083 _gen_i->UpdateIcons( me );
6088 //=============================================================================
6090 * \brief Convert submesh ids into submesh interfaces
6092 //=============================================================================
6094 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6095 SMESH::submesh_array_array& theResOrder,
6096 const bool theIsDump)
6098 int nbSet = theIdsOrder.size();
6099 TPythonDump aPythonDump; // prevent dump of called methods
6101 aPythonDump << "[ ";
6102 theResOrder.length(nbSet);
6103 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6105 for( ; it != theIdsOrder.end(); it++ ) {
6106 // translate submesh identificators into submesh objects
6107 // takeing into account real number of concurrent lists
6108 const TListOfInt& aSubOrder = (*it);
6109 if (!aSubOrder.size())
6112 aPythonDump << "[ ";
6113 // convert shape indices into interfaces
6114 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6115 aResSubSet->length(aSubOrder.size());
6116 TListOfInt::const_iterator subIt = aSubOrder.begin();
6118 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6119 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6121 SMESH::SMESH_subMesh_var subMesh =
6122 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6125 aPythonDump << ", ";
6126 aPythonDump << subMesh;
6128 aResSubSet[ j++ ] = subMesh;
6131 aPythonDump << " ]";
6133 theResOrder[ listIndx++ ] = aResSubSet;
6135 // correct number of lists
6136 theResOrder.length( listIndx );
6139 // finilise python dump
6140 aPythonDump << " ]";
6141 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6145 namespace // utils used by SMESH_MeshPartDS
6148 * \brief Class used to access to protected data of SMDS_MeshInfo
6150 struct TMeshInfo : public SMDS_MeshInfo
6152 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6155 * \brief Element holing its ID only
6157 struct TElemID : public SMDS_LinearEdge
6159 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6163 //================================================================================
6165 // Implementation of SMESH_MeshPartDS
6167 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6168 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6170 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6171 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6174 _meshDS = mesh_i->GetImpl().GetMeshDS();
6176 SetPersistentId( _meshDS->GetPersistentId() );
6178 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6180 // <meshPart> is the whole mesh
6181 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6183 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6184 myGroupSet = _meshDS->GetGroups();
6189 SMESH::long_array_var anIDs = meshPart->GetIDs();
6190 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6191 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6193 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6194 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6195 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6200 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6201 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6202 if ( _elements[ e->GetType() ].insert( e ).second )
6205 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6206 while ( nIt->more() )
6208 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6209 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6216 ShapeToMesh( _meshDS->ShapeToMesh() );
6218 _meshDS = 0; // to enforce iteration on _elements and _nodes
6221 // -------------------------------------------------------------------------------------
6222 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6223 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6226 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6227 for ( ; partIt != meshPart.end(); ++partIt )
6228 if ( const SMDS_MeshElement * e = *partIt )
6229 if ( _elements[ e->GetType() ].insert( e ).second )
6232 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6233 while ( nIt->more() )
6235 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6236 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6242 // -------------------------------------------------------------------------------------
6243 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6245 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6247 TElemID elem( IDelem );
6248 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6249 if ( !_elements[ iType ].empty() )
6251 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6252 if ( it != _elements[ iType ].end() )
6257 // -------------------------------------------------------------------------------------
6258 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6260 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6262 typedef SMDS_SetIterator
6263 <const SMDS_MeshElement*,
6264 TIDSortedElemSet::const_iterator,
6265 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6266 SMDS_MeshElement::GeomFilter
6269 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6271 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6272 _elements[type].end(),
6273 SMDS_MeshElement::GeomFilter( geomType )));
6275 // -------------------------------------------------------------------------------------
6276 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6278 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6280 typedef SMDS_SetIterator
6281 <const SMDS_MeshElement*,
6282 TIDSortedElemSet::const_iterator,
6283 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6284 SMDS_MeshElement::EntityFilter
6287 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6289 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6290 _elements[type].end(),
6291 SMDS_MeshElement::EntityFilter( entity )));
6293 // -------------------------------------------------------------------------------------
6294 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6296 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6297 if ( type == SMDSAbs_All && !_meshDS )
6299 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6301 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6302 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6304 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6306 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6307 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6309 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6310 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6312 // -------------------------------------------------------------------------------------
6313 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6314 iterType SMESH_MeshPartDS::methName() const \
6316 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6317 return _meshDS ? _meshDS->methName() : iterType \
6318 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6320 // -------------------------------------------------------------------------------------
6321 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6322 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6323 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6324 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6325 #undef _GET_ITER_DEFINE
6327 // END Implementation of SMESH_MeshPartDS
6329 //================================================================================