1 // Copyright (C) 2007-2019 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_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
118 _previewEditor = NULL;
123 //=============================================================================
127 //=============================================================================
129 SMESH_Mesh_i::~SMESH_Mesh_i()
132 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
133 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
134 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
136 aGroup->UnRegister();
137 SMESH::SMESH_GroupBase_var( itGr->second );
142 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
143 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
144 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
146 aSubMesh->UnRegister();
147 SMESH::SMESH_subMesh_var( itSM->second );
149 _mapSubMeshIor.clear();
151 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
152 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
153 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
154 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
155 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
156 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
159 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
163 // clear cached shapes if no more meshes remain; (the cache is blame,
164 // together with publishing, of spent time increasing in issue 22874)
165 if ( _impl->NbMeshes() == 1 )
166 _gen_i->GetShapeReader()->ClearClientBuffer();
168 delete _editor; _editor = NULL;
169 delete _previewEditor; _previewEditor = NULL;
170 delete _impl; _impl = NULL;
171 delete _preMeshInfo; _preMeshInfo = NULL;
174 //=============================================================================
178 * Associates <this> mesh with <theShape> and puts a reference
179 * to <theShape> into the current study;
180 * the previous shape is substituted by the new one.
182 //=============================================================================
184 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
185 throw (SALOME::SALOME_Exception)
187 Unexpect aCatch(SALOME_SalomeException);
189 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
191 catch(SALOME_Exception & S_ex) {
192 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
194 // to track changes of GEOM groups
195 SMESH::SMESH_Mesh_var mesh = _this();
196 addGeomGroupData( theShapeObject, mesh );
197 if ( !CORBA::is_nil( theShapeObject ))
198 _mainShapeTick = theShapeObject->GetTick();
201 //================================================================================
203 * \brief return true if mesh has a shape to build a shape on
205 //================================================================================
207 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
208 throw (SALOME::SALOME_Exception)
210 Unexpect aCatch(SALOME_SalomeException);
213 res = _impl->HasShapeToMesh();
215 catch(SALOME_Exception & S_ex) {
216 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
221 //=======================================================================
222 //function : GetShapeToMesh
224 //=======================================================================
226 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
227 throw (SALOME::SALOME_Exception)
229 Unexpect aCatch(SALOME_SalomeException);
230 GEOM::GEOM_Object_var aShapeObj;
232 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
236 if ( aShapeObj->_is_nil() )
238 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
239 // find GEOM_Object by entry (IPAL52735)
240 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
241 for ( ; data != _geomGroupData.end(); ++data )
242 if ( data->_smeshObject->_is_equivalent( _this() ))
244 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
245 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
246 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
252 catch(SALOME_Exception & S_ex) {
253 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
255 return aShapeObj._retn();
258 //================================================================================
260 * \brief Replaces a shape in the mesh
262 //================================================================================
263 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
264 throw (SALOME::SALOME_Exception)
266 TopoDS_Shape S = _impl->GetShapeToMesh();
267 GEOM_Client* geomClient = _gen_i->GetShapeReader();
268 TCollection_AsciiString aIOR;
269 if (geomClient->Find(S, aIOR)) {
270 geomClient->RemoveShapeFromBuffer(aIOR);
273 // re-assign global hypotheses to the new shape
275 CheckGeomModif( true );
278 //================================================================================
280 * \brief Return false if the mesh is not yet fully loaded from the study file
282 //================================================================================
284 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
286 Unexpect aCatch(SALOME_SalomeException);
287 return !_preMeshInfo;
290 //================================================================================
292 * \brief Load full mesh data from the study file
294 //================================================================================
296 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
298 Unexpect aCatch(SALOME_SalomeException);
300 _preMeshInfo->FullLoadFromFile();
303 //================================================================================
305 * \brief Remove all nodes and elements
307 //================================================================================
309 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
311 Unexpect aCatch(SALOME_SalomeException);
313 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
317 //CheckGeomGroupModif(); // issue 20145
319 catch(SALOME_Exception & S_ex) {
320 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
323 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
325 SMESH::SMESH_Mesh_var mesh = _this();
326 _gen_i->UpdateIcons( mesh );
329 //================================================================================
331 * \brief Remove all nodes and elements for indicated shape
333 //================================================================================
335 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
336 throw (SALOME::SALOME_Exception)
338 Unexpect aCatch(SALOME_SalomeException);
340 _preMeshInfo->FullLoadFromFile();
343 _impl->ClearSubMesh( ShapeID );
345 catch(SALOME_Exception & S_ex) {
346 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
348 _impl->GetMeshDS()->Modified();
350 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
353 //=============================================================================
355 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
357 //=============================================================================
359 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
361 SMESH::DriverMED_ReadStatus res;
364 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
365 res = SMESH::DRS_OK; break;
366 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
367 res = SMESH::DRS_EMPTY; break;
368 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
369 res = SMESH::DRS_WARN_RENUMBER; break;
370 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
371 res = SMESH::DRS_WARN_SKIP_ELEM; break;
372 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
373 res = SMESH::DRS_WARN_DESCENDING; break;
374 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
376 res = SMESH::DRS_FAIL; break;
381 //=============================================================================
383 * Convert ::SMESH_ComputeError to SMESH::ComputeError
385 //=============================================================================
387 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
389 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
390 errVar->subShapeID = -1;
391 errVar->hasBadMesh = false;
393 if ( !errorPtr || errorPtr->IsOK() )
395 errVar->code = SMESH::COMPERR_OK;
399 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
400 errVar->comment = errorPtr->myComment.c_str();
402 return errVar._retn();
405 //=============================================================================
409 * Imports mesh data from MED file
411 //=============================================================================
413 SMESH::DriverMED_ReadStatus
414 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
415 throw ( SALOME::SALOME_Exception )
417 Unexpect aCatch(SALOME_SalomeException);
420 status = _impl->MEDToMesh( theFileName, theMeshName );
422 catch( SALOME_Exception& S_ex ) {
423 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
426 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
429 CreateGroupServants();
431 int major, minor, release;
432 major = minor = release = 0;
433 MED::GetMEDVersion(theFileName, major, minor, release);
434 _medFileInfo = new SMESH::MedFileInfo();
435 _medFileInfo->fileName = theFileName;
436 _medFileInfo->fileSize = 0;
437 _medFileInfo->major = major;
438 _medFileInfo->minor = minor;
439 _medFileInfo->release = release;
440 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
442 return ConvertDriverMEDReadStatus(status);
445 //================================================================================
447 * \brief Imports mesh data from the CGNS file
449 //================================================================================
451 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
452 const int theMeshIndex,
453 std::string& theMeshName )
454 throw ( SALOME::SALOME_Exception )
456 Unexpect aCatch(SALOME_SalomeException);
459 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
461 catch( SALOME_Exception& S_ex ) {
462 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
465 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
468 CreateGroupServants();
470 _medFileInfo = new SMESH::MedFileInfo();
471 _medFileInfo->fileName = theFileName;
472 _medFileInfo->major = 0;
473 _medFileInfo->minor = 0;
474 _medFileInfo->release = 0;
475 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
477 return ConvertDriverMEDReadStatus(status);
480 //================================================================================
482 * \brief Return string representation of a MED file version comprising nbDigits
484 //================================================================================
486 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
488 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
490 return CORBA::string_dup( ver.c_str() );
493 //================================================================================
495 * Return the list of med versions compatibles for write/append,
496 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
498 //================================================================================
499 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
501 SMESH::long_array_var aResult = new SMESH::long_array();
502 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
503 long nbver = mvok.size();
504 aResult->length( nbver );
505 for ( int i = 0; i < nbver; i++ )
506 aResult[i] = mvok[i];
507 return aResult._retn();
510 //=============================================================================
514 * Imports mesh data from MED file
516 //=============================================================================
518 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
519 throw ( SALOME::SALOME_Exception )
523 // Read mesh with name = <theMeshName> into SMESH_Mesh
524 _impl->UNVToMesh( theFileName );
526 CreateGroupServants();
528 _medFileInfo = new SMESH::MedFileInfo();
529 _medFileInfo->fileName = theFileName;
530 _medFileInfo->major = 0;
531 _medFileInfo->minor = 0;
532 _medFileInfo->release = 0;
533 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
535 SMESH_CATCH( SMESH::throwCorbaException );
540 //=============================================================================
544 * Imports mesh data from STL file
546 //=============================================================================
547 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
548 throw ( SALOME::SALOME_Exception )
552 // Read mesh with name = <theMeshName> into SMESH_Mesh
553 std::string name = _impl->STLToMesh( theFileName );
556 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
557 _gen_i->SetName( meshSO, name.c_str() );
559 _medFileInfo = new SMESH::MedFileInfo();
560 _medFileInfo->fileName = theFileName;
561 _medFileInfo->major = 0;
562 _medFileInfo->minor = 0;
563 _medFileInfo->release = 0;
564 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
566 SMESH_CATCH( SMESH::throwCorbaException );
571 //================================================================================
573 * \brief Function used in SMESH_CATCH by ImportGMFFile()
575 //================================================================================
579 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
581 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
585 //================================================================================
587 * \brief Imports data from a GMF file and returns an error description
589 //================================================================================
591 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
592 bool theMakeRequiredGroups )
593 throw (SALOME::SALOME_Exception)
595 SMESH_ComputeErrorPtr error;
598 #define SMESH_CAUGHT error =
601 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
603 _medFileInfo = new SMESH::MedFileInfo();
604 _medFileInfo->fileName = theFileName;
605 _medFileInfo->major = 0;
606 _medFileInfo->minor = 0;
607 _medFileInfo->release = 0;
608 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
610 SMESH_CATCH( exceptionToComputeError );
614 CreateGroupServants();
616 return ConvertComputeError( error );
619 //=============================================================================
623 //=============================================================================
625 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
627 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
628 (SMESH_Hypothesis::Hypothesis_Status theStatus)
631 RETURNCASE( HYP_OK );
632 RETURNCASE( HYP_MISSING );
633 RETURNCASE( HYP_CONCURRENT );
634 RETURNCASE( HYP_BAD_PARAMETER );
635 RETURNCASE( HYP_HIDDEN_ALGO );
636 RETURNCASE( HYP_HIDING_ALGO );
637 RETURNCASE( HYP_UNKNOWN_FATAL );
638 RETURNCASE( HYP_INCOMPATIBLE );
639 RETURNCASE( HYP_NOTCONFORM );
640 RETURNCASE( HYP_ALREADY_EXIST );
641 RETURNCASE( HYP_BAD_DIM );
642 RETURNCASE( HYP_BAD_SUBSHAPE );
643 RETURNCASE( HYP_BAD_GEOMETRY );
644 RETURNCASE( HYP_NEED_SHAPE );
645 RETURNCASE( HYP_INCOMPAT_HYPS );
648 return SMESH::HYP_UNKNOWN_FATAL;
651 //=============================================================================
655 * calls internal addHypothesis() and then adds a reference to <anHyp> under
656 * the SObject actually having a reference to <aSubShape>.
657 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
659 //=============================================================================
661 SMESH::Hypothesis_Status
662 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
663 SMESH::SMESH_Hypothesis_ptr anHyp,
664 CORBA::String_out anErrorText)
665 throw(SALOME::SALOME_Exception)
667 Unexpect aCatch(SALOME_SalomeException);
669 _preMeshInfo->ForgetOrLoad();
672 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
673 anErrorText = error.c_str();
675 SMESH::SMESH_Mesh_var mesh( _this() );
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
679 _gen_i->UpdateIcons( mesh );
681 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
683 // Update Python script
684 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
685 << aSubShape << ", " << anHyp << " )";
687 return ConvertHypothesisStatus(status);
690 //=============================================================================
694 //=============================================================================
696 SMESH_Hypothesis::Hypothesis_Status
697 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
698 SMESH::SMESH_Hypothesis_ptr anHyp,
699 std::string* anErrorText)
701 if(MYDEBUG) MESSAGE("addHypothesis");
703 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
704 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
706 if (CORBA::is_nil( anHyp ))
707 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
709 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
712 TopoDS_Shape myLocSubShape;
713 //use PseudoShape in case if mesh has no shape
715 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
717 myLocSubShape = _impl->GetShapeToMesh();
719 const int hypId = anHyp->GetId();
721 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
726 // assure there is a corresponding submesh
727 if ( !_impl->IsMainShape( myLocSubShape )) {
728 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
729 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
730 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
733 else if ( anErrorText )
735 *anErrorText = error;
738 catch(SALOME_Exception & S_ex)
740 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
745 //=============================================================================
749 //=============================================================================
751 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
752 SMESH::SMESH_Hypothesis_ptr anHyp)
753 throw(SALOME::SALOME_Exception)
755 Unexpect aCatch(SALOME_SalomeException);
757 _preMeshInfo->ForgetOrLoad();
759 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
760 SMESH::SMESH_Mesh_var mesh = _this();
762 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
764 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
765 _gen_i->UpdateIcons( mesh );
767 // Update Python script
768 if(_impl->HasShapeToMesh())
769 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
770 << aSubShape << ", " << anHyp << " )";
772 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
775 return ConvertHypothesisStatus(status);
778 //=============================================================================
782 //=============================================================================
784 SMESH_Hypothesis::Hypothesis_Status
785 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
786 SMESH::SMESH_Hypothesis_ptr anHyp)
788 if(MYDEBUG) MESSAGE("removeHypothesis()");
790 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
791 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
793 if (CORBA::is_nil( anHyp ))
794 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
797 _preMeshInfo->ForgetOrLoad();
799 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
802 TopoDS_Shape myLocSubShape;
803 //use PseudoShape in case if mesh has no shape
804 if( _impl->HasShapeToMesh() )
805 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
807 myLocSubShape = _impl->GetShapeToMesh();
809 const int hypId = anHyp->GetId();
810 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
811 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
813 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
817 catch(SALOME_Exception & S_ex)
819 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
824 //=============================================================================
828 //=============================================================================
830 SMESH::ListOfHypothesis *
831 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
832 throw(SALOME::SALOME_Exception)
834 Unexpect aCatch(SALOME_SalomeException);
835 if (MYDEBUG) MESSAGE("GetHypothesisList");
836 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
837 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
839 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
842 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
843 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
844 myLocSubShape = _impl->GetShapeToMesh();
845 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
846 int i = 0, n = aLocalList.size();
849 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
850 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
851 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
853 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
854 if ( id_hypptr != _mapHypo.end() )
855 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
863 return aList._retn();
866 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
868 Unexpect aCatch(SALOME_SalomeException);
869 if (MYDEBUG) MESSAGE("GetSubMeshes");
871 SMESH::submesh_array_var aList = new SMESH::submesh_array();
874 TPythonDump aPythonDump;
875 if ( !_mapSubMeshIor.empty() )
879 aList->length( _mapSubMeshIor.size() );
881 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
882 for ( ; it != _mapSubMeshIor.end(); it++ ) {
883 if ( CORBA::is_nil( it->second )) continue;
884 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
886 if (i > 1) aPythonDump << ", ";
887 aPythonDump << it->second;
891 catch(SALOME_Exception & S_ex) {
892 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
895 // Update Python script
896 if ( !_mapSubMeshIor.empty() )
897 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
899 return aList._retn();
902 //=============================================================================
906 //=============================================================================
908 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
909 const char* theName )
910 throw(SALOME::SALOME_Exception)
912 Unexpect aCatch(SALOME_SalomeException);
913 if (CORBA::is_nil(aSubShape))
914 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
916 SMESH::SMESH_subMesh_var subMesh;
917 SMESH::SMESH_Mesh_var aMesh = _this();
919 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
921 //Get or Create the SMESH_subMesh object implementation
923 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
925 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
927 TopoDS_Iterator it( myLocSubShape );
929 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
931 subMesh = getSubMesh( subMeshId );
933 // create a new subMesh object servant if there is none for the shape
934 if ( subMesh->_is_nil() )
935 subMesh = createSubMesh( aSubShape );
936 if ( _gen_i->CanPublishInStudy( subMesh ))
938 SALOMEDS::SObject_wrap aSO =
939 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
940 if ( !aSO->_is_nil()) {
941 // Update Python script
942 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
943 << aSubShape << ", '" << theName << "' )";
947 catch(SALOME_Exception & S_ex) {
948 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
950 return subMesh._retn();
953 //=============================================================================
957 //=============================================================================
959 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
960 throw (SALOME::SALOME_Exception)
964 if ( theSubMesh->_is_nil() )
967 GEOM::GEOM_Object_var aSubShape;
968 // Remove submesh's SObject
969 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
970 if ( !anSO->_is_nil() ) {
971 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
972 SALOMEDS::SObject_wrap anObj, aRef;
973 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
974 anObj->ReferencedObject( aRef.inout() ))
976 CORBA::Object_var obj = aRef->GetObject();
977 aSubShape = GEOM::GEOM_Object::_narrow( obj );
979 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
980 // aSubShape = theSubMesh->GetSubShape();
982 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
983 builder->RemoveObjectWithChildren( anSO );
985 // Update Python script
986 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
989 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
991 _preMeshInfo->ForgetOrLoad();
993 SMESH_CATCH( SMESH::throwCorbaException );
996 //=============================================================================
1000 //=============================================================================
1002 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1003 const char* theName )
1004 throw(SALOME::SALOME_Exception)
1006 Unexpect aCatch(SALOME_SalomeException);
1008 _preMeshInfo->FullLoadFromFile();
1010 SMESH::SMESH_Group_var aNewGroup =
1011 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1013 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1015 SMESH::SMESH_Mesh_var mesh = _this();
1016 SALOMEDS::SObject_wrap aSO =
1017 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1018 if ( !aSO->_is_nil())
1019 // Update Python script
1020 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1021 << theElemType << ", '" << theName << "' )";
1023 return aNewGroup._retn();
1026 //=============================================================================
1030 //=============================================================================
1031 SMESH::SMESH_GroupOnGeom_ptr
1032 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1033 const char* theName,
1034 GEOM::GEOM_Object_ptr theGeomObj)
1035 throw(SALOME::SALOME_Exception)
1037 Unexpect aCatch(SALOME_SalomeException);
1039 _preMeshInfo->FullLoadFromFile();
1041 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1043 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1044 if ( !aShape.IsNull() )
1047 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1049 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1051 SMESH::SMESH_Mesh_var mesh = _this();
1052 SALOMEDS::SObject_wrap aSO =
1053 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1054 if ( !aSO->_is_nil())
1055 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1056 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1060 return aNewGroup._retn();
1063 //================================================================================
1065 * \brief Creates a group whose contents is defined by filter
1066 * \param theElemType - group type
1067 * \param theName - group name
1068 * \param theFilter - the filter
1069 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1071 //================================================================================
1073 SMESH::SMESH_GroupOnFilter_ptr
1074 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1075 const char* theName,
1076 SMESH::Filter_ptr theFilter )
1077 throw (SALOME::SALOME_Exception)
1079 Unexpect aCatch(SALOME_SalomeException);
1081 _preMeshInfo->FullLoadFromFile();
1083 if ( CORBA::is_nil( theFilter ))
1084 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1086 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1088 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1090 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1091 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1094 if ( !aNewGroup->_is_nil() )
1095 aNewGroup->SetFilter( theFilter );
1097 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1099 SMESH::SMESH_Mesh_var mesh = _this();
1100 SALOMEDS::SObject_wrap aSO =
1101 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1103 if ( !aSO->_is_nil())
1104 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1105 << theElemType << ", '" << theName << "', " << theFilter << " )";
1107 return aNewGroup._retn();
1110 //=============================================================================
1114 //=============================================================================
1116 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1117 throw (SALOME::SALOME_Exception)
1119 if ( theGroup->_is_nil() )
1124 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1128 if ( aGroup->GetMeshServant() != this )
1129 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1130 SALOME::BAD_PARAM );
1132 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1133 if ( !aGroupSO->_is_nil() )
1135 // Update Python script
1136 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1138 // Remove group's SObject
1139 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1140 builder->RemoveObjectWithChildren( aGroupSO );
1142 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1144 // Remove the group from SMESH data structures
1145 removeGroup( aGroup->GetLocalID() );
1147 SMESH_CATCH( SMESH::throwCorbaException );
1150 //=============================================================================
1152 * Remove group with its contents
1154 //=============================================================================
1156 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1157 throw (SALOME::SALOME_Exception)
1161 _preMeshInfo->FullLoadFromFile();
1163 if ( theGroup->_is_nil() )
1166 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1167 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1168 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1171 vector<int> nodeIds; // to remove nodes becoming free
1172 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1173 if ( !isNodal && !theGroup->IsEmpty() )
1175 CORBA::Long elemID = theGroup->GetID( 1 );
1176 int nbElemNodes = GetElemNbNodes( elemID );
1177 if ( nbElemNodes > 0 )
1178 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1181 // Retrieve contents
1182 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1183 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1184 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1185 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1186 elems.assign( elemBeg, elemEnd );
1188 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1191 RemoveGroup( theGroup );
1194 for ( size_t i = 0; i < elems.size(); ++i )
1196 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1200 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1201 nodeIds.push_back( nIt->next()->GetID() );
1203 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1207 _impl->GetMeshDS()->RemoveElement( elems[i] );
1211 // Remove free nodes
1212 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1213 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1214 if ( n->NbInverseElements() == 0 )
1215 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1217 // Update Python script (theGroup must be alive for this)
1218 pyDump << SMESH::SMESH_Mesh_var(_this())
1219 << ".RemoveGroupWithContents( " << theGroup << " )";
1221 SMESH_CATCH( SMESH::throwCorbaException );
1224 //================================================================================
1226 * \brief Get the list of groups existing in the mesh
1227 * \retval SMESH::ListOfGroups * - list of groups
1229 //================================================================================
1231 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1233 Unexpect aCatch(SALOME_SalomeException);
1234 if (MYDEBUG) MESSAGE("GetGroups");
1236 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1239 TPythonDump aPythonDump;
1240 if ( !_mapGroups.empty() )
1242 aPythonDump << "[ ";
1244 aList->length( _mapGroups.size() );
1246 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1247 for ( ; it != _mapGroups.end(); it++ ) {
1248 if ( CORBA::is_nil( it->second )) continue;
1249 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1251 if (i > 1) aPythonDump << ", ";
1252 aPythonDump << it->second;
1256 catch(SALOME_Exception & S_ex) {
1257 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1259 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1261 return aList._retn();
1264 //=============================================================================
1266 * Get number of groups existing in the mesh
1268 //=============================================================================
1270 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1272 Unexpect aCatch(SALOME_SalomeException);
1273 return _mapGroups.size();
1276 //=============================================================================
1278 * New group including all mesh elements present in initial groups is created.
1280 //=============================================================================
1282 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1283 SMESH::SMESH_GroupBase_ptr theGroup2,
1284 const char* theName )
1285 throw (SALOME::SALOME_Exception)
1287 SMESH::SMESH_Group_var aResGrp;
1291 _preMeshInfo->FullLoadFromFile();
1293 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1294 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1296 if ( theGroup1->GetType() != theGroup2->GetType() )
1297 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1302 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1303 if ( aResGrp->_is_nil() )
1304 return SMESH::SMESH_Group::_nil();
1306 aResGrp->AddFrom( theGroup1 );
1307 aResGrp->AddFrom( theGroup2 );
1309 // Update Python script
1310 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1311 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1313 SMESH_CATCH( SMESH::throwCorbaException );
1315 return aResGrp._retn();
1318 //=============================================================================
1320 * \brief New group including all mesh elements present in initial groups is created.
1321 * \param theGroups list of groups
1322 * \param theName name of group to be created
1323 * \return pointer to the new group
1325 //=============================================================================
1327 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1328 const char* theName )
1329 throw (SALOME::SALOME_Exception)
1331 SMESH::SMESH_Group_var aResGrp;
1334 _preMeshInfo->FullLoadFromFile();
1337 return SMESH::SMESH_Group::_nil();
1342 SMESH::ElementType aType = SMESH::ALL;
1343 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1345 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1346 if ( CORBA::is_nil( aGrp ) )
1348 if ( aType == SMESH::ALL )
1349 aType = aGrp->GetType();
1350 else if ( aType != aGrp->GetType() )
1351 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1354 if ( aType == SMESH::ALL )
1355 return SMESH::SMESH_Group::_nil();
1360 aResGrp = CreateGroup( aType, theName );
1361 if ( aResGrp->_is_nil() )
1362 return SMESH::SMESH_Group::_nil();
1364 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1365 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1367 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1368 if ( !CORBA::is_nil( aGrp ) )
1370 aResGrp->AddFrom( aGrp );
1371 if ( g > 0 ) pyDump << ", ";
1375 pyDump << " ], '" << theName << "' )";
1377 SMESH_CATCH( SMESH::throwCorbaException );
1379 return aResGrp._retn();
1382 //=============================================================================
1384 * New group is created. All mesh elements that are
1385 * present in both initial groups are added to the new one.
1387 //=============================================================================
1389 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1390 SMESH::SMESH_GroupBase_ptr theGroup2,
1391 const char* theName )
1392 throw (SALOME::SALOME_Exception)
1394 SMESH::SMESH_Group_var aResGrp;
1399 _preMeshInfo->FullLoadFromFile();
1401 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1402 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1404 if ( theGroup1->GetType() != theGroup2->GetType() )
1405 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1409 // Create Intersection
1410 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1411 if ( aResGrp->_is_nil() )
1412 return aResGrp._retn();
1414 SMESHDS_GroupBase* groupDS1 = 0;
1415 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1416 groupDS1 = grp_i->GetGroupDS();
1418 SMESHDS_GroupBase* groupDS2 = 0;
1419 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1420 groupDS2 = grp_i->GetGroupDS();
1422 SMESHDS_Group* resGroupDS = 0;
1423 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1424 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1426 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1428 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1429 while ( elemIt1->more() )
1431 const SMDS_MeshElement* e = elemIt1->next();
1432 if ( groupDS2->Contains( e ))
1433 resGroupDS->SMDSGroup().Add( e );
1436 // Update Python script
1437 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1438 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1440 SMESH_CATCH( SMESH::throwCorbaException );
1442 return aResGrp._retn();
1445 //=============================================================================
1447 \brief Intersect list of groups. New group is created. All mesh elements that
1448 are present in all initial groups simultaneously are added to the new one.
1449 \param theGroups list of groups
1450 \param theName name of group to be created
1451 \return pointer on the group
1453 //=============================================================================
1454 SMESH::SMESH_Group_ptr
1455 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1456 const char* theName )
1457 throw (SALOME::SALOME_Exception)
1459 SMESH::SMESH_Group_var aResGrp;
1464 _preMeshInfo->FullLoadFromFile();
1467 return SMESH::SMESH_Group::_nil();
1469 // check types and get SMESHDS_GroupBase's
1470 SMESH::ElementType aType = SMESH::ALL;
1471 vector< SMESHDS_GroupBase* > groupVec;
1472 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1474 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1475 if ( CORBA::is_nil( aGrp ) )
1477 if ( aType == SMESH::ALL )
1478 aType = aGrp->GetType();
1479 else if ( aType != aGrp->GetType() )
1480 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1483 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1484 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1486 if ( grpDS->IsEmpty() )
1491 groupVec.push_back( grpDS );
1494 if ( aType == SMESH::ALL ) // all groups are nil
1495 return SMESH::SMESH_Group::_nil();
1500 aResGrp = CreateGroup( aType, theName );
1502 SMESHDS_Group* resGroupDS = 0;
1503 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1504 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1505 if ( !resGroupDS || groupVec.empty() )
1506 return aResGrp._retn();
1509 size_t i, nb = groupVec.size();
1510 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1511 while ( elemIt1->more() )
1513 const SMDS_MeshElement* e = elemIt1->next();
1515 for ( i = 1; ( i < nb && inAll ); ++i )
1516 inAll = groupVec[i]->Contains( e );
1519 resGroupDS->SMDSGroup().Add( e );
1522 // Update Python script
1523 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1524 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1526 SMESH_CATCH( SMESH::throwCorbaException );
1528 return aResGrp._retn();
1531 //=============================================================================
1533 * New group is created. All mesh elements that are present in
1534 * a main group but is not present in a tool group are added to the new one
1536 //=============================================================================
1538 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1539 SMESH::SMESH_GroupBase_ptr theGroup2,
1540 const char* theName )
1541 throw (SALOME::SALOME_Exception)
1543 SMESH::SMESH_Group_var aResGrp;
1548 _preMeshInfo->FullLoadFromFile();
1550 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1551 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1553 if ( theGroup1->GetType() != theGroup2->GetType() )
1554 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1558 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1559 if ( aResGrp->_is_nil() )
1560 return aResGrp._retn();
1562 SMESHDS_GroupBase* groupDS1 = 0;
1563 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1564 groupDS1 = grp_i->GetGroupDS();
1566 SMESHDS_GroupBase* groupDS2 = 0;
1567 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1568 groupDS2 = grp_i->GetGroupDS();
1570 SMESHDS_Group* resGroupDS = 0;
1571 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1572 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1574 if ( groupDS1 && groupDS2 && resGroupDS )
1576 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1577 while ( elemIt1->more() )
1579 const SMDS_MeshElement* e = elemIt1->next();
1580 if ( !groupDS2->Contains( e ))
1581 resGroupDS->SMDSGroup().Add( e );
1584 // Update Python script
1585 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1586 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1588 SMESH_CATCH( SMESH::throwCorbaException );
1590 return aResGrp._retn();
1593 //=============================================================================
1595 \brief Cut lists of groups. New group is created. All mesh elements that are
1596 present in main groups but do not present in tool groups are added to the new one
1597 \param theMainGroups list of main groups
1598 \param theToolGroups list of tool groups
1599 \param theName name of group to be created
1600 \return pointer on the group
1602 //=============================================================================
1603 SMESH::SMESH_Group_ptr
1604 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1605 const SMESH::ListOfGroups& theToolGroups,
1606 const char* theName )
1607 throw (SALOME::SALOME_Exception)
1609 SMESH::SMESH_Group_var aResGrp;
1614 _preMeshInfo->FullLoadFromFile();
1617 return SMESH::SMESH_Group::_nil();
1619 // check types and get SMESHDS_GroupBase's
1620 SMESH::ElementType aType = SMESH::ALL;
1621 vector< SMESHDS_GroupBase* > toolGroupVec;
1622 vector< SMDS_ElemIteratorPtr > mainIterVec;
1624 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1626 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1627 if ( CORBA::is_nil( aGrp ) )
1629 if ( aType == SMESH::ALL )
1630 aType = aGrp->GetType();
1631 else if ( aType != aGrp->GetType() )
1632 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1634 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1635 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1636 if ( !grpDS->IsEmpty() )
1637 mainIterVec.push_back( grpDS->GetElements() );
1639 if ( aType == SMESH::ALL ) // all main groups are nil
1640 return SMESH::SMESH_Group::_nil();
1641 if ( mainIterVec.empty() ) // all main groups are empty
1642 return aResGrp._retn();
1644 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1646 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1647 if ( CORBA::is_nil( aGrp ) )
1649 if ( aType != aGrp->GetType() )
1650 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1652 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1653 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1654 toolGroupVec.push_back( grpDS );
1660 aResGrp = CreateGroup( aType, theName );
1662 SMESHDS_Group* resGroupDS = 0;
1663 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1664 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1666 return aResGrp._retn();
1669 size_t i, nb = toolGroupVec.size();
1670 SMDS_ElemIteratorPtr mainElemIt
1671 ( new SMDS_IteratorOnIterators
1672 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1673 while ( mainElemIt->more() )
1675 const SMDS_MeshElement* e = mainElemIt->next();
1677 for ( i = 0; ( i < nb && !isIn ); ++i )
1678 isIn = toolGroupVec[i]->Contains( e );
1681 resGroupDS->SMDSGroup().Add( e );
1684 // Update Python script
1685 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1686 << ".CutListOfGroups( " << theMainGroups << ", "
1687 << theToolGroups << ", '" << theName << "' )";
1689 SMESH_CATCH( SMESH::throwCorbaException );
1691 return aResGrp._retn();
1694 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1696 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1697 bool & toStopChecking )
1699 toStopChecking = ( nbCommon < nbChecked );
1700 return nbCommon == nbNodes;
1702 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1703 bool & toStopChecking )
1705 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1706 return nbCommon == nbCorners;
1708 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1709 bool & toStopChecking )
1711 return nbCommon > 0;
1713 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1714 bool & toStopChecking )
1716 return nbCommon >= (nbNodes+1) / 2;
1720 //=============================================================================
1722 * Create a group of entities basing on nodes of other groups.
1723 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1724 * \param [in] anElemType - a type of elements to include to the new group.
1725 * \param [in] theName - a name of the new group.
1726 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1727 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1728 * new group provided that it is based on nodes of an element of \a aListOfGroups
1729 * \return SMESH_Group - the created group
1731 // IMP 19939, bug 22010, IMP 22635
1732 //=============================================================================
1734 SMESH::SMESH_Group_ptr
1735 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1736 SMESH::ElementType theElemType,
1737 const char* theName,
1738 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1739 CORBA::Boolean theUnderlyingOnly)
1740 throw (SALOME::SALOME_Exception)
1742 SMESH::SMESH_Group_var aResGrp;
1746 _preMeshInfo->FullLoadFromFile();
1748 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1750 if ( !theName || !aMeshDS )
1751 return SMESH::SMESH_Group::_nil();
1753 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1755 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1756 SMESH_Comment nbCoNoStr( "SMESH.");
1757 switch ( theNbCommonNodes ) {
1758 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1759 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1760 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1761 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1762 default: return aResGrp._retn();
1764 int nbChecked, nbCommon, nbNodes, nbCorners;
1770 aResGrp = CreateGroup( theElemType, theName );
1771 if ( aResGrp->_is_nil() )
1772 return SMESH::SMESH_Group::_nil();
1774 SMESHDS_GroupBase* groupBaseDS =
1775 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1776 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1778 vector<bool> isNodeInGroups;
1780 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1782 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1783 if ( CORBA::is_nil( aGrp ) )
1785 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1786 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1789 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1790 if ( !elIt ) continue;
1792 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1794 while ( elIt->more() ) {
1795 const SMDS_MeshElement* el = elIt->next();
1796 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1797 while ( nIt->more() )
1798 resGroupCore.Add( nIt->next() );
1801 // get elements of theElemType based on nodes of every element of group
1802 else if ( theUnderlyingOnly )
1804 while ( elIt->more() )
1806 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1807 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1808 TIDSortedElemSet checkedElems;
1809 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1810 while ( nIt->more() )
1812 const SMDS_MeshNode* n = nIt->next();
1813 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1814 // check nodes of elements of theElemType around el
1815 while ( elOfTypeIt->more() )
1817 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1818 if ( !checkedElems.insert( elOfType ).second ) continue;
1819 nbNodes = elOfType->NbNodes();
1820 nbCorners = elOfType->NbCornerNodes();
1822 bool toStopChecking = false;
1823 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1824 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1825 if ( elNodes.count( nIt2->next() ) &&
1826 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1828 resGroupCore.Add( elOfType );
1835 // get all nodes of elements of groups
1838 while ( elIt->more() )
1840 const SMDS_MeshElement* el = elIt->next(); // an element of group
1841 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1842 while ( nIt->more() )
1844 const SMDS_MeshNode* n = nIt->next();
1845 if ( n->GetID() >= (int) isNodeInGroups.size() )
1846 isNodeInGroups.resize( n->GetID() + 1, false );
1847 isNodeInGroups[ n->GetID() ] = true;
1853 // Get elements of theElemType based on a certain number of nodes of elements of groups
1854 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1856 const SMDS_MeshNode* n;
1857 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1858 const int isNodeInGroupsSize = isNodeInGroups.size();
1859 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1861 if ( !isNodeInGroups[ iN ] ||
1862 !( n = aMeshDS->FindNode( iN )))
1865 // check nodes of elements of theElemType around n
1866 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1867 while ( elOfTypeIt->more() )
1869 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1870 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1875 nbNodes = elOfType->NbNodes();
1876 nbCorners = elOfType->NbCornerNodes();
1878 bool toStopChecking = false;
1879 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1880 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1882 const int nID = nIt->next()->GetID();
1883 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1884 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1886 resGroupCore.Add( elOfType );
1894 // Update Python script
1895 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1896 << ".CreateDimGroup( "
1897 << theGroups << ", " << theElemType << ", '" << theName << "', "
1898 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1900 SMESH_CATCH( SMESH::throwCorbaException );
1902 return aResGrp._retn();
1905 //================================================================================
1907 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1908 * existing 1D elements as group boundaries.
1909 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1910 * adjacent faces is more than \a sharpAngle in degrees.
1911 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1912 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1913 * \return ListOfGroups - the created groups
1915 //================================================================================
1917 SMESH::ListOfGroups*
1918 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1919 CORBA::Boolean theCreateEdges,
1920 CORBA::Boolean theUseExistingEdges )
1921 throw (SALOME::SALOME_Exception)
1923 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1924 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1927 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1933 _preMeshInfo->FullLoadFromFile();
1935 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1937 std::vector< SMESH_MeshAlgos::Edge > edges =
1938 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1940 if ( theCreateEdges )
1942 std::vector<const SMDS_MeshNode *> nodes(2);
1943 for ( size_t i = 0; i < edges.size(); ++i )
1945 nodes[0] = edges[i]._node1;
1946 nodes[1] = edges[i]._node2;
1947 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1949 if ( edges[i]._medium )
1950 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1952 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1956 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1957 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1959 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1961 resultGroups->length( faceGroups.size() );
1962 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1964 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1965 _editor->GenerateGroupName("Group").c_str());
1966 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1968 SMESHDS_GroupBase* groupBaseDS =
1969 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1970 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1972 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
1973 for ( size_t i = 0; i < faces.size(); ++i )
1974 groupCore.Add( faces[i] );
1977 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
1978 << ".FaceGroupsSeparatedByEdges( "
1979 << TVar( theSharpAngle ) << ", "
1980 << theCreateEdges << ", "
1981 << theUseExistingEdges << " )";
1983 SMESH_CATCH( SMESH::throwCorbaException );
1984 return resultGroups._retn();
1988 //================================================================================
1990 * \brief Remember GEOM group data
1992 //================================================================================
1994 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1995 CORBA::Object_ptr theSmeshObj)
1997 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2000 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2001 if ( groupSO->_is_nil() )
2004 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2005 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2006 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2009 _geomGroupData.push_back( TGeomGroupData() );
2010 TGeomGroupData & groupData = _geomGroupData.back();
2012 CORBA::String_var entry = groupSO->GetID();
2013 groupData._groupEntry = entry.in();
2015 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2016 groupData._indices.insert( ids[i] );
2018 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2019 // shape index in SMESHDS
2020 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2021 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2024 //================================================================================
2026 * Remove GEOM group data relating to removed smesh object
2028 //================================================================================
2030 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2032 list<TGeomGroupData>::iterator
2033 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2034 for ( ; data != dataEnd; ++data ) {
2035 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2036 _geomGroupData.erase( data );
2042 //================================================================================
2044 * \brief Return new group contents if it has been changed and update group data
2046 //================================================================================
2047 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2049 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2051 TopoDS_Shape newShape;
2053 if ( how == IS_BREAK_LINK )
2055 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2056 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2057 if ( !meshSO->_is_nil() &&
2058 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2059 geomRefSO->ReferencedObject( geomSO.inout() ))
2061 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2062 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2063 newShape = _gen_i->GeomObjectToShape( geom );
2069 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2070 if ( !groupSO->_is_nil() )
2072 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2073 if ( CORBA::is_nil( groupObj )) return newShape;
2074 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2076 // get indices of group items
2077 set<int> curIndices;
2078 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2079 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2080 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2081 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2082 curIndices.insert( ids[i] );
2084 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2085 return newShape; // group not changed
2088 groupData._indices = curIndices;
2090 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2091 if ( !geomClient ) return newShape;
2092 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2093 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2094 newShape = _gen_i->GeomObjectToShape( geomGroup );
2097 if ( newShape.IsNull() ) {
2098 // geom group becomes empty - return empty compound
2099 TopoDS_Compound compound;
2100 BRep_Builder().MakeCompound(compound);
2101 newShape = compound;
2108 //-----------------------------------------------------------------------------
2110 * \brief Storage of shape and index used in CheckGeomGroupModif()
2112 struct TIndexedShape
2115 TopoDS_Shape _shape;
2116 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2118 //-----------------------------------------------------------------------------
2120 * \brief Data to re-create a group on geometry
2122 struct TGroupOnGeomData
2125 TopoDS_Shape _shape;
2126 SMDSAbs_ElementType _type;
2128 Quantity_Color _color;
2130 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2132 _oldID = group->GetID();
2133 _type = group->GetType();
2134 _name = group->GetStoreName();
2135 _color = group->GetColor();
2139 //-----------------------------------------------------------------------------
2141 * \brief Check if a filter is still valid after geometry removal
2143 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2145 if ( theFilter->_is_nil() )
2147 SMESH::Filter::Criteria_var criteria;
2148 theFilter->GetCriteria( criteria.out() );
2150 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2152 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2154 switch ( criteria[ iCr ].Type )
2156 case SMESH::FT_BelongToGeom:
2157 case SMESH::FT_BelongToPlane:
2158 case SMESH::FT_BelongToCylinder:
2159 case SMESH::FT_BelongToGenSurface:
2160 case SMESH::FT_LyingOnGeom:
2161 entry = thresholdID;
2163 case SMESH::FT_ConnectedElements:
2166 entry = thresholdID;
2172 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2173 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2174 if ( so->_is_nil() )
2176 CORBA::Object_var obj = so->GetObject();
2177 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2178 if ( gen->GeomObjectToShape( geom ).IsNull() )
2181 } // loop on criteria
2187 //=============================================================================
2189 * \brief Update data if geometry changes
2193 //=============================================================================
2195 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2197 SMESH::SMESH_Mesh_var me = _this();
2198 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2200 TPythonDump dumpNothing; // prevent any dump
2202 //bool removedFromClient = false;
2204 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2206 //removedFromClient = _impl->HasShapeToMesh();
2208 // try to find geometry by study reference
2209 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2210 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2211 if ( !meshSO->_is_nil() &&
2212 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2213 geomRefSO->ReferencedObject( geomSO.inout() ))
2215 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2216 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2219 if ( mainGO->_is_nil() && // geometry removed ==>
2220 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2222 // convert geom dependent groups into standalone ones
2223 CheckGeomGroupModif();
2225 _impl->ShapeToMesh( TopoDS_Shape() );
2227 // remove sub-meshes
2228 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2229 while ( i_sm != _mapSubMeshIor.end() )
2231 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2233 RemoveSubMesh( sm );
2235 // remove all children except groups in the study
2236 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2237 SALOMEDS::SObject_wrap so;
2238 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2239 if ( meshSO->FindSubObject( tag, so.inout() ))
2240 builder->RemoveObjectWithChildren( so );
2242 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2248 if ( !_impl->HasShapeToMesh() ) return;
2251 // Update after group modification
2253 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2254 mainGO->GetTick() == _mainShapeTick )
2256 int nb = NbNodes() + NbElements();
2257 CheckGeomGroupModif();
2258 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2259 _gen_i->UpdateIcons( me );
2263 // Update after shape modification
2265 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2266 if ( !geomClient ) return;
2267 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2268 if ( geomGen->_is_nil() ) return;
2270 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2271 geomClient->RemoveShapeFromBuffer( ior.in() );
2273 // Update data taking into account that if topology doesn't change
2274 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2277 _preMeshInfo->ForgetAllData();
2280 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2281 if ( newShape.IsNull() )
2284 _mainShapeTick = mainGO->GetTick();
2286 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2288 // store data of groups on geometry
2289 std::vector< TGroupOnGeomData > groupsData;
2290 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2291 groupsData.reserve( groups.size() );
2292 TopTools_DataMapOfShapeShape old2newShapeMap;
2293 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2294 for ( ; g != groups.end(); ++g )
2296 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2298 groupsData.push_back( TGroupOnGeomData( group ));
2301 SMESH::SMESH_GroupOnGeom_var gog;
2302 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2303 if ( i_grp != _mapGroups.end() )
2304 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2306 GEOM::GEOM_Object_var geom;
2307 if ( !gog->_is_nil() )
2311 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2312 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2313 if ( !grpSO->_is_nil() &&
2314 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2315 geomRefSO->ReferencedObject( geomSO.inout() ))
2317 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2318 geom = GEOM::GEOM_Object::_narrow( geomObj );
2323 geom = gog->GetShape();
2326 if ( !geom->_is_nil() )
2328 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2329 geomClient->RemoveShapeFromBuffer( ior.in() );
2330 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2331 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2333 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2335 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2339 // store assigned hypotheses
2340 std::vector< pair< int, THypList > > ids2Hyps;
2341 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2342 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2344 const TopoDS_Shape& s = s2hyps.Key();
2345 const THypList& hyps = s2hyps.ChangeValue();
2346 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2349 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2351 // count shapes excluding compounds corresponding to geom groups
2352 int oldNbSubShapes = meshDS->MaxShapeIndex();
2353 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2355 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2356 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2359 std::set<int> subIds;
2360 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2361 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2362 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2365 // check if shape topology changes - save shape type per shape ID
2366 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2367 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2368 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2370 // change shape to mesh
2371 _impl->ShapeToMesh( TopoDS_Shape() );
2372 _impl->ShapeToMesh( newShape );
2374 // check if shape topology changes - check new shape types
2375 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2376 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2378 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2379 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2382 // re-add shapes (compounds) of geom groups
2383 std::map< int, int > old2newIDs; // group IDs
2384 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2385 for ( ; data != _geomGroupData.end(); ++data )
2388 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2389 if ( ii2i != ii2iMap.end() )
2390 oldID = ii2i->second;
2392 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2393 if ( !newShape.IsNull() )
2395 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2397 TopoDS_Compound compound;
2398 BRep_Builder().MakeCompound( compound );
2399 BRep_Builder().Add( compound, newShape );
2400 newShape = compound;
2402 int newID = _impl->GetSubMesh( newShape )->GetId();
2403 if ( oldID && oldID != newID )
2404 old2newIDs.insert( std::make_pair( oldID, newID ));
2408 // re-assign hypotheses
2409 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2411 if ( !sameTopology && ids2Hyps[i].first != 1 )
2412 continue; // assign only global hypos
2413 int sID = ids2Hyps[i].first;
2414 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2415 if ( o2n != old2newIDs.end() )
2417 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2418 const THypList& hyps = ids2Hyps[i].second;
2419 THypList::const_iterator h = hyps.begin();
2420 for ( ; h != hyps.end(); ++h )
2421 _impl->AddHypothesis( s, (*h)->GetID() );
2424 if ( !sameTopology )
2426 // remove invalid study sub-objects
2427 CheckGeomGroupModif();
2431 // restore groups on geometry
2432 for ( size_t i = 0; i < groupsData.size(); ++i )
2434 const TGroupOnGeomData& data = groupsData[i];
2435 if ( data._shape.IsNull() )
2438 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2439 if ( i2g == _mapGroups.end() ) continue;
2441 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2442 if ( !gr_i ) continue;
2444 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2446 _mapGroups.erase( i2g );
2448 g->GetGroupDS()->SetColor( data._color );
2451 std::map< int, int >::iterator o2n = old2newIDs.begin();
2452 for ( ; o2n != old2newIDs.end(); ++o2n )
2454 int newID = o2n->second, oldID = o2n->first;
2455 if ( !_mapSubMesh.count( oldID ))
2457 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2458 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2459 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2460 _mapSubMesh. erase(oldID);
2461 _mapSubMesh_i. erase(oldID);
2462 _mapSubMeshIor.erase(oldID);
2463 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2466 // update _mapSubMesh
2467 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2468 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2469 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2472 _gen_i->UpdateIcons( SMESH::SMESH_Mesh_var( _this() ));
2475 //=============================================================================
2477 * \brief Update objects depending on changed geom groups
2479 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2480 * issue 0020210: Update of a smesh group after modification of the associated geom group
2482 //=============================================================================
2484 void SMESH_Mesh_i::CheckGeomGroupModif()
2486 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2487 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2488 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2489 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2490 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2492 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2493 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2494 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2496 int nbValid = 0, nbRemoved = 0;
2497 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2498 for ( ; chItr->More(); chItr->Next() )
2500 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2501 if ( !smSO->_is_nil() &&
2502 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2503 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2505 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2506 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2507 if ( !geom->_non_existent() )
2510 continue; // keep the sub-mesh
2513 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2514 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2515 if ( !sm->_is_nil() && !sm->_non_existent() )
2517 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2518 if ( smGeom->_is_nil() )
2520 RemoveSubMesh( sm );
2527 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2528 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2532 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2533 builder->RemoveObjectWithChildren( rootSO );
2537 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2538 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2539 while ( i_gr != _mapGroups.end())
2541 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2543 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2544 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2545 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2546 bool isValidGeom = false;
2547 if ( !onGeom->_is_nil() )
2549 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2551 else if ( !onFilt->_is_nil() )
2553 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2557 isValidGeom = ( !groupSO->_is_nil() &&
2558 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2562 if ( !IsLoaded() || group->IsEmpty() )
2564 RemoveGroup( group );
2566 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2568 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2570 else // is it possible?
2572 builder->RemoveObjectWithChildren( refSO );
2578 if ( !_impl->HasShapeToMesh() ) return;
2580 CORBA::Long nbEntities = NbNodes() + NbElements();
2582 // Check if group contents changed
2584 typedef map< string, TopoDS_Shape > TEntry2Geom;
2585 TEntry2Geom newGroupContents;
2587 list<TGeomGroupData>::iterator
2588 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2589 for ( ; data != dataEnd; ++data )
2591 pair< TEntry2Geom::iterator, bool > it_new =
2592 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2593 bool processedGroup = !it_new.second;
2594 TopoDS_Shape& newShape = it_new.first->second;
2595 if ( !processedGroup )
2596 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2597 if ( newShape.IsNull() )
2598 continue; // no changes
2601 _preMeshInfo->ForgetOrLoad();
2603 if ( processedGroup ) { // update group indices
2604 list<TGeomGroupData>::iterator data2 = data;
2605 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2606 data->_indices = data2->_indices;
2609 // Update SMESH objects according to new GEOM group contents
2611 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2612 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2614 int oldID = submesh->GetId();
2615 if ( !_mapSubMeshIor.count( oldID ))
2617 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2619 // update hypotheses
2620 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2621 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2622 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2624 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2625 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2627 // care of submeshes
2628 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2629 int newID = newSubmesh->GetId();
2630 if ( newID != oldID ) {
2631 _mapSubMesh [ newID ] = newSubmesh;
2632 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2633 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2634 _mapSubMesh. erase(oldID);
2635 _mapSubMesh_i. erase(oldID);
2636 _mapSubMeshIor.erase(oldID);
2637 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2642 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2643 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2644 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2646 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2648 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2649 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2650 ds->SetShape( newShape );
2655 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2656 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2658 // Remove groups and submeshes basing on removed sub-shapes
2660 TopTools_MapOfShape newShapeMap;
2661 TopoDS_Iterator shapeIt( newShape );
2662 for ( ; shapeIt.More(); shapeIt.Next() )
2663 newShapeMap.Add( shapeIt.Value() );
2665 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2666 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2668 if ( newShapeMap.Contains( shapeIt.Value() ))
2670 TopTools_IndexedMapOfShape oldShapeMap;
2671 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2672 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2674 const TopoDS_Shape& oldShape = oldShapeMap(i);
2675 int oldInd = meshDS->ShapeToIndex( oldShape );
2677 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2678 if ( i_smIor != _mapSubMeshIor.end() ) {
2679 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2682 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2683 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2685 // check if a group bases on oldInd shape
2686 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2687 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2688 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2689 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2691 RemoveGroup( i_grp->second ); // several groups can base on same shape
2692 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2697 // Reassign hypotheses and update groups after setting the new shape to mesh
2699 // collect anassigned hypotheses
2700 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2701 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2702 TShapeHypList assignedHyps;
2703 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2705 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2706 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2707 if ( !hyps.empty() ) {
2708 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2709 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2710 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2713 // collect shapes supporting groups
2714 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2715 TShapeTypeList groupData;
2716 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2717 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2718 for ( ; grIt != groups.end(); ++grIt )
2720 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2722 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2724 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2726 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2727 _impl->ShapeToMesh( newShape );
2729 // reassign hypotheses
2730 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2731 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2733 TIndexedShape& geom = indS_hyps->first;
2734 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2735 int oldID = geom._index;
2736 int newID = meshDS->ShapeToIndex( geom._shape );
2737 if ( oldID == 1 ) { // main shape
2739 geom._shape = newShape;
2743 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2744 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2745 // care of sub-meshes
2746 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2747 if ( newID != oldID ) {
2748 _mapSubMesh [ newID ] = newSubmesh;
2749 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2750 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2751 _mapSubMesh. erase(oldID);
2752 _mapSubMesh_i. erase(oldID);
2753 _mapSubMeshIor.erase(oldID);
2754 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2758 TShapeTypeList::iterator geomType = groupData.begin();
2759 for ( ; geomType != groupData.end(); ++geomType )
2761 const TIndexedShape& geom = geomType->first;
2762 int oldID = geom._index;
2763 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2766 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2767 CORBA::String_var name = groupSO->GetName();
2769 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2770 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2771 /*id=*/-1, geom._shape ))
2772 group_i->changeLocalId( group->GetID() );
2775 break; // everything has been updated
2778 } // loop on group data
2782 CORBA::Long newNbEntities = NbNodes() + NbElements();
2783 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2784 if ( newNbEntities != nbEntities )
2786 // Add all SObjects with icons to soToUpdateIcons
2787 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2789 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2790 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2791 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2793 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2794 i_gr != _mapGroups.end(); ++i_gr ) // groups
2795 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2798 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2799 for ( ; so != soToUpdateIcons.end(); ++so )
2800 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2803 //=============================================================================
2805 * \brief Create standalone group from a group on geometry or filter
2807 //=============================================================================
2809 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2810 throw (SALOME::SALOME_Exception)
2812 SMESH::SMESH_Group_var aGroup;
2817 _preMeshInfo->FullLoadFromFile();
2819 if ( theGroup->_is_nil() )
2820 return aGroup._retn();
2822 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2824 return aGroup._retn();
2826 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2828 const int anId = aGroupToRem->GetLocalID();
2829 if ( !_impl->ConvertToStandalone( anId ) )
2830 return aGroup._retn();
2831 removeGeomGroupData( theGroup );
2833 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2835 // remove old instance of group from own map
2836 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2837 _mapGroups.erase( anId );
2839 SALOMEDS::StudyBuilder_var builder;
2840 SALOMEDS::SObject_wrap aGroupSO;
2841 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2842 if ( !aStudy->_is_nil() ) {
2843 builder = aStudy->NewBuilder();
2844 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2845 if ( !aGroupSO->_is_nil() )
2847 // remove reference to geometry
2848 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2849 for ( ; chItr->More(); chItr->Next() )
2851 // Remove group's child SObject
2852 SALOMEDS::SObject_wrap so = chItr->Value();
2853 builder->RemoveObject( so );
2855 // Update Python script
2856 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2857 << ".ConvertToStandalone( " << aGroupSO << " )";
2859 // change icon of Group on Filter
2862 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2863 // const int isEmpty = ( elemTypes->length() == 0 );
2866 SALOMEDS::GenericAttribute_wrap anAttr =
2867 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2868 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2869 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2875 // remember new group in own map
2876 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2877 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2879 // register CORBA object for persistence
2880 _gen_i->RegisterObject( aGroup );
2882 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2883 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2884 //aGroup->Register();
2885 aGroupToRem->UnRegister();
2887 SMESH_CATCH( SMESH::throwCorbaException );
2889 return aGroup._retn();
2892 //=============================================================================
2896 //=============================================================================
2898 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2900 if(MYDEBUG) MESSAGE( "createSubMesh" );
2901 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2902 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2905 SMESH_subMesh_i * subMeshServant;
2908 subMeshId = mySubMesh->GetId();
2909 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2911 else // "invalid sub-mesh"
2913 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2914 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2915 if ( _mapSubMesh.empty() )
2918 subMeshId = _mapSubMesh.begin()->first - 1;
2919 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2922 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2924 _mapSubMesh [subMeshId] = mySubMesh;
2925 _mapSubMesh_i [subMeshId] = subMeshServant;
2926 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2928 subMeshServant->Register();
2930 // register CORBA object for persistence
2931 int nextId = _gen_i->RegisterObject( subMesh );
2932 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2933 else { nextId = 0; } // avoid "unused variable" warning
2935 // to track changes of GEOM groups
2936 if ( subMeshId > 0 )
2937 addGeomGroupData( theSubShapeObject, subMesh );
2939 return subMesh._retn();
2942 //=======================================================================
2943 //function : getSubMesh
2945 //=======================================================================
2947 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2949 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2950 if ( it == _mapSubMeshIor.end() )
2951 return SMESH::SMESH_subMesh::_nil();
2953 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2956 //=============================================================================
2960 //=============================================================================
2962 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2963 GEOM::GEOM_Object_ptr theSubShapeObject )
2965 bool isHypChanged = false;
2966 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2967 return isHypChanged;
2969 const int subMeshId = theSubMesh->GetId();
2971 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2974 if (( _mapSubMesh.count( subMeshId )) &&
2975 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2977 TopoDS_Shape S = sm->GetSubShape();
2980 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2981 isHypChanged = !hyps.empty();
2982 if ( isHypChanged && _preMeshInfo )
2983 _preMeshInfo->ForgetOrLoad();
2984 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2985 for ( ; hyp != hyps.end(); ++hyp )
2986 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2993 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2994 isHypChanged = ( aHypList->length() > 0 );
2995 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2996 removeHypothesis( theSubShapeObject, aHypList[i] );
2999 catch( const SALOME::SALOME_Exception& ) {
3000 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3002 removeGeomGroupData( theSubShapeObject );
3006 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3007 if ( id_smi != _mapSubMesh_i.end() )
3008 id_smi->second->UnRegister();
3010 // remove a CORBA object
3011 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3012 if ( id_smptr != _mapSubMeshIor.end() )
3013 SMESH::SMESH_subMesh_var( id_smptr->second );
3015 _mapSubMesh.erase(subMeshId);
3016 _mapSubMesh_i.erase(subMeshId);
3017 _mapSubMeshIor.erase(subMeshId);
3019 return isHypChanged;
3022 //=============================================================================
3026 //=============================================================================
3028 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3029 const char* theName,
3031 const TopoDS_Shape& theShape,
3032 const SMESH_PredicatePtr& thePredicate )
3034 std::string newName;
3035 if ( !theName || !theName[0] )
3037 std::set< std::string > presentNames;
3038 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3039 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3041 CORBA::String_var name = i_gr->second->GetName();
3042 presentNames.insert( name.in() );
3045 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3046 } while ( !presentNames.insert( newName ).second );
3047 theName = newName.c_str();
3049 SMESH::SMESH_GroupBase_var aGroup;
3050 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3051 theID, theShape, thePredicate ))
3053 int anId = g->GetID();
3054 SMESH_GroupBase_i* aGroupImpl;
3055 if ( !theShape.IsNull() )
3056 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3057 else if ( thePredicate )
3058 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3060 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3062 aGroup = aGroupImpl->_this();
3063 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3064 aGroupImpl->Register();
3066 // register CORBA object for persistence
3067 int nextId = _gen_i->RegisterObject( aGroup );
3068 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3069 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3071 // to track changes of GEOM groups
3072 if ( !theShape.IsNull() ) {
3073 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3074 addGeomGroupData( geom, aGroup );
3077 return aGroup._retn();
3080 //=============================================================================
3082 * SMESH_Mesh_i::removeGroup
3084 * Should be called by ~SMESH_Group_i()
3086 //=============================================================================
3088 void SMESH_Mesh_i::removeGroup( const int theId )
3090 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3091 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3092 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3093 _mapGroups.erase( theId );
3094 removeGeomGroupData( group );
3095 if ( !_impl->RemoveGroup( theId ))
3097 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3098 RemoveGroup( group );
3100 group->UnRegister();
3104 //=============================================================================
3108 //=============================================================================
3110 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3111 throw(SALOME::SALOME_Exception)
3113 SMESH::log_array_var aLog;
3117 _preMeshInfo->FullLoadFromFile();
3119 list < SMESHDS_Command * >logDS = _impl->GetLog();
3120 aLog = new SMESH::log_array;
3122 int lg = logDS.size();
3125 list < SMESHDS_Command * >::iterator its = logDS.begin();
3126 while(its != logDS.end()){
3127 SMESHDS_Command *com = *its;
3128 int comType = com->GetType();
3130 int lgcom = com->GetNumber();
3132 const list < int >&intList = com->GetIndexes();
3133 int inum = intList.size();
3135 list < int >::const_iterator ii = intList.begin();
3136 const list < double >&coordList = com->GetCoords();
3137 int rnum = coordList.size();
3139 list < double >::const_iterator ir = coordList.begin();
3140 aLog[indexLog].commandType = comType;
3141 aLog[indexLog].number = lgcom;
3142 aLog[indexLog].coords.length(rnum);
3143 aLog[indexLog].indexes.length(inum);
3144 for(int i = 0; i < rnum; i++){
3145 aLog[indexLog].coords[i] = *ir;
3146 //MESSAGE(" "<<i<<" "<<ir.Value());
3149 for(int i = 0; i < inum; i++){
3150 aLog[indexLog].indexes[i] = *ii;
3151 //MESSAGE(" "<<i<<" "<<ii.Value());
3160 SMESH_CATCH( SMESH::throwCorbaException );
3162 return aLog._retn();
3166 //=============================================================================
3170 //=============================================================================
3172 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3176 SMESH_CATCH( SMESH::throwCorbaException );
3179 //=============================================================================
3183 //=============================================================================
3185 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3190 //=============================================================================
3193 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3194 // issue 0020918: groups removal is caused by hyp modification
3195 // issue 0021208: to forget not loaded mesh data at hyp modification
3196 struct TCallUp_i : public SMESH_Mesh::TCallUp
3198 SMESH_Mesh_i* _mesh;
3199 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3200 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3201 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3202 virtual void Load () { _mesh->Load(); }
3206 //================================================================================
3208 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3210 //================================================================================
3212 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3215 _preMeshInfo->ForgetOrLoad();
3217 SMESH::SMESH_Mesh_var mesh = _this();
3218 _gen_i->UpdateIcons( mesh );
3220 // mark a hypothesis as valid after edition
3221 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3222 SALOMEDS::SObject_wrap hypRoot;
3223 if ( !smeshComp->_is_nil() &&
3224 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3226 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3227 for ( ; anIter->More(); anIter->Next() )
3229 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3230 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3231 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3232 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3233 _gen_i->HighLightInvalid( hyp, false );
3238 //=============================================================================
3242 //=============================================================================
3244 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3246 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3249 _impl->SetCallUp( new TCallUp_i(this));
3252 //=============================================================================
3256 //=============================================================================
3258 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3260 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3264 //=============================================================================
3266 * Return mesh editor
3268 //=============================================================================
3270 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3271 throw (SALOME::SALOME_Exception)
3273 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3277 _preMeshInfo->FullLoadFromFile();
3279 // Create MeshEditor
3281 _editor = new SMESH_MeshEditor_i( this, false );
3282 aMeshEdVar = _editor->_this();
3284 // Update Python script
3285 TPythonDump() << _editor << " = "
3286 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3288 SMESH_CATCH( SMESH::throwCorbaException );
3290 return aMeshEdVar._retn();
3293 //=============================================================================
3295 * Return mesh edition previewer
3297 //=============================================================================
3299 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3300 throw (SALOME::SALOME_Exception)
3302 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3306 _preMeshInfo->FullLoadFromFile();
3308 if ( !_previewEditor )
3309 _previewEditor = new SMESH_MeshEditor_i( this, true );
3310 aMeshEdVar = _previewEditor->_this();
3312 SMESH_CATCH( SMESH::throwCorbaException );
3314 return aMeshEdVar._retn();
3317 //================================================================================
3319 * \brief Return true if the mesh has been edited since a last total re-compute
3320 * and those modifications may prevent successful partial re-compute
3322 //================================================================================
3324 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3326 Unexpect aCatch(SALOME_SalomeException);
3327 return _impl->HasModificationsToDiscard();
3330 //================================================================================
3332 * \brief Returns a random unique color
3334 //================================================================================
3336 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3338 const int MAX_ATTEMPTS = 100;
3340 double tolerance = 0.5;
3341 SALOMEDS::Color col;
3345 // generate random color
3346 double red = (double)rand() / RAND_MAX;
3347 double green = (double)rand() / RAND_MAX;
3348 double blue = (double)rand() / RAND_MAX;
3349 // check existence in the list of the existing colors
3350 bool matched = false;
3351 std::list<SALOMEDS::Color>::const_iterator it;
3352 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3353 SALOMEDS::Color color = *it;
3354 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3355 matched = tol < tolerance;
3357 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3358 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3366 //=============================================================================
3368 * Sets auto-color mode. If it is on, groups get unique random colors
3370 //=============================================================================
3372 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3374 Unexpect aCatch(SALOME_SalomeException);
3375 _impl->SetAutoColor(theAutoColor);
3377 TPythonDump pyDump; // not to dump group->SetColor() from below code
3378 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3380 std::list<SALOMEDS::Color> aReservedColors;
3381 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3382 for ( ; it != _mapGroups.end(); it++ ) {
3383 if ( CORBA::is_nil( it->second )) continue;
3384 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3385 it->second->SetColor( aColor );
3386 aReservedColors.push_back( aColor );
3390 //=============================================================================
3392 * Returns true if auto-color mode is on
3394 //=============================================================================
3396 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3398 Unexpect aCatch(SALOME_SalomeException);
3399 return _impl->GetAutoColor();
3402 //=============================================================================
3404 * Checks if there are groups with equal names
3406 //=============================================================================
3408 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3410 return _impl->HasDuplicatedGroupNamesMED();
3413 //================================================================================
3415 * \brief Care of a file before exporting mesh into it
3417 //================================================================================
3419 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3421 SMESH_File aFile( file, false );
3423 if ( aFile.exists() ) {
3424 // existing filesystem node
3425 if ( !aFile.isDirectory() ) {
3426 if ( aFile.openForWriting() ) {
3427 if ( overwrite && ! aFile.remove()) {
3428 msg << "Can't replace " << aFile.getName();
3431 msg << "Can't write into " << aFile.getName();
3434 msg << "Location " << aFile.getName() << " is not a file";
3438 // nonexisting file; check if it can be created
3439 if ( !aFile.openForWriting() ) {
3440 msg << "You cannot create the file "
3442 << ". Check the directory existence and access rights";
3450 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3454 //================================================================================
3456 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3457 * \param file - file name
3458 * \param overwrite - to erase the file or not
3459 * \retval string - mesh name
3461 //================================================================================
3463 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3464 CORBA::Boolean overwrite)
3467 PrepareForWriting(file, overwrite);
3468 string aMeshName = "Mesh";
3469 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3470 if ( !aStudy->_is_nil() ) {
3471 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3472 if ( !aMeshSO->_is_nil() ) {
3473 CORBA::String_var name = aMeshSO->GetName();
3475 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3476 if ( !aStudy->GetProperties()->IsLocked() )
3478 SALOMEDS::GenericAttribute_wrap anAttr;
3479 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3480 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3481 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3482 ASSERT(!aFileName->_is_nil());
3483 aFileName->SetValue(file);
3484 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3485 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3486 ASSERT(!aFileType->_is_nil());
3487 aFileType->SetValue("FICHIERMED");
3491 // Update Python script
3492 // set name of mesh before export
3493 TPythonDump() << _gen_i << ".SetName("
3494 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3496 // check names of groups
3502 //================================================================================
3504 * \brief Export to MED file
3506 //================================================================================
3508 void SMESH_Mesh_i::ExportMED(const char* file,
3509 CORBA::Boolean auto_groups,
3510 CORBA::Long version,
3511 CORBA::Boolean overwrite,
3512 CORBA::Boolean autoDimension)
3513 throw(SALOME::SALOME_Exception)
3515 //MESSAGE("MED minor version: "<< minor);
3518 _preMeshInfo->FullLoadFromFile();
3520 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3521 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3523 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3525 << "auto_groups=" <<auto_groups << ", "
3526 << "minor=" << version << ", "
3527 << "overwrite=" << overwrite << ", "
3528 << "meshPart=None, "
3529 << "autoDimension=" << autoDimension << " )";
3531 SMESH_CATCH( SMESH::throwCorbaException );
3534 //================================================================================
3536 * \brief Export a mesh to a SAUV file
3538 //================================================================================
3540 void SMESH_Mesh_i::ExportSAUV (const char* file,
3541 CORBA::Boolean auto_groups)
3542 throw(SALOME::SALOME_Exception)
3544 Unexpect aCatch(SALOME_SalomeException);
3546 _preMeshInfo->FullLoadFromFile();
3548 string aMeshName = prepareMeshNameAndGroups(file, true);
3549 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3550 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3551 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3555 //================================================================================
3557 * \brief Export a mesh to a DAT file
3559 //================================================================================
3561 void SMESH_Mesh_i::ExportDAT (const char *file)
3562 throw(SALOME::SALOME_Exception)
3564 Unexpect aCatch(SALOME_SalomeException);
3566 _preMeshInfo->FullLoadFromFile();
3568 // Update Python script
3569 // check names of groups
3571 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3574 PrepareForWriting(file);
3575 _impl->ExportDAT(file);
3578 //================================================================================
3580 * \brief Export a mesh to an UNV file
3582 //================================================================================
3584 void SMESH_Mesh_i::ExportUNV (const char *file)
3585 throw(SALOME::SALOME_Exception)
3587 Unexpect aCatch(SALOME_SalomeException);
3589 _preMeshInfo->FullLoadFromFile();
3591 // Update Python script
3592 // check names of groups
3594 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3597 PrepareForWriting(file);
3598 _impl->ExportUNV(file);
3601 //================================================================================
3603 * \brief Export a mesh to an STL file
3605 //================================================================================
3607 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3608 throw(SALOME::SALOME_Exception)
3610 Unexpect aCatch(SALOME_SalomeException);
3612 _preMeshInfo->FullLoadFromFile();
3614 // Update Python script
3615 // check names of groups
3617 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3618 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3620 CORBA::String_var name;
3621 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3622 if ( !so->_is_nil() )
3623 name = so->GetName();
3626 PrepareForWriting( file );
3627 _impl->ExportSTL( file, isascii, name.in() );
3630 //================================================================================
3632 * \brief Export a part of mesh to a med file
3634 //================================================================================
3636 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3638 CORBA::Boolean auto_groups,
3639 CORBA::Long version,
3640 CORBA::Boolean overwrite,
3641 CORBA::Boolean autoDimension,
3642 const GEOM::ListOfFields& fields,
3643 const char* geomAssocFields,
3644 CORBA::Double ZTolerance)
3645 throw (SALOME::SALOME_Exception)
3647 MESSAGE("MED version: "<< version);
3650 _preMeshInfo->FullLoadFromFile();
3653 bool have0dField = false;
3654 if ( fields.length() > 0 )
3656 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3657 if ( shapeToMesh->_is_nil() )
3658 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3660 for ( size_t i = 0; i < fields.length(); ++i )
3662 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3663 THROW_SALOME_CORBA_EXCEPTION
3664 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3665 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3666 if ( fieldShape->_is_nil() )
3667 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3668 if ( !fieldShape->IsSame( shapeToMesh ) )
3669 THROW_SALOME_CORBA_EXCEPTION
3670 ( "Field defined not on shape", SALOME::BAD_PARAM);
3671 if ( fields[i]->GetDimension() == 0 )
3674 if ( geomAssocFields )
3675 for ( int i = 0; geomAssocFields[i]; ++i )
3676 switch ( geomAssocFields[i] ) {
3677 case 'v':case 'e':case 'f':case 's': break;
3678 case 'V':case 'E':case 'F':case 'S': break;
3679 default: THROW_SALOME_CORBA_EXCEPTION
3680 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3684 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3688 string aMeshName = "Mesh";
3689 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3690 if ( CORBA::is_nil( meshPart ) ||
3691 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3693 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3694 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3695 0, autoDimension, /*addODOnVertices=*/have0dField,
3697 meshDS = _impl->GetMeshDS();
3702 _preMeshInfo->FullLoadFromFile();
3704 PrepareForWriting(file, overwrite);
3706 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3707 if ( !SO->_is_nil() ) {
3708 CORBA::String_var name = SO->GetName();
3712 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3713 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3714 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3715 meshDS = tmpDSDeleter._obj = partDS;
3720 if ( _impl->HasShapeToMesh() )
3722 DriverMED_W_Field fieldWriter;
3723 fieldWriter.SetFile( file );
3724 fieldWriter.SetMeshName( aMeshName );
3725 fieldWriter.AddODOnVertices( have0dField );
3727 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3731 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3732 goList->length( fields.length() );
3733 for ( size_t i = 0; i < fields.length(); ++i )
3735 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3738 TPythonDump() << _this() << ".ExportPartToMED( "
3739 << meshPart << ", r'"
3741 << auto_groups << ", "
3743 << overwrite << ", "
3744 << autoDimension << ", "
3746 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3747 << TVar( ZTolerance )
3750 SMESH_CATCH( SMESH::throwCorbaException );
3753 //================================================================================
3755 * Write GEOM fields to MED file
3757 //================================================================================
3759 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3760 SMESHDS_Mesh* meshDS,
3761 const GEOM::ListOfFields& fields,
3762 const char* geomAssocFields)
3764 #define METH "SMESH_Mesh_i::exportMEDFields() "
3766 if (( fields.length() < 1 ) &&
3767 ( !geomAssocFields || !geomAssocFields[0] ))
3770 std::vector< std::vector< double > > dblVals;
3771 std::vector< std::vector< int > > intVals;
3772 std::vector< int > subIdsByDim[ 4 ];
3773 const double noneDblValue = 0.;
3774 const double noneIntValue = 0;
3776 for ( size_t iF = 0; iF < fields.length(); ++iF )
3780 int dim = fields[ iF ]->GetDimension();
3781 SMDSAbs_ElementType elemType;
3782 TopAbs_ShapeEnum shapeType;
3784 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3785 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3786 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3787 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3789 continue; // skip fields on whole shape
3791 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3792 if ( dataType == GEOM::FDT_String )
3794 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3795 if ( stepIDs->length() < 1 )
3797 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3798 if ( comps->length() < 1 )
3800 CORBA::String_var name = fields[ iF ]->GetName();
3802 if ( !fieldWriter.Set( meshDS,
3806 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3809 for ( size_t iC = 0; iC < comps->length(); ++iC )
3810 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3812 dblVals.resize( comps->length() );
3813 intVals.resize( comps->length() );
3815 // find sub-shape IDs
3817 std::vector< int >& subIds = subIdsByDim[ dim ];
3818 if ( subIds.empty() )
3819 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3820 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3821 subIds.push_back( id );
3825 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3829 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3831 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3832 if ( step->_is_nil() )
3835 CORBA::Long stamp = step->GetStamp();
3836 CORBA::Long id = step->GetID();
3837 fieldWriter.SetDtIt( int( stamp ), int( id ));
3839 // fill dblVals or intVals
3840 for ( size_t iC = 0; iC < comps->length(); ++iC )
3841 if ( dataType == GEOM::FDT_Double )
3843 dblVals[ iC ].clear();
3844 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3848 intVals[ iC ].clear();
3849 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3853 case GEOM::FDT_Double:
3855 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3856 if ( dblStep->_is_nil() ) continue;
3857 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3858 if ( vv->length() != subIds.size() * comps->length() )
3859 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3860 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3861 for ( size_t iC = 0; iC < comps->length(); ++iC )
3862 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3867 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3868 if ( intStep->_is_nil() ) continue;
3869 GEOM::ListOfLong_var vv = intStep->GetValues();
3870 if ( vv->length() != subIds.size() * comps->length() )
3871 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3872 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3873 for ( size_t iC = 0; iC < comps->length(); ++iC )
3874 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3877 case GEOM::FDT_Bool:
3879 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3880 if ( boolStep->_is_nil() ) continue;
3881 GEOM::short_array_var vv = boolStep->GetValues();
3882 if ( vv->length() != subIds.size() * comps->length() )
3883 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3884 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3885 for ( size_t iC = 0; iC < comps->length(); ++iC )
3886 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3892 // pass values to fieldWriter
3893 elemIt = fieldWriter.GetOrderedElems();
3894 if ( dataType == GEOM::FDT_Double )
3895 while ( elemIt->more() )
3897 const SMDS_MeshElement* e = elemIt->next();
3898 const int shapeID = e->getshapeId();
3899 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3900 for ( size_t iC = 0; iC < comps->length(); ++iC )
3901 fieldWriter.AddValue( noneDblValue );
3903 for ( size_t iC = 0; iC < comps->length(); ++iC )
3904 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3907 while ( elemIt->more() )
3909 const SMDS_MeshElement* e = elemIt->next();
3910 const int shapeID = e->getshapeId();
3911 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3912 for ( size_t iC = 0; iC < comps->length(); ++iC )
3913 fieldWriter.AddValue( (double) noneIntValue );
3915 for ( size_t iC = 0; iC < comps->length(); ++iC )
3916 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3920 fieldWriter.Perform();
3921 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3922 if ( res && res->IsKO() )
3924 if ( res->myComment.empty() )
3925 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3927 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3933 if ( !geomAssocFields || !geomAssocFields[0] )
3936 // write geomAssocFields
3938 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3939 shapeDim[ TopAbs_COMPOUND ] = 3;
3940 shapeDim[ TopAbs_COMPSOLID ] = 3;
3941 shapeDim[ TopAbs_SOLID ] = 3;
3942 shapeDim[ TopAbs_SHELL ] = 2;
3943 shapeDim[ TopAbs_FACE ] = 2;
3944 shapeDim[ TopAbs_WIRE ] = 1;
3945 shapeDim[ TopAbs_EDGE ] = 1;
3946 shapeDim[ TopAbs_VERTEX ] = 0;
3947 shapeDim[ TopAbs_SHAPE ] = 3;
3949 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3951 std::vector< std::string > compNames;
3952 switch ( geomAssocFields[ iF ]) {
3954 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3955 compNames.push_back( "dim" );
3958 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3961 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3964 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3968 compNames.push_back( "id" );
3969 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3970 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3972 fieldWriter.SetDtIt( -1, -1 );
3974 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3978 if ( compNames.size() == 2 ) // _vertices_
3979 while ( elemIt->more() )
3981 const SMDS_MeshElement* e = elemIt->next();
3982 const int shapeID = e->getshapeId();
3985 fieldWriter.AddValue( (double) -1 );
3986 fieldWriter.AddValue( (double) -1 );
3990 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3991 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3992 fieldWriter.AddValue( (double) shapeID );
3996 while ( elemIt->more() )
3998 const SMDS_MeshElement* e = elemIt->next();
3999 const int shapeID = e->getshapeId();
4001 fieldWriter.AddValue( (double) -1 );
4003 fieldWriter.AddValue( (double) shapeID );
4007 fieldWriter.Perform();
4008 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4009 if ( res && res->IsKO() )
4011 if ( res->myComment.empty() )
4012 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4014 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4017 } // loop on geomAssocFields
4022 //================================================================================
4024 * \brief Export a part of mesh to a DAT file
4026 //================================================================================
4028 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4030 throw (SALOME::SALOME_Exception)
4032 Unexpect aCatch(SALOME_SalomeException);
4034 _preMeshInfo->FullLoadFromFile();
4036 PrepareForWriting(file);
4038 SMESH_MeshPartDS partDS( meshPart );
4039 _impl->ExportDAT(file,&partDS);
4041 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4042 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4044 //================================================================================
4046 * \brief Export a part of mesh to an UNV file
4048 //================================================================================
4050 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4052 throw (SALOME::SALOME_Exception)
4054 Unexpect aCatch(SALOME_SalomeException);
4056 _preMeshInfo->FullLoadFromFile();
4058 PrepareForWriting(file);
4060 SMESH_MeshPartDS partDS( meshPart );
4061 _impl->ExportUNV(file, &partDS);
4063 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4064 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4066 //================================================================================
4068 * \brief Export a part of mesh to an STL file
4070 //================================================================================
4072 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4074 ::CORBA::Boolean isascii)
4075 throw (SALOME::SALOME_Exception)
4077 Unexpect aCatch(SALOME_SalomeException);
4079 _preMeshInfo->FullLoadFromFile();
4081 PrepareForWriting(file);
4083 CORBA::String_var name;
4084 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4085 if ( !so->_is_nil() )
4086 name = so->GetName();
4088 SMESH_MeshPartDS partDS( meshPart );
4089 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4091 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4092 << meshPart<< ", r'" << file << "', " << isascii << ")";
4095 //================================================================================
4097 * \brief Export a part of mesh to an STL file
4099 //================================================================================
4101 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4103 CORBA::Boolean overwrite,
4104 CORBA::Boolean groupElemsByType)
4105 throw (SALOME::SALOME_Exception)
4108 Unexpect aCatch(SALOME_SalomeException);
4110 _preMeshInfo->FullLoadFromFile();
4112 PrepareForWriting(file,overwrite);
4114 std::string meshName("");
4115 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4116 if ( !so->_is_nil() )
4118 CORBA::String_var name = so->GetName();
4119 meshName = name.in();
4123 SMESH_MeshPartDS partDS( meshPart );
4124 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4126 SMESH_CATCH( SMESH::throwCorbaException );
4128 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4129 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4131 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4135 //================================================================================
4137 * \brief Export a part of mesh to a GMF file
4139 //================================================================================
4141 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4143 bool withRequiredGroups)
4144 throw (SALOME::SALOME_Exception)
4146 Unexpect aCatch(SALOME_SalomeException);
4148 _preMeshInfo->FullLoadFromFile();
4150 PrepareForWriting(file,/*overwrite=*/true);
4152 SMESH_MeshPartDS partDS( meshPart );
4153 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4155 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4156 << meshPart<< ", r'"
4158 << withRequiredGroups << ")";
4161 //=============================================================================
4163 * Return computation progress [0.,1]
4165 //=============================================================================
4167 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4171 return _impl->GetComputeProgress();
4173 SMESH_CATCH( SMESH::doNothing );
4177 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4179 Unexpect aCatch(SALOME_SalomeException);
4181 return _preMeshInfo->NbNodes();
4183 return _impl->NbNodes();
4186 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4188 Unexpect aCatch(SALOME_SalomeException);
4190 return _preMeshInfo->NbElements();
4192 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4195 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4197 Unexpect aCatch(SALOME_SalomeException);
4199 return _preMeshInfo->Nb0DElements();
4201 return _impl->Nb0DElements();
4204 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4206 Unexpect aCatch(SALOME_SalomeException);
4208 return _preMeshInfo->NbBalls();
4210 return _impl->NbBalls();
4213 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4215 Unexpect aCatch(SALOME_SalomeException);
4217 return _preMeshInfo->NbEdges();
4219 return _impl->NbEdges();
4222 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4223 throw(SALOME::SALOME_Exception)
4225 Unexpect aCatch(SALOME_SalomeException);
4227 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4229 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4232 //=============================================================================
4234 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4236 Unexpect aCatch(SALOME_SalomeException);
4238 return _preMeshInfo->NbFaces();
4240 return _impl->NbFaces();
4243 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4245 Unexpect aCatch(SALOME_SalomeException);
4247 return _preMeshInfo->NbTriangles();
4249 return _impl->NbTriangles();
4252 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4254 Unexpect aCatch(SALOME_SalomeException);
4256 return _preMeshInfo->NbBiQuadTriangles();
4258 return _impl->NbBiQuadTriangles();
4261 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4263 Unexpect aCatch(SALOME_SalomeException);
4265 return _preMeshInfo->NbQuadrangles();
4267 return _impl->NbQuadrangles();
4270 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4272 Unexpect aCatch(SALOME_SalomeException);
4274 return _preMeshInfo->NbBiQuadQuadrangles();
4276 return _impl->NbBiQuadQuadrangles();
4279 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4281 Unexpect aCatch(SALOME_SalomeException);
4283 return _preMeshInfo->NbPolygons();
4285 return _impl->NbPolygons();
4288 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4290 Unexpect aCatch(SALOME_SalomeException);
4292 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4294 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4297 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4298 throw(SALOME::SALOME_Exception)
4300 Unexpect aCatch(SALOME_SalomeException);
4302 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4304 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4307 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4308 throw(SALOME::SALOME_Exception)
4310 Unexpect aCatch(SALOME_SalomeException);
4312 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4314 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4317 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4318 throw(SALOME::SALOME_Exception)
4320 Unexpect aCatch(SALOME_SalomeException);
4322 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4324 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4327 //=============================================================================
4329 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4331 Unexpect aCatch(SALOME_SalomeException);
4333 return _preMeshInfo->NbVolumes();
4335 return _impl->NbVolumes();
4338 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4340 Unexpect aCatch(SALOME_SalomeException);
4342 return _preMeshInfo->NbTetras();
4344 return _impl->NbTetras();
4347 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4349 Unexpect aCatch(SALOME_SalomeException);
4351 return _preMeshInfo->NbHexas();
4353 return _impl->NbHexas();
4356 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4358 Unexpect aCatch(SALOME_SalomeException);
4360 return _preMeshInfo->NbTriQuadHexas();
4362 return _impl->NbTriQuadraticHexas();
4365 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4367 Unexpect aCatch(SALOME_SalomeException);
4369 return _preMeshInfo->NbPyramids();
4371 return _impl->NbPyramids();
4374 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4376 Unexpect aCatch(SALOME_SalomeException);
4378 return _preMeshInfo->NbPrisms();
4380 return _impl->NbPrisms();
4383 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4385 Unexpect aCatch(SALOME_SalomeException);
4387 return _preMeshInfo->NbHexPrisms();
4389 return _impl->NbHexagonalPrisms();
4392 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4394 Unexpect aCatch(SALOME_SalomeException);
4396 return _preMeshInfo->NbPolyhedrons();
4398 return _impl->NbPolyhedrons();
4401 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4402 throw(SALOME::SALOME_Exception)
4404 Unexpect aCatch(SALOME_SalomeException);
4406 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4408 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4411 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4412 throw(SALOME::SALOME_Exception)
4414 Unexpect aCatch(SALOME_SalomeException);
4416 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4418 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4421 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4422 throw(SALOME::SALOME_Exception)
4424 Unexpect aCatch(SALOME_SalomeException);
4426 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4428 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4431 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4432 throw(SALOME::SALOME_Exception)
4434 Unexpect aCatch(SALOME_SalomeException);
4436 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4438 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4441 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4442 throw(SALOME::SALOME_Exception)
4444 Unexpect aCatch(SALOME_SalomeException);
4446 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4448 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4451 //=============================================================================
4453 * Returns nb of published sub-meshes
4455 //=============================================================================
4457 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4459 Unexpect aCatch(SALOME_SalomeException);
4460 return _mapSubMesh_i.size();
4463 //=============================================================================
4465 * Dumps mesh into a string
4467 //=============================================================================
4469 char* SMESH_Mesh_i::Dump()
4473 return CORBA::string_dup( os.str().c_str() );
4476 //=============================================================================
4478 * Method of SMESH_IDSource interface
4480 //=============================================================================
4482 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4484 return GetElementsId();
4487 //=============================================================================
4489 * Returns ids of all elements
4491 //=============================================================================
4493 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4494 throw (SALOME::SALOME_Exception)
4496 Unexpect aCatch(SALOME_SalomeException);
4498 _preMeshInfo->FullLoadFromFile();
4500 SMESH::long_array_var aResult = new SMESH::long_array();
4501 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4503 if ( aSMESHDS_Mesh == NULL )
4504 return aResult._retn();
4506 long nbElements = NbElements();
4507 aResult->length( nbElements );
4508 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4509 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4510 aResult[i] = anIt->next()->GetID();
4512 return aResult._retn();
4516 //=============================================================================
4518 * Returns ids of all elements of given type
4520 //=============================================================================
4522 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4523 throw (SALOME::SALOME_Exception)
4525 Unexpect aCatch(SALOME_SalomeException);
4527 _preMeshInfo->FullLoadFromFile();
4529 SMESH::long_array_var aResult = new SMESH::long_array();
4530 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4532 if ( aSMESHDS_Mesh == NULL )
4533 return aResult._retn();
4535 long nbElements = NbElements();
4537 // No sense in returning ids of elements along with ids of nodes:
4538 // when theElemType == SMESH::ALL, return node ids only if
4539 // there are no elements
4540 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4541 return GetNodesId();
4543 aResult->length( nbElements );
4547 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4548 while ( i < nbElements && anIt->more() )
4549 aResult[i++] = anIt->next()->GetID();
4551 aResult->length( i );
4553 return aResult._retn();
4556 //=============================================================================
4558 * Returns ids of all nodes
4560 //=============================================================================
4562 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4563 throw (SALOME::SALOME_Exception)
4565 Unexpect aCatch(SALOME_SalomeException);
4567 _preMeshInfo->FullLoadFromFile();
4569 SMESH::long_array_var aResult = new SMESH::long_array();
4570 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4572 if ( aMeshDS == NULL )
4573 return aResult._retn();
4575 long nbNodes = NbNodes();
4576 aResult->length( nbNodes );
4577 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4578 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4579 aResult[i] = anIt->next()->GetID();
4581 return aResult._retn();
4584 //=============================================================================
4588 //=============================================================================
4590 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4591 throw (SALOME::SALOME_Exception)
4593 SMESH::ElementType type = SMESH::ALL;
4597 _preMeshInfo->FullLoadFromFile();
4599 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4601 SMESH_CATCH( SMESH::throwCorbaException );
4606 //=============================================================================
4610 //=============================================================================
4612 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4613 throw (SALOME::SALOME_Exception)
4616 _preMeshInfo->FullLoadFromFile();
4618 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4620 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4622 return ( SMESH::EntityType ) e->GetEntityType();
4625 //=============================================================================
4629 //=============================================================================
4631 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4632 throw (SALOME::SALOME_Exception)
4635 _preMeshInfo->FullLoadFromFile();
4637 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4639 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4641 return ( SMESH::GeometryType ) e->GetGeomType();
4644 //=============================================================================
4646 * Returns ID of elements for given submesh
4648 //=============================================================================
4649 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4650 throw (SALOME::SALOME_Exception)
4652 SMESH::long_array_var aResult = new SMESH::long_array();
4656 _preMeshInfo->FullLoadFromFile();
4658 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4659 if(!SM) return aResult._retn();
4661 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4662 if(!SDSM) return aResult._retn();
4664 aResult->length(SDSM->NbElements());
4666 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4668 while ( eIt->more() ) {
4669 aResult[i++] = eIt->next()->GetID();
4672 SMESH_CATCH( SMESH::throwCorbaException );
4674 return aResult._retn();
4677 //=============================================================================
4679 * Returns ID of nodes for given submesh
4680 * If param all==true - returns all nodes, else -
4681 * returns only nodes on shapes.
4683 //=============================================================================
4685 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4687 throw (SALOME::SALOME_Exception)
4689 SMESH::long_array_var aResult = new SMESH::long_array();
4693 _preMeshInfo->FullLoadFromFile();
4695 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4696 if(!SM) return aResult._retn();
4698 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4699 if(!SDSM) return aResult._retn();
4702 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4703 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4704 while ( nIt->more() ) {
4705 const SMDS_MeshNode* elem = nIt->next();
4706 theElems.insert( elem->GetID() );
4709 else { // all nodes of submesh elements
4710 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4711 while ( eIt->more() ) {
4712 const SMDS_MeshElement* anElem = eIt->next();
4713 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4714 while ( nIt->more() ) {
4715 const SMDS_MeshElement* elem = nIt->next();
4716 theElems.insert( elem->GetID() );
4721 aResult->length(theElems.size());
4722 set<int>::iterator itElem;
4724 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4725 aResult[i++] = *itElem;
4727 SMESH_CATCH( SMESH::throwCorbaException );
4729 return aResult._retn();
4732 //=============================================================================
4734 * Returns type of elements for given submesh
4736 //=============================================================================
4738 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4739 throw (SALOME::SALOME_Exception)
4741 SMESH::ElementType type = SMESH::ALL;
4745 _preMeshInfo->FullLoadFromFile();
4747 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4748 if(!SM) return SMESH::ALL;
4750 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4751 if(!SDSM) return SMESH::ALL;
4753 if(SDSM->NbElements()==0)
4754 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4756 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4757 const SMDS_MeshElement* anElem = eIt->next();
4759 type = ( SMESH::ElementType ) anElem->GetType();
4761 SMESH_CATCH( SMESH::throwCorbaException );
4767 //=============================================================================
4769 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4771 //=============================================================================
4773 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4776 _preMeshInfo->FullLoadFromFile();
4778 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4779 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4784 //=============================================================================
4786 * Get XYZ coordinates of node as list of double
4787 * If there is not node for given ID - returns empty list
4789 //=============================================================================
4791 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4794 _preMeshInfo->FullLoadFromFile();
4796 SMESH::double_array_var aResult = new SMESH::double_array();
4797 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4798 if ( aMeshDS == NULL )
4799 return aResult._retn();
4802 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4804 return aResult._retn();
4808 aResult[0] = aNode->X();
4809 aResult[1] = aNode->Y();
4810 aResult[2] = aNode->Z();
4811 return aResult._retn();
4815 //=============================================================================
4817 * For given node returns list of IDs of inverse elements
4818 * If there is not node for given ID - returns empty list
4820 //=============================================================================
4822 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4823 SMESH::ElementType elemType)
4826 _preMeshInfo->FullLoadFromFile();
4828 SMESH::long_array_var aResult = new SMESH::long_array();
4829 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4830 if ( aMeshDS == NULL )
4831 return aResult._retn();
4834 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4836 return aResult._retn();
4838 // find inverse elements
4839 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4840 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4841 aResult->length( aNode->NbInverseElements( type ));
4842 for( int i = 0; eIt->more(); ++i )
4844 const SMDS_MeshElement* elem = eIt->next();
4845 aResult[ i ] = elem->GetID();
4847 return aResult._retn();
4850 //=============================================================================
4852 * \brief Return position of a node on shape
4854 //=============================================================================
4856 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4859 _preMeshInfo->FullLoadFromFile();
4861 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4862 aNodePosition->shapeID = 0;
4863 aNodePosition->shapeType = GEOM::SHAPE;
4865 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4866 if ( !mesh ) return aNodePosition;
4868 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4870 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4872 aNodePosition->shapeID = aNode->getshapeId();
4873 switch ( pos->GetTypeOfPosition() ) {
4875 aNodePosition->shapeType = GEOM::EDGE;
4876 aNodePosition->params.length(1);
4877 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4879 case SMDS_TOP_FACE: {
4880 SMDS_FacePositionPtr fPos = pos;
4881 aNodePosition->shapeType = GEOM::FACE;
4882 aNodePosition->params.length(2);
4883 aNodePosition->params[0] = fPos->GetUParameter();
4884 aNodePosition->params[1] = fPos->GetVParameter();
4887 case SMDS_TOP_VERTEX:
4888 aNodePosition->shapeType = GEOM::VERTEX;
4890 case SMDS_TOP_3DSPACE:
4891 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4892 aNodePosition->shapeType = GEOM::SOLID;
4893 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4894 aNodePosition->shapeType = GEOM::SHELL;
4900 return aNodePosition;
4903 //=============================================================================
4905 * \brief Return position of an element on shape
4907 //=============================================================================
4909 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4912 _preMeshInfo->FullLoadFromFile();
4914 SMESH::ElementPosition anElementPosition;
4915 anElementPosition.shapeID = 0;
4916 anElementPosition.shapeType = GEOM::SHAPE;
4918 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4919 if ( !mesh ) return anElementPosition;
4921 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4923 anElementPosition.shapeID = anElem->getshapeId();
4924 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4925 if ( !aSp.IsNull() ) {
4926 switch ( aSp.ShapeType() ) {
4928 anElementPosition.shapeType = GEOM::EDGE;
4931 anElementPosition.shapeType = GEOM::FACE;
4934 anElementPosition.shapeType = GEOM::VERTEX;
4937 anElementPosition.shapeType = GEOM::SOLID;
4940 anElementPosition.shapeType = GEOM::SHELL;
4946 return anElementPosition;
4949 //=============================================================================
4951 * If given element is node returns IDs of shape from position
4952 * If there is not node for given ID - returns -1
4954 //=============================================================================
4956 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4959 _preMeshInfo->FullLoadFromFile();
4961 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4962 if ( aMeshDS == NULL )
4966 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4968 return aNode->getshapeId();
4975 //=============================================================================
4977 * For given element returns ID of result shape after
4978 * ::FindShape() from SMESH_MeshEditor
4979 * If there is not element for given ID - returns -1
4981 //=============================================================================
4983 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4986 _preMeshInfo->FullLoadFromFile();
4988 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4989 if ( aMeshDS == NULL )
4992 // try to find element
4993 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4997 ::SMESH_MeshEditor aMeshEditor(_impl);
4998 int index = aMeshEditor.FindShape( elem );
5006 //=============================================================================
5008 * Returns number of nodes for given element
5009 * If there is not element for given ID - returns -1
5011 //=============================================================================
5013 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5016 _preMeshInfo->FullLoadFromFile();
5018 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5019 if ( aMeshDS == NULL ) return -1;
5020 // try to find element
5021 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5022 if(!elem) return -1;
5023 return elem->NbNodes();
5027 //=============================================================================
5029 * Returns ID of node by given index for given element
5030 * If there is not element for given ID - returns -1
5031 * If there is not node for given index - returns -2
5033 //=============================================================================
5035 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5038 _preMeshInfo->FullLoadFromFile();
5040 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5041 if ( aMeshDS == NULL ) return -1;
5042 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5043 if(!elem) return -1;
5044 if( index>=elem->NbNodes() || index<0 ) return -1;
5045 return elem->GetNode(index)->GetID();
5048 //=============================================================================
5050 * Returns IDs of nodes of given element
5052 //=============================================================================
5054 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5057 _preMeshInfo->FullLoadFromFile();
5059 SMESH::long_array_var aResult = new SMESH::long_array();
5060 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5062 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5064 aResult->length( elem->NbNodes() );
5065 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5066 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5067 aResult[ i ] = n->GetID();
5070 return aResult._retn();
5073 //=============================================================================
5075 * Returns true if given node is medium node
5076 * in given quadratic element
5078 //=============================================================================
5080 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5083 _preMeshInfo->FullLoadFromFile();
5085 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5086 if ( aMeshDS == NULL ) return false;
5088 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5089 if(!aNode) return false;
5090 // try to find element
5091 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5092 if(!elem) return false;
5094 return elem->IsMediumNode(aNode);
5098 //=============================================================================
5100 * Returns true if given node is medium node
5101 * in one of quadratic elements
5103 //=============================================================================
5105 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5106 SMESH::ElementType theElemType)
5109 _preMeshInfo->FullLoadFromFile();
5111 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5112 if ( aMeshDS == NULL ) return false;
5115 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5116 if(!aNode) return false;
5118 SMESH_MesherHelper aHelper( *(_impl) );
5120 SMDSAbs_ElementType aType;
5121 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5122 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5123 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5124 else aType = SMDSAbs_All;
5126 return aHelper.IsMedium(aNode,aType);
5130 //=============================================================================
5132 * Returns number of edges for given element
5134 //=============================================================================
5136 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5139 _preMeshInfo->FullLoadFromFile();
5141 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5142 if ( aMeshDS == NULL ) return -1;
5143 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5144 if(!elem) return -1;
5145 return elem->NbEdges();
5149 //=============================================================================
5151 * Returns number of faces for given element
5153 //=============================================================================
5155 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5158 _preMeshInfo->FullLoadFromFile();
5160 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5161 if ( aMeshDS == NULL ) return -1;
5162 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5163 if(!elem) return -1;
5164 return elem->NbFaces();
5167 //=======================================================================
5168 //function : GetElemFaceNodes
5169 //purpose : Returns nodes of given face (counted from zero) for given element.
5170 //=======================================================================
5172 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5173 CORBA::Short faceIndex)
5176 _preMeshInfo->FullLoadFromFile();
5178 SMESH::long_array_var aResult = new SMESH::long_array();
5179 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5181 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5183 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5184 if ( faceIndex < vtool.NbFaces() )
5186 aResult->length( vtool.NbFaceNodes( faceIndex ));
5187 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5188 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5189 aResult[ i ] = nn[ i ]->GetID();
5193 return aResult._retn();
5196 //=======================================================================
5197 //function : GetFaceNormal
5198 //purpose : Returns three components of normal of given mesh face.
5199 //=======================================================================
5201 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5202 CORBA::Boolean normalized)
5205 _preMeshInfo->FullLoadFromFile();
5207 SMESH::double_array_var aResult = new SMESH::double_array();
5209 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5212 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5214 aResult->length( 3 );
5215 aResult[ 0 ] = normal.X();
5216 aResult[ 1 ] = normal.Y();
5217 aResult[ 2 ] = normal.Z();
5220 return aResult._retn();
5223 //=======================================================================
5224 //function : FindElementByNodes
5225 //purpose : Returns an element based on all given nodes.
5226 //=======================================================================
5228 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5231 _preMeshInfo->FullLoadFromFile();
5233 CORBA::Long elemID(0);
5234 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5236 vector< const SMDS_MeshNode * > nn( nodes.length() );
5237 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5238 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5241 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5242 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5243 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5244 _impl->NbVolumes( ORDER_QUADRATIC )))
5245 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5247 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5252 //================================================================================
5254 * \brief Return elements including all given nodes.
5256 //================================================================================
5258 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5259 SMESH::ElementType elemType)
5262 _preMeshInfo->FullLoadFromFile();
5264 SMESH::long_array_var result = new SMESH::long_array();
5266 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5268 vector< const SMDS_MeshNode * > nn( nodes.length() );
5269 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5270 nn[i] = mesh->FindNode( nodes[i] );
5272 std::vector<const SMDS_MeshElement *> elems;
5273 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5274 result->length( elems.size() );
5275 for ( size_t i = 0; i < elems.size(); ++i )
5276 result[i] = elems[i]->GetID();
5278 return result._retn();
5281 //=============================================================================
5283 * Returns true if given element is polygon
5285 //=============================================================================
5287 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5290 _preMeshInfo->FullLoadFromFile();
5292 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5293 if ( aMeshDS == NULL ) return false;
5294 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5295 if(!elem) return false;
5296 return elem->IsPoly();
5300 //=============================================================================
5302 * Returns true if given element is quadratic
5304 //=============================================================================
5306 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5309 _preMeshInfo->FullLoadFromFile();
5311 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5312 if ( aMeshDS == NULL ) return false;
5313 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5314 if(!elem) return false;
5315 return elem->IsQuadratic();
5318 //=============================================================================
5320 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5322 //=============================================================================
5324 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5327 _preMeshInfo->FullLoadFromFile();
5329 if ( const SMDS_BallElement* ball =
5330 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5331 return ball->GetDiameter();
5336 //=============================================================================
5338 * Returns bary center for given element
5340 //=============================================================================
5342 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5345 _preMeshInfo->FullLoadFromFile();
5347 SMESH::double_array_var aResult = new SMESH::double_array();
5348 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5349 if ( aMeshDS == NULL )
5350 return aResult._retn();
5352 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5354 return aResult._retn();
5356 if(elem->GetType()==SMDSAbs_Volume) {
5357 SMDS_VolumeTool aTool;
5358 if(aTool.Set(elem)) {
5360 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5365 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5367 double x=0., y=0., z=0.;
5368 for(; anIt->more(); ) {
5370 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5384 return aResult._retn();
5387 //================================================================================
5389 * \brief Create a group of elements preventing computation of a sub-shape
5391 //================================================================================
5393 SMESH::ListOfGroups*
5394 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5395 const char* theGroupName )
5396 throw ( SALOME::SALOME_Exception )
5398 Unexpect aCatch(SALOME_SalomeException);
5400 if ( !theGroupName || strlen( theGroupName) == 0 )
5401 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5403 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5404 ::SMESH_MeshEditor::ElemFeatures elemType;
5406 // submesh by subshape id
5407 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5408 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5411 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5412 if ( error && error->HasBadElems() )
5414 // sort bad elements by type
5415 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5416 const list<const SMDS_MeshElement*>& badElems =
5417 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5418 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5419 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5420 for ( ; elemIt != elemEnd; ++elemIt )
5422 const SMDS_MeshElement* elem = *elemIt;
5423 if ( !elem ) continue;
5425 if ( elem->GetID() < 1 )
5427 // elem is a temporary element, make a real element
5428 vector< const SMDS_MeshNode* > nodes;
5429 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5430 while ( nIt->more() && elem )
5432 nodes.push_back( nIt->next() );
5433 if ( nodes.back()->GetID() < 1 )
5434 elem = 0; // a temporary element on temporary nodes
5438 ::SMESH_MeshEditor editor( _impl );
5439 elem = editor.AddElement( nodes, elemType.Init( elem ));
5443 elemsByType[ elem->GetType() ].push_back( elem );
5446 // how many groups to create?
5448 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5449 nbTypes += int( !elemsByType[ i ].empty() );
5450 groups->length( nbTypes );
5453 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5455 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5456 if ( elems.empty() ) continue;
5458 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5459 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5461 SMESH::SMESH_Mesh_var mesh = _this();
5462 SALOMEDS::SObject_wrap aSO =
5463 _gen_i->PublishGroup( mesh, groups[ iG ],
5464 GEOM::GEOM_Object::_nil(), theGroupName);
5466 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5467 if ( !grp_i ) continue;
5469 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5470 for ( size_t iE = 0; iE < elems.size(); ++iE )
5471 grpDS->SMDSGroup().Add( elems[ iE ]);
5476 return groups._retn();
5479 //=============================================================================
5481 * Create and publish group servants if any groups were imported or created anyhow
5483 //=============================================================================
5485 void SMESH_Mesh_i::CreateGroupServants()
5487 SMESH::SMESH_Mesh_var aMesh = _this();
5490 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5491 while ( groupIt->more() )
5493 ::SMESH_Group* group = groupIt->next();
5494 int anId = group->GetID();
5496 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5497 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5499 addedIDs.insert( anId );
5501 SMESH_GroupBase_i* aGroupImpl;
5503 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5504 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5506 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5507 shape = groupOnGeom->GetShape();
5510 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5513 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5514 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5515 aGroupImpl->Register();
5517 // register CORBA object for persistence
5518 int nextId = _gen_i->RegisterObject( groupVar );
5519 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5520 else { nextId = 0; } // avoid "unused variable" warning in release mode
5522 // publishing the groups in the study
5523 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5524 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5526 if ( !addedIDs.empty() )
5529 set<int>::iterator id = addedIDs.begin();
5530 for ( ; id != addedIDs.end(); ++id )
5532 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5533 int i = std::distance( _mapGroups.begin(), it );
5534 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5539 //=============================================================================
5541 * \brief Return true if all sub-meshes are computed OK - to update an icon
5543 //=============================================================================
5545 bool SMESH_Mesh_i::IsComputedOK()
5547 return _impl->IsComputedOK();
5550 //=============================================================================
5552 * \brief Return groups cantained in _mapGroups by their IDs
5554 //=============================================================================
5556 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5558 int nbGroups = groupIDs.size();
5559 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5560 aList->length( nbGroups );
5562 list<int>::const_iterator ids = groupIDs.begin();
5563 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5565 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5566 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5567 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5569 aList->length( nbGroups );
5570 return aList._retn();
5573 //=============================================================================
5575 * \brief Return information about imported file
5577 //=============================================================================
5579 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5581 SMESH::MedFileInfo_var res( _medFileInfo );
5582 if ( !res.operator->() ) {
5583 res = new SMESH::MedFileInfo;
5585 res->fileSize = res->major = res->minor = res->release = -1;
5590 //=======================================================================
5591 //function : FileInfoToString
5592 //purpose : Persistence of file info
5593 //=======================================================================
5595 std::string SMESH_Mesh_i::FileInfoToString()
5598 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5600 s = SMESH_Comment( _medFileInfo->fileSize )
5601 << " " << _medFileInfo->major
5602 << " " << _medFileInfo->minor
5603 << " " << _medFileInfo->release
5604 << " " << _medFileInfo->fileName;
5609 //=======================================================================
5610 //function : FileInfoFromString
5611 //purpose : Persistence of file info
5612 //=======================================================================
5614 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5616 std::string size, major, minor, release, fileName;
5617 std::istringstream is(info);
5618 is >> size >> major >> minor >> release;
5619 fileName = info.data() + ( size.size() + 1 +
5622 release.size()+ 1 );
5624 _medFileInfo = new SMESH::MedFileInfo();
5625 _medFileInfo->fileName = fileName.c_str();
5626 _medFileInfo->fileSize = atoi( size.c_str() );
5627 _medFileInfo->major = atoi( major.c_str() );
5628 _medFileInfo->minor = atoi( minor.c_str() );
5629 _medFileInfo->release = atoi( release.c_str() );
5632 //=============================================================================
5634 * \brief Pass names of mesh groups from study to mesh DS
5636 //=============================================================================
5638 void SMESH_Mesh_i::checkGroupNames()
5640 int nbGrp = NbGroups();
5644 SMESH::ListOfGroups* grpList = 0;
5645 // avoid dump of "GetGroups"
5647 // store python dump into a local variable inside local scope
5648 SMESH::TPythonDump pDump; // do not delete this line of code
5649 grpList = GetGroups();
5652 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5653 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5656 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5657 if ( aGrpSO->_is_nil() )
5659 // correct name of the mesh group if necessary
5660 const char* guiName = aGrpSO->GetName();
5661 if ( strcmp(guiName, aGrp->GetName()) )
5662 aGrp->SetName( guiName );
5666 //=============================================================================
5668 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5670 //=============================================================================
5671 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5673 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5677 //=============================================================================
5679 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5681 //=============================================================================
5683 char* SMESH_Mesh_i::GetParameters()
5685 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5688 //=============================================================================
5690 * \brief Returns list of notebook variables used for last Mesh operation
5692 //=============================================================================
5693 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5695 SMESH::string_array_var aResult = new SMESH::string_array();
5696 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5698 CORBA::String_var aParameters = GetParameters();
5699 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5700 if ( aSections->length() > 0 ) {
5701 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5702 aResult->length( aVars.length() );
5703 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5704 aResult[i] = CORBA::string_dup( aVars[i] );
5707 return aResult._retn();
5710 //=======================================================================
5711 //function : GetTypes
5712 //purpose : Returns types of elements it contains
5713 //=======================================================================
5715 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5718 return _preMeshInfo->GetTypes();
5720 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5724 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5725 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5726 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5727 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5728 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5729 if (_impl->NbNodes() &&
5730 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5731 types->length( nbTypes );
5733 return types._retn();
5736 //=======================================================================
5737 //function : GetMesh
5738 //purpose : Returns self
5739 //=======================================================================
5741 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5743 return SMESH::SMESH_Mesh::_duplicate( _this() );
5746 //=======================================================================
5747 //function : IsMeshInfoCorrect
5748 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5749 // * happen if mesh data is not yet fully loaded from the file of study.
5750 //=======================================================================
5752 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5754 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5757 //=============================================================================
5759 * \brief Returns number of mesh elements per each \a EntityType
5761 //=============================================================================
5763 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5766 return _preMeshInfo->GetMeshInfo();
5768 SMESH::long_array_var aRes = new SMESH::long_array();
5769 aRes->length(SMESH::Entity_Last);
5770 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5772 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5774 return aRes._retn();
5775 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5776 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5777 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5778 return aRes._retn();
5781 //=============================================================================
5783 * \brief Returns number of mesh elements per each \a ElementType
5785 //=============================================================================
5787 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5789 SMESH::long_array_var aRes = new SMESH::long_array();
5790 aRes->length(SMESH::NB_ELEMENT_TYPES);
5791 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5794 const SMDS_MeshInfo* meshInfo = 0;
5796 meshInfo = _preMeshInfo;
5797 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5798 meshInfo = & meshDS->GetMeshInfo();
5801 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5802 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5804 return aRes._retn();
5807 //=============================================================================
5809 * Collect statistic of mesh elements given by iterator
5811 //=============================================================================
5813 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5814 SMESH::long_array& theInfo)
5816 if (!theItr) return;
5817 while (theItr->more())
5818 theInfo[ theItr->next()->GetEntityType() ]++;
5820 //=============================================================================
5822 * Returns mesh unstructed grid information.
5824 //=============================================================================
5826 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5828 SALOMEDS::TMPFile_var SeqFile;
5829 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5830 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5832 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5833 aWriter->WriteToOutputStringOn();
5834 aWriter->SetInputData(aGrid);
5835 aWriter->SetFileTypeToBinary();
5837 char* str = aWriter->GetOutputString();
5838 int size = aWriter->GetOutputStringLength();
5840 //Allocate octet buffer of required size
5841 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5842 //Copy ostrstream content to the octet buffer
5843 memcpy(OctetBuf, str, size);
5844 //Create and return TMPFile
5845 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5849 return SeqFile._retn();
5852 //=============================================================================
5853 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5854 * SMESH::ElementType type) */
5856 using namespace SMESH::Controls;
5857 //-----------------------------------------------------------------------------
5858 struct PredicateIterator : public SMDS_ElemIterator
5860 SMDS_ElemIteratorPtr _elemIter;
5861 PredicatePtr _predicate;
5862 const SMDS_MeshElement* _elem;
5863 SMDSAbs_ElementType _type;
5865 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5866 PredicatePtr predicate,
5867 SMDSAbs_ElementType type):
5868 _elemIter(iterator), _predicate(predicate), _type(type)
5876 virtual const SMDS_MeshElement* next()
5878 const SMDS_MeshElement* res = _elem;
5880 while ( _elemIter->more() && !_elem )
5882 if ((_elem = _elemIter->next()) &&
5883 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5884 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5891 //-----------------------------------------------------------------------------
5892 struct IDSourceIterator : public SMDS_ElemIterator
5894 const CORBA::Long* _idPtr;
5895 const CORBA::Long* _idEndPtr;
5896 SMESH::long_array_var _idArray;
5897 const SMDS_Mesh* _mesh;
5898 const SMDSAbs_ElementType _type;
5899 const SMDS_MeshElement* _elem;
5901 IDSourceIterator( const SMDS_Mesh* mesh,
5902 const CORBA::Long* ids,
5904 SMDSAbs_ElementType type):
5905 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5907 if ( _idPtr && nbIds && _mesh )
5910 IDSourceIterator( const SMDS_Mesh* mesh,
5911 SMESH::long_array* idArray,
5912 SMDSAbs_ElementType type):
5913 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5915 if ( idArray && _mesh )
5917 _idPtr = &_idArray[0];
5918 _idEndPtr = _idPtr + _idArray->length();
5926 virtual const SMDS_MeshElement* next()
5928 const SMDS_MeshElement* res = _elem;
5930 while ( _idPtr < _idEndPtr && !_elem )
5932 if ( _type == SMDSAbs_Node )
5934 _elem = _mesh->FindNode( *_idPtr++ );
5936 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5937 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5945 //-----------------------------------------------------------------------------
5947 struct NodeOfElemIterator : public SMDS_ElemIterator
5949 TColStd_MapOfInteger _checkedNodeIDs;
5950 SMDS_ElemIteratorPtr _elemIter;
5951 SMDS_ElemIteratorPtr _nodeIter;
5952 const SMDS_MeshElement* _node;
5954 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5956 if ( _elemIter && _elemIter->more() )
5958 _nodeIter = _elemIter->next()->nodesIterator();
5966 virtual const SMDS_MeshElement* next()
5968 const SMDS_MeshElement* res = _node;
5970 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5972 if ( _nodeIter->more() )
5974 _node = _nodeIter->next();
5975 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5980 _nodeIter = _elemIter->next()->nodesIterator();
5988 //=============================================================================
5990 * Return iterator on elements of given type in given object
5992 //=============================================================================
5994 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5995 SMESH::ElementType theType)
5997 SMDS_ElemIteratorPtr elemIt;
5998 bool typeOK = ( theType == SMESH::ALL );
5999 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6001 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6002 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6003 if ( !mesh_i ) return elemIt;
6004 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6006 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6008 elemIt = meshDS->elementsIterator( elemType );
6011 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6013 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6016 elemIt = sm->GetElements();
6017 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6019 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6020 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6024 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6026 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6027 if ( groupDS && ( elemType == groupDS->GetType() ||
6028 elemType == SMDSAbs_Node ||
6029 elemType == SMDSAbs_All ))
6031 elemIt = groupDS->GetElements();
6032 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6035 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6037 if ( filter_i->GetElementType() == theType ||
6038 filter_i->GetElementType() == SMESH::ALL ||
6039 elemType == SMDSAbs_Node ||
6040 elemType == SMDSAbs_All)
6042 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6043 if ( pred_i && pred_i->GetPredicate() )
6045 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6046 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6047 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6048 elemIt = SMDS_ElemIteratorPtr
6049 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6050 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6056 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6057 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6058 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6060 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6061 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6064 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6065 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6069 SMESH::long_array_var ids = theObject->GetIDs();
6070 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6072 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6075 if ( elemIt && elemIt->more() && !typeOK )
6077 if ( elemType == SMDSAbs_Node )
6079 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6083 elemIt = SMDS_ElemIteratorPtr();
6089 //=============================================================================
6090 namespace // Finding concurrent hypotheses
6091 //=============================================================================
6095 * \brief mapping of mesh dimension into shape type
6097 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6099 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6101 case 0: aType = TopAbs_VERTEX; break;
6102 case 1: aType = TopAbs_EDGE; break;
6103 case 2: aType = TopAbs_FACE; break;
6105 default:aType = TopAbs_SOLID; break;
6110 //-----------------------------------------------------------------------------
6112 * \brief Internal structure used to find concurrent submeshes
6114 * It represents a pair < submesh, concurrent dimension >, where
6115 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6116 * with another submesh. In other words, it is dimension of a hypothesis assigned
6123 int _dim; //!< a dimension the algo can build (concurrent dimension)
6124 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6125 TopTools_MapOfShape _shapeMap;
6126 SMESH_subMesh* _subMesh;
6127 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6129 //-----------------------------------------------------------------------------
6130 // Return the algorithm
6131 const SMESH_Algo* GetAlgo() const
6132 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6134 //-----------------------------------------------------------------------------
6136 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6138 const TopoDS_Shape& theShape)
6140 _subMesh = (SMESH_subMesh*)theSubMesh;
6141 SetShape( theDim, theShape );
6144 //-----------------------------------------------------------------------------
6146 void SetShape(const int theDim,
6147 const TopoDS_Shape& theShape)
6150 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6151 if (_dim >= _ownDim)
6152 _shapeMap.Add( theShape );
6154 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6155 for( ; anExp.More(); anExp.Next() )
6156 _shapeMap.Add( anExp.Current() );
6160 //-----------------------------------------------------------------------------
6161 //! Check sharing of sub-shapes
6162 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6163 const TopTools_MapOfShape& theToFind,
6164 const TopAbs_ShapeEnum theType)
6166 bool isShared = false;
6167 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6168 for (; !isShared && anItr.More(); anItr.Next() )
6170 const TopoDS_Shape aSubSh = anItr.Key();
6171 // check for case when concurrent dimensions are same
6172 isShared = theToFind.Contains( aSubSh );
6173 // check for sub-shape with concurrent dimension
6174 TopExp_Explorer anExp( aSubSh, theType );
6175 for ( ; !isShared && anExp.More(); anExp.Next() )
6176 isShared = theToFind.Contains( anExp.Current() );
6181 //-----------------------------------------------------------------------------
6182 //! check algorithms
6183 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6184 const SMESHDS_Hypothesis* theA2)
6186 if ( !theA1 || !theA2 ||
6187 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6188 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6189 return false; // one of the hypothesis is not algorithm
6190 // check algorithm names (should be equal)
6191 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6195 //-----------------------------------------------------------------------------
6196 //! Check if sub-shape hypotheses are concurrent
6197 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6199 if ( _subMesh == theOther->_subMesh )
6200 return false; // same sub-shape - should not be
6202 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6203 // any of the two submeshes is not on COMPOUND shape )
6204 // -> no concurrency
6205 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6206 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6207 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6208 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6209 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6212 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6213 if ( !checkSubShape )
6216 // check algorithms to be same
6217 const SMESH_Algo* a1 = this->GetAlgo();
6218 const SMESH_Algo* a2 = theOther->GetAlgo();
6219 bool isSame = checkAlgo( a1, a2 );
6223 return false; // pb?
6224 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6227 // check hypothesises for concurrence (skip first as algorithm)
6229 // pointers should be same, because it is referened from mesh hypothesis partition
6230 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6231 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6232 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6233 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6235 // the submeshes are concurrent if their algorithms has different parameters
6236 return nbSame != theOther->_hypotheses.size() - 1;
6239 // Return true if algorithm of this SMESH_DimHyp is used if no
6240 // sub-mesh order is imposed by the user
6241 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6243 // NeedDiscreteBoundary() algo has a higher priority
6244 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6245 theOther->GetAlgo()->NeedDiscreteBoundary() )
6246 return !this->GetAlgo()->NeedDiscreteBoundary();
6248 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6251 }; // end of SMESH_DimHyp
6252 //-----------------------------------------------------------------------------
6254 typedef list<const SMESH_DimHyp*> TDimHypList;
6256 //-----------------------------------------------------------------------------
6258 void addDimHypInstance(const int theDim,
6259 const TopoDS_Shape& theShape,
6260 const SMESH_Algo* theAlgo,
6261 const SMESH_subMesh* theSubMesh,
6262 const list <const SMESHDS_Hypothesis*>& theHypList,
6263 TDimHypList* theDimHypListArr )
6265 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6266 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6267 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6268 dimHyp->_hypotheses.push_front(theAlgo);
6269 listOfdimHyp.push_back( dimHyp );
6272 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6273 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6274 theHypList.begin(), theHypList.end() );
6277 //-----------------------------------------------------------------------------
6278 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6279 TDimHypList& theListOfConcurr)
6281 if ( theListOfConcurr.empty() )
6283 theListOfConcurr.push_back( theDimHyp );
6287 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6288 while ( hypIt != theListOfConcurr.end() &&
6289 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6291 theListOfConcurr.insert( hypIt, theDimHyp );
6295 //-----------------------------------------------------------------------------
6296 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6297 const TDimHypList& theListOfDimHyp,
6298 TDimHypList& theListOfConcurrHyp,
6299 set<int>& theSetOfConcurrId )
6301 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6302 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6304 const SMESH_DimHyp* curDimHyp = *rIt;
6305 if ( curDimHyp == theDimHyp )
6306 break; // meet own dimHyp pointer in same dimension
6308 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6309 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6311 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6316 //-----------------------------------------------------------------------------
6317 void unionLists(TListOfInt& theListOfId,
6318 TListOfListOfInt& theListOfListOfId,
6321 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6322 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6324 continue; //skip already treated lists
6325 // check if other list has any same submesh object
6326 TListOfInt& otherListOfId = *it;
6327 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6328 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6331 // union two lists (from source into target)
6332 TListOfInt::iterator it2 = otherListOfId.begin();
6333 for ( ; it2 != otherListOfId.end(); it2++ ) {
6334 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6335 theListOfId.push_back(*it2);
6337 // clear source list
6338 otherListOfId.clear();
6341 //-----------------------------------------------------------------------------
6343 //! free memory allocated for dimension-hypothesis objects
6344 void removeDimHyps( TDimHypList* theArrOfList )
6346 for (int i = 0; i < 4; i++ ) {
6347 TDimHypList& listOfdimHyp = theArrOfList[i];
6348 TDimHypList::const_iterator it = listOfdimHyp.begin();
6349 for ( ; it != listOfdimHyp.end(); it++ )
6354 //-----------------------------------------------------------------------------
6356 * \brief find common submeshes with given submesh
6357 * \param theSubMeshList list of already collected submesh to check
6358 * \param theSubMesh given submesh to intersect with other
6359 * \param theCommonSubMeshes collected common submeshes
6361 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6362 const SMESH_subMesh* theSubMesh,
6363 set<const SMESH_subMesh*>& theCommon )
6367 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6368 for ( ; it != theSubMeshList.end(); it++ )
6369 theSubMesh->FindIntersection( *it, theCommon );
6370 theSubMeshList.push_back( theSubMesh );
6371 //theCommon.insert( theSubMesh );
6374 //-----------------------------------------------------------------------------
6375 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6377 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6378 for ( ; listsIt != smLists.end(); ++listsIt )
6380 const TListOfInt& smIDs = *listsIt;
6381 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6389 //=============================================================================
6391 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6393 //=============================================================================
6395 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6397 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6398 if ( isSubMeshInList( submeshID, anOrder ))
6401 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6402 return isSubMeshInList( submeshID, allConurrent );
6405 //=============================================================================
6407 * \brief Return submesh objects list in meshing order
6409 //=============================================================================
6411 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6413 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6415 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6417 return aResult._retn();
6419 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6420 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6421 anOrder.splice( anOrder.end(), allConurrent );
6424 TListOfListOfInt::iterator listIt = anOrder.begin();
6425 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6426 unionLists( *listIt, anOrder, listIndx + 1 );
6428 // convert submesh ids into interface instances
6429 // and dump command into python
6430 convertMeshOrder( anOrder, aResult, false );
6432 return aResult._retn();
6435 //=============================================================================
6437 * \brief Finds concurrent sub-meshes
6439 //=============================================================================
6441 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6443 TListOfListOfInt anOrder;
6444 ::SMESH_Mesh& mesh = GetImpl();
6446 // collect submeshes and detect concurrent algorithms and hypothesises
6447 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6449 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6450 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6451 ::SMESH_subMesh* sm = (*i_sm).second;
6453 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6455 // list of assigned hypothesises
6456 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6457 // Find out dimensions where the submesh can be concurrent.
6458 // We define the dimensions by algo of each of hypotheses in hypList
6459 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6460 for( ; hypIt != hypList.end(); hypIt++ ) {
6461 SMESH_Algo* anAlgo = 0;
6462 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6463 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6464 // hyp it-self is algo
6465 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6467 // try to find algorithm with help of sub-shapes
6468 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6469 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6470 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6473 continue; // no algorithm assigned to a current submesh
6475 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6476 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6478 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6479 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6480 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6482 } // end iterations on submesh
6484 // iterate on created dimension-hypotheses and check for concurrents
6485 for ( int i = 0; i < 4; i++ ) {
6486 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6487 // check for concurrents in own and other dimensions (step-by-step)
6488 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6489 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6490 const SMESH_DimHyp* dimHyp = *dhIt;
6491 TDimHypList listOfConcurr;
6492 set<int> setOfConcurrIds;
6493 // looking for concurrents and collect into own list
6494 for ( int j = i; j < 4; j++ )
6495 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6496 // check if any concurrents found
6497 if ( listOfConcurr.size() > 0 ) {
6498 // add own submesh to list of concurrent
6499 addInOrderOfPriority( dimHyp, listOfConcurr );
6500 list<int> listOfConcurrIds;
6501 TDimHypList::iterator hypIt = listOfConcurr.begin();
6502 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6503 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6504 anOrder.push_back( listOfConcurrIds );
6509 removeDimHyps(dimHypListArr);
6511 // now, minimize the number of concurrent groups
6512 // Here we assume that lists of submeshes can have same submesh
6513 // in case of multi-dimension algorithms, as result
6514 // list with common submesh has to be united into one list
6516 TListOfListOfInt::iterator listIt = anOrder.begin();
6517 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6518 unionLists( *listIt, anOrder, listIndx + 1 );
6524 //=============================================================================
6526 * \brief Set submesh object order
6527 * \param theSubMeshArray submesh array order
6529 //=============================================================================
6531 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6534 _preMeshInfo->ForgetOrLoad();
6537 ::SMESH_Mesh& mesh = GetImpl();
6539 TPythonDump aPythonDump; // prevent dump of called methods
6540 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6542 TListOfListOfInt subMeshOrder;
6543 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6545 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6546 TListOfInt subMeshIds;
6548 aPythonDump << ", ";
6549 aPythonDump << "[ ";
6550 // Collect subMeshes which should be clear
6551 // do it list-by-list, because modification of submesh order
6552 // take effect between concurrent submeshes only
6553 set<const SMESH_subMesh*> subMeshToClear;
6554 list<const SMESH_subMesh*> subMeshList;
6555 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6557 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6559 aPythonDump << ", ";
6560 aPythonDump << subMesh;
6561 subMeshIds.push_back( subMesh->GetId() );
6562 // detect common parts of submeshes
6563 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6564 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6566 aPythonDump << " ]";
6567 subMeshOrder.push_back( subMeshIds );
6569 // clear collected sub-meshes
6570 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6571 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6572 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6574 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6575 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6576 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6579 aPythonDump << " ])";
6581 mesh.SetMeshOrder( subMeshOrder );
6584 SMESH::SMESH_Mesh_var me = _this();
6585 _gen_i->UpdateIcons( me );
6590 //=============================================================================
6592 * \brief Convert submesh ids into submesh interfaces
6594 //=============================================================================
6596 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6597 SMESH::submesh_array_array& theResOrder,
6598 const bool theIsDump)
6600 int nbSet = theIdsOrder.size();
6601 TPythonDump aPythonDump; // prevent dump of called methods
6603 aPythonDump << "[ ";
6604 theResOrder.length(nbSet);
6605 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6607 for( ; it != theIdsOrder.end(); it++ ) {
6608 // translate submesh identificators into submesh objects
6609 // takeing into account real number of concurrent lists
6610 const TListOfInt& aSubOrder = (*it);
6611 if (!aSubOrder.size())
6614 aPythonDump << "[ ";
6615 // convert shape indices into interfaces
6616 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6617 aResSubSet->length(aSubOrder.size());
6618 TListOfInt::const_iterator subIt = aSubOrder.begin();
6620 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6621 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6623 SMESH::SMESH_subMesh_var subMesh =
6624 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6627 aPythonDump << ", ";
6628 aPythonDump << subMesh;
6630 aResSubSet[ j++ ] = subMesh;
6633 aPythonDump << " ]";
6635 theResOrder[ listIndx++ ] = aResSubSet;
6637 // correct number of lists
6638 theResOrder.length( listIndx );
6641 // finilise python dump
6642 aPythonDump << " ]";
6643 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6647 namespace // utils used by SMESH_MeshPartDS
6650 * \brief Class used to access to protected data of SMDS_MeshInfo
6652 struct TMeshInfo : public SMDS_MeshInfo
6654 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6657 * \brief Element holing its ID only
6659 struct TElemID : public SMDS_LinearEdge
6661 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6665 //================================================================================
6667 // Implementation of SMESH_MeshPartDS
6669 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6670 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6672 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6673 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6676 _meshDS = mesh_i->GetImpl().GetMeshDS();
6678 SetPersistentId( _meshDS->GetPersistentId() );
6680 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6682 // <meshPart> is the whole mesh
6683 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6685 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6686 myGroupSet = _meshDS->GetGroups();
6691 SMESH::long_array_var anIDs = meshPart->GetIDs();
6692 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6693 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6695 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6696 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6697 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6702 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6703 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6704 if ( _elements[ e->GetType() ].insert( e ).second )
6707 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6708 while ( nIt->more() )
6710 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6711 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6718 ShapeToMesh( _meshDS->ShapeToMesh() );
6720 _meshDS = 0; // to enforce iteration on _elements and _nodes
6723 // -------------------------------------------------------------------------------------
6724 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6725 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6728 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6729 for ( ; partIt != meshPart.end(); ++partIt )
6730 if ( const SMDS_MeshElement * e = *partIt )
6731 if ( _elements[ e->GetType() ].insert( e ).second )
6734 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6735 while ( nIt->more() )
6737 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6738 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6744 // -------------------------------------------------------------------------------------
6745 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6747 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6749 TElemID elem( IDelem );
6750 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6751 if ( !_elements[ iType ].empty() )
6753 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6754 if ( it != _elements[ iType ].end() )
6759 // -------------------------------------------------------------------------------------
6760 bool SMESH_MeshPartDS::HasNumerationHoles()
6762 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6764 return ( MinNodeID() != 1 ||
6765 MaxNodeID() != NbNodes() ||
6766 MinElementID() != 1 ||
6767 MaxElementID() != NbElements() );
6769 // -------------------------------------------------------------------------------------
6770 int SMESH_MeshPartDS::MaxNodeID() const
6772 if ( _meshDS ) return _meshDS->MaxNodeID();
6773 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6775 // -------------------------------------------------------------------------------------
6776 int SMESH_MeshPartDS::MinNodeID() const
6778 if ( _meshDS ) return _meshDS->MinNodeID();
6779 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6781 // -------------------------------------------------------------------------------------
6782 int SMESH_MeshPartDS::MaxElementID() const
6784 if ( _meshDS ) return _meshDS->MaxElementID();
6786 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6787 if ( !_elements[ iType ].empty() )
6788 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6791 // -------------------------------------------------------------------------------------
6792 int SMESH_MeshPartDS::MinElementID() const
6794 if ( _meshDS ) return _meshDS->MinElementID();
6796 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6797 if ( !_elements[ iType ].empty() )
6798 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6801 // -------------------------------------------------------------------------------------
6802 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6804 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6806 typedef SMDS_SetIterator
6807 <const SMDS_MeshElement*,
6808 TIDSortedElemSet::const_iterator,
6809 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6810 SMDS_MeshElement::GeomFilter
6813 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6815 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6816 _elements[type].end(),
6817 SMDS_MeshElement::GeomFilter( geomType )));
6819 // -------------------------------------------------------------------------------------
6820 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6822 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6824 typedef SMDS_SetIterator
6825 <const SMDS_MeshElement*,
6826 TIDSortedElemSet::const_iterator,
6827 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6828 SMDS_MeshElement::EntityFilter
6831 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6833 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6834 _elements[type].end(),
6835 SMDS_MeshElement::EntityFilter( entity )));
6837 // -------------------------------------------------------------------------------------
6838 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6840 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6841 if ( type == SMDSAbs_All && !_meshDS )
6843 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6845 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6846 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6848 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6850 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6851 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6853 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6854 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6856 // -------------------------------------------------------------------------------------
6857 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6858 iterType SMESH_MeshPartDS::methName() const \
6860 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6861 return _meshDS ? _meshDS->methName() : iterType \
6862 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6864 // -------------------------------------------------------------------------------------
6865 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6866 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6867 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6868 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6869 #undef _GET_ITER_DEFINE
6871 // END Implementation of SMESH_MeshPartDS
6873 //================================================================================