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() ));
2476 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2477 if ( !meshSO->_is_nil() )
2478 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2482 //=============================================================================
2484 * \brief Update objects depending on changed geom groups
2486 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2487 * issue 0020210: Update of a smesh group after modification of the associated geom group
2489 //=============================================================================
2491 void SMESH_Mesh_i::CheckGeomGroupModif()
2493 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2494 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2495 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2496 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2497 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2499 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2500 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2501 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2503 int nbValid = 0, nbRemoved = 0;
2504 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2505 for ( ; chItr->More(); chItr->Next() )
2507 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2508 if ( !smSO->_is_nil() &&
2509 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2510 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2512 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2513 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2514 if ( !geom->_non_existent() )
2517 continue; // keep the sub-mesh
2520 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2521 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2522 if ( !sm->_is_nil() && !sm->_non_existent() )
2524 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2525 if ( smGeom->_is_nil() )
2527 RemoveSubMesh( sm );
2534 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2535 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2539 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2540 builder->RemoveObjectWithChildren( rootSO );
2544 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2545 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2546 while ( i_gr != _mapGroups.end())
2548 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2550 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2551 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2552 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2553 bool isValidGeom = false;
2554 if ( !onGeom->_is_nil() )
2556 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2558 else if ( !onFilt->_is_nil() )
2560 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2564 isValidGeom = ( !groupSO->_is_nil() &&
2565 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2569 if ( !IsLoaded() || group->IsEmpty() )
2571 RemoveGroup( group );
2573 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2575 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2577 else // is it possible?
2579 builder->RemoveObjectWithChildren( refSO );
2585 if ( !_impl->HasShapeToMesh() ) return;
2587 CORBA::Long nbEntities = NbNodes() + NbElements();
2589 // Check if group contents changed
2591 typedef map< string, TopoDS_Shape > TEntry2Geom;
2592 TEntry2Geom newGroupContents;
2594 list<TGeomGroupData>::iterator
2595 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2596 for ( ; data != dataEnd; ++data )
2598 pair< TEntry2Geom::iterator, bool > it_new =
2599 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2600 bool processedGroup = !it_new.second;
2601 TopoDS_Shape& newShape = it_new.first->second;
2602 if ( !processedGroup )
2603 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2604 if ( newShape.IsNull() )
2605 continue; // no changes
2608 _preMeshInfo->ForgetOrLoad();
2610 if ( processedGroup ) { // update group indices
2611 list<TGeomGroupData>::iterator data2 = data;
2612 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2613 data->_indices = data2->_indices;
2616 // Update SMESH objects according to new GEOM group contents
2618 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2619 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2621 int oldID = submesh->GetId();
2622 if ( !_mapSubMeshIor.count( oldID ))
2624 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2626 // update hypotheses
2627 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2628 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2629 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2631 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2632 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2634 // care of submeshes
2635 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2636 int newID = newSubmesh->GetId();
2637 if ( newID != oldID ) {
2638 _mapSubMesh [ newID ] = newSubmesh;
2639 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2640 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2641 _mapSubMesh. erase(oldID);
2642 _mapSubMesh_i. erase(oldID);
2643 _mapSubMeshIor.erase(oldID);
2644 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2649 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2650 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2651 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2653 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2655 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2656 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2657 ds->SetShape( newShape );
2662 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2663 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2665 // Remove groups and submeshes basing on removed sub-shapes
2667 TopTools_MapOfShape newShapeMap;
2668 TopoDS_Iterator shapeIt( newShape );
2669 for ( ; shapeIt.More(); shapeIt.Next() )
2670 newShapeMap.Add( shapeIt.Value() );
2672 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2673 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2675 if ( newShapeMap.Contains( shapeIt.Value() ))
2677 TopTools_IndexedMapOfShape oldShapeMap;
2678 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2679 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2681 const TopoDS_Shape& oldShape = oldShapeMap(i);
2682 int oldInd = meshDS->ShapeToIndex( oldShape );
2684 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2685 if ( i_smIor != _mapSubMeshIor.end() ) {
2686 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2689 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2690 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2692 // check if a group bases on oldInd shape
2693 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2694 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2695 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2696 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2698 RemoveGroup( i_grp->second ); // several groups can base on same shape
2699 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2704 // Reassign hypotheses and update groups after setting the new shape to mesh
2706 // collect anassigned hypotheses
2707 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2708 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2709 TShapeHypList assignedHyps;
2710 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2712 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2713 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2714 if ( !hyps.empty() ) {
2715 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2716 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2717 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2720 // collect shapes supporting groups
2721 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2722 TShapeTypeList groupData;
2723 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2724 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2725 for ( ; grIt != groups.end(); ++grIt )
2727 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2729 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2731 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2733 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2734 _impl->ShapeToMesh( newShape );
2736 // reassign hypotheses
2737 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2738 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2740 TIndexedShape& geom = indS_hyps->first;
2741 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2742 int oldID = geom._index;
2743 int newID = meshDS->ShapeToIndex( geom._shape );
2744 if ( oldID == 1 ) { // main shape
2746 geom._shape = newShape;
2750 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2751 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2752 // care of sub-meshes
2753 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2754 if ( newID != oldID ) {
2755 _mapSubMesh [ newID ] = newSubmesh;
2756 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2757 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2758 _mapSubMesh. erase(oldID);
2759 _mapSubMesh_i. erase(oldID);
2760 _mapSubMeshIor.erase(oldID);
2761 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2765 TShapeTypeList::iterator geomType = groupData.begin();
2766 for ( ; geomType != groupData.end(); ++geomType )
2768 const TIndexedShape& geom = geomType->first;
2769 int oldID = geom._index;
2770 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2773 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2774 CORBA::String_var name = groupSO->GetName();
2776 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2777 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2778 /*id=*/-1, geom._shape ))
2779 group_i->changeLocalId( group->GetID() );
2782 break; // everything has been updated
2785 } // loop on group data
2789 CORBA::Long newNbEntities = NbNodes() + NbElements();
2790 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2791 if ( newNbEntities != nbEntities )
2793 // Add all SObjects with icons to soToUpdateIcons
2794 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2796 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2797 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2798 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2800 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2801 i_gr != _mapGroups.end(); ++i_gr ) // groups
2802 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2805 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2806 for ( ; so != soToUpdateIcons.end(); ++so )
2807 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2810 //=============================================================================
2812 * \brief Create standalone group from a group on geometry or filter
2814 //=============================================================================
2816 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2817 throw (SALOME::SALOME_Exception)
2819 SMESH::SMESH_Group_var aGroup;
2824 _preMeshInfo->FullLoadFromFile();
2826 if ( theGroup->_is_nil() )
2827 return aGroup._retn();
2829 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2831 return aGroup._retn();
2833 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2835 const int anId = aGroupToRem->GetLocalID();
2836 if ( !_impl->ConvertToStandalone( anId ) )
2837 return aGroup._retn();
2838 removeGeomGroupData( theGroup );
2840 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2842 // remove old instance of group from own map
2843 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2844 _mapGroups.erase( anId );
2846 SALOMEDS::StudyBuilder_var builder;
2847 SALOMEDS::SObject_wrap aGroupSO;
2848 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2849 if ( !aStudy->_is_nil() ) {
2850 builder = aStudy->NewBuilder();
2851 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2852 if ( !aGroupSO->_is_nil() )
2854 // remove reference to geometry
2855 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2856 for ( ; chItr->More(); chItr->Next() )
2858 // Remove group's child SObject
2859 SALOMEDS::SObject_wrap so = chItr->Value();
2860 builder->RemoveObject( so );
2862 // Update Python script
2863 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2864 << ".ConvertToStandalone( " << aGroupSO << " )";
2866 // change icon of Group on Filter
2869 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2870 // const int isEmpty = ( elemTypes->length() == 0 );
2873 SALOMEDS::GenericAttribute_wrap anAttr =
2874 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2875 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2876 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2882 // remember new group in own map
2883 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2884 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2886 // register CORBA object for persistence
2887 _gen_i->RegisterObject( aGroup );
2889 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2890 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2891 //aGroup->Register();
2892 aGroupToRem->UnRegister();
2894 SMESH_CATCH( SMESH::throwCorbaException );
2896 return aGroup._retn();
2899 //=============================================================================
2903 //=============================================================================
2905 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2907 if(MYDEBUG) MESSAGE( "createSubMesh" );
2908 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2909 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2912 SMESH_subMesh_i * subMeshServant;
2915 subMeshId = mySubMesh->GetId();
2916 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2918 else // "invalid sub-mesh"
2920 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2921 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2922 if ( _mapSubMesh.empty() )
2925 subMeshId = _mapSubMesh.begin()->first - 1;
2926 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2929 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2931 _mapSubMesh [subMeshId] = mySubMesh;
2932 _mapSubMesh_i [subMeshId] = subMeshServant;
2933 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2935 subMeshServant->Register();
2937 // register CORBA object for persistence
2938 int nextId = _gen_i->RegisterObject( subMesh );
2939 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2940 else { nextId = 0; } // avoid "unused variable" warning
2942 // to track changes of GEOM groups
2943 if ( subMeshId > 0 )
2944 addGeomGroupData( theSubShapeObject, subMesh );
2946 return subMesh._retn();
2949 //=======================================================================
2950 //function : getSubMesh
2952 //=======================================================================
2954 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2956 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2957 if ( it == _mapSubMeshIor.end() )
2958 return SMESH::SMESH_subMesh::_nil();
2960 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2963 //=============================================================================
2967 //=============================================================================
2969 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2970 GEOM::GEOM_Object_ptr theSubShapeObject )
2972 bool isHypChanged = false;
2973 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2974 return isHypChanged;
2976 const int subMeshId = theSubMesh->GetId();
2978 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2981 if (( _mapSubMesh.count( subMeshId )) &&
2982 ( sm = _impl->GetSubMeshContaining( subMeshId )))
2984 TopoDS_Shape S = sm->GetSubShape();
2987 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2988 isHypChanged = !hyps.empty();
2989 if ( isHypChanged && _preMeshInfo )
2990 _preMeshInfo->ForgetOrLoad();
2991 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2992 for ( ; hyp != hyps.end(); ++hyp )
2993 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3000 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3001 isHypChanged = ( aHypList->length() > 0 );
3002 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3003 removeHypothesis( theSubShapeObject, aHypList[i] );
3006 catch( const SALOME::SALOME_Exception& ) {
3007 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3009 removeGeomGroupData( theSubShapeObject );
3013 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3014 if ( id_smi != _mapSubMesh_i.end() )
3015 id_smi->second->UnRegister();
3017 // remove a CORBA object
3018 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3019 if ( id_smptr != _mapSubMeshIor.end() )
3020 SMESH::SMESH_subMesh_var( id_smptr->second );
3022 _mapSubMesh.erase(subMeshId);
3023 _mapSubMesh_i.erase(subMeshId);
3024 _mapSubMeshIor.erase(subMeshId);
3026 return isHypChanged;
3029 //=============================================================================
3033 //=============================================================================
3035 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3036 const char* theName,
3038 const TopoDS_Shape& theShape,
3039 const SMESH_PredicatePtr& thePredicate )
3041 std::string newName;
3042 if ( !theName || !theName[0] )
3044 std::set< std::string > presentNames;
3045 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3046 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3048 CORBA::String_var name = i_gr->second->GetName();
3049 presentNames.insert( name.in() );
3052 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3053 } while ( !presentNames.insert( newName ).second );
3054 theName = newName.c_str();
3056 SMESH::SMESH_GroupBase_var aGroup;
3057 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3058 theID, theShape, thePredicate ))
3060 int anId = g->GetID();
3061 SMESH_GroupBase_i* aGroupImpl;
3062 if ( !theShape.IsNull() )
3063 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3064 else if ( thePredicate )
3065 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3067 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3069 aGroup = aGroupImpl->_this();
3070 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3071 aGroupImpl->Register();
3073 // register CORBA object for persistence
3074 int nextId = _gen_i->RegisterObject( aGroup );
3075 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3076 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3078 // to track changes of GEOM groups
3079 if ( !theShape.IsNull() ) {
3080 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3081 addGeomGroupData( geom, aGroup );
3084 return aGroup._retn();
3087 //=============================================================================
3089 * SMESH_Mesh_i::removeGroup
3091 * Should be called by ~SMESH_Group_i()
3093 //=============================================================================
3095 void SMESH_Mesh_i::removeGroup( const int theId )
3097 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3098 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3099 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3100 _mapGroups.erase( theId );
3101 removeGeomGroupData( group );
3102 if ( !_impl->RemoveGroup( theId ))
3104 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3105 RemoveGroup( group );
3107 group->UnRegister();
3111 //=============================================================================
3115 //=============================================================================
3117 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3118 throw(SALOME::SALOME_Exception)
3120 SMESH::log_array_var aLog;
3124 _preMeshInfo->FullLoadFromFile();
3126 list < SMESHDS_Command * >logDS = _impl->GetLog();
3127 aLog = new SMESH::log_array;
3129 int lg = logDS.size();
3132 list < SMESHDS_Command * >::iterator its = logDS.begin();
3133 while(its != logDS.end()){
3134 SMESHDS_Command *com = *its;
3135 int comType = com->GetType();
3137 int lgcom = com->GetNumber();
3139 const list < int >&intList = com->GetIndexes();
3140 int inum = intList.size();
3142 list < int >::const_iterator ii = intList.begin();
3143 const list < double >&coordList = com->GetCoords();
3144 int rnum = coordList.size();
3146 list < double >::const_iterator ir = coordList.begin();
3147 aLog[indexLog].commandType = comType;
3148 aLog[indexLog].number = lgcom;
3149 aLog[indexLog].coords.length(rnum);
3150 aLog[indexLog].indexes.length(inum);
3151 for(int i = 0; i < rnum; i++){
3152 aLog[indexLog].coords[i] = *ir;
3153 //MESSAGE(" "<<i<<" "<<ir.Value());
3156 for(int i = 0; i < inum; i++){
3157 aLog[indexLog].indexes[i] = *ii;
3158 //MESSAGE(" "<<i<<" "<<ii.Value());
3167 SMESH_CATCH( SMESH::throwCorbaException );
3169 return aLog._retn();
3173 //=============================================================================
3177 //=============================================================================
3179 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3183 SMESH_CATCH( SMESH::throwCorbaException );
3186 //=============================================================================
3190 //=============================================================================
3192 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3197 //=============================================================================
3200 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3201 // issue 0020918: groups removal is caused by hyp modification
3202 // issue 0021208: to forget not loaded mesh data at hyp modification
3203 struct TCallUp_i : public SMESH_Mesh::TCallUp
3205 SMESH_Mesh_i* _mesh;
3206 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3207 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3208 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
3209 virtual void Load () { _mesh->Load(); }
3213 //================================================================================
3215 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
3217 //================================================================================
3219 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
3222 _preMeshInfo->ForgetOrLoad();
3224 SMESH::SMESH_Mesh_var mesh = _this();
3225 _gen_i->UpdateIcons( mesh );
3227 // mark a hypothesis as valid after edition
3228 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3229 SALOMEDS::SObject_wrap hypRoot;
3230 if ( !smeshComp->_is_nil() &&
3231 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3233 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3234 for ( ; anIter->More(); anIter->Next() )
3236 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3237 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3238 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3239 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3240 _gen_i->HighLightInvalid( hyp, false );
3245 //=============================================================================
3249 //=============================================================================
3251 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3253 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3256 _impl->SetCallUp( new TCallUp_i(this));
3259 //=============================================================================
3263 //=============================================================================
3265 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3267 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3271 //=============================================================================
3273 * Return mesh editor
3275 //=============================================================================
3277 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3278 throw (SALOME::SALOME_Exception)
3280 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3284 _preMeshInfo->FullLoadFromFile();
3286 // Create MeshEditor
3288 _editor = new SMESH_MeshEditor_i( this, false );
3289 aMeshEdVar = _editor->_this();
3291 // Update Python script
3292 TPythonDump() << _editor << " = "
3293 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3295 SMESH_CATCH( SMESH::throwCorbaException );
3297 return aMeshEdVar._retn();
3300 //=============================================================================
3302 * Return mesh edition previewer
3304 //=============================================================================
3306 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3307 throw (SALOME::SALOME_Exception)
3309 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3313 _preMeshInfo->FullLoadFromFile();
3315 if ( !_previewEditor )
3316 _previewEditor = new SMESH_MeshEditor_i( this, true );
3317 aMeshEdVar = _previewEditor->_this();
3319 SMESH_CATCH( SMESH::throwCorbaException );
3321 return aMeshEdVar._retn();
3324 //================================================================================
3326 * \brief Return true if the mesh has been edited since a last total re-compute
3327 * and those modifications may prevent successful partial re-compute
3329 //================================================================================
3331 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3333 Unexpect aCatch(SALOME_SalomeException);
3334 return _impl->HasModificationsToDiscard();
3337 //================================================================================
3339 * \brief Returns a random unique color
3341 //================================================================================
3343 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3345 const int MAX_ATTEMPTS = 100;
3347 double tolerance = 0.5;
3348 SALOMEDS::Color col;
3352 // generate random color
3353 double red = (double)rand() / RAND_MAX;
3354 double green = (double)rand() / RAND_MAX;
3355 double blue = (double)rand() / RAND_MAX;
3356 // check existence in the list of the existing colors
3357 bool matched = false;
3358 std::list<SALOMEDS::Color>::const_iterator it;
3359 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3360 SALOMEDS::Color color = *it;
3361 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3362 matched = tol < tolerance;
3364 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3365 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3373 //=============================================================================
3375 * Sets auto-color mode. If it is on, groups get unique random colors
3377 //=============================================================================
3379 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3381 Unexpect aCatch(SALOME_SalomeException);
3382 _impl->SetAutoColor(theAutoColor);
3384 TPythonDump pyDump; // not to dump group->SetColor() from below code
3385 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3387 std::list<SALOMEDS::Color> aReservedColors;
3388 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3389 for ( ; it != _mapGroups.end(); it++ ) {
3390 if ( CORBA::is_nil( it->second )) continue;
3391 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3392 it->second->SetColor( aColor );
3393 aReservedColors.push_back( aColor );
3397 //=============================================================================
3399 * Returns true if auto-color mode is on
3401 //=============================================================================
3403 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3405 Unexpect aCatch(SALOME_SalomeException);
3406 return _impl->GetAutoColor();
3409 //=============================================================================
3411 * Checks if there are groups with equal names
3413 //=============================================================================
3415 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3417 return _impl->HasDuplicatedGroupNamesMED();
3420 //================================================================================
3422 * \brief Care of a file before exporting mesh into it
3424 //================================================================================
3426 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3428 SMESH_File aFile( file, false );
3430 if ( aFile.exists() ) {
3431 // existing filesystem node
3432 if ( !aFile.isDirectory() ) {
3433 if ( aFile.openForWriting() ) {
3434 if ( overwrite && ! aFile.remove()) {
3435 msg << "Can't replace " << aFile.getName();
3438 msg << "Can't write into " << aFile.getName();
3441 msg << "Location " << aFile.getName() << " is not a file";
3445 // nonexisting file; check if it can be created
3446 if ( !aFile.openForWriting() ) {
3447 msg << "You cannot create the file "
3449 << ". Check the directory existence and access rights";
3457 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3461 //================================================================================
3463 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3464 * \param file - file name
3465 * \param overwrite - to erase the file or not
3466 * \retval string - mesh name
3468 //================================================================================
3470 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3471 CORBA::Boolean overwrite)
3474 PrepareForWriting(file, overwrite);
3475 string aMeshName = "Mesh";
3476 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3477 if ( !aStudy->_is_nil() ) {
3478 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3479 if ( !aMeshSO->_is_nil() ) {
3480 CORBA::String_var name = aMeshSO->GetName();
3482 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3483 if ( !aStudy->GetProperties()->IsLocked() )
3485 SALOMEDS::GenericAttribute_wrap anAttr;
3486 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3487 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3488 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3489 ASSERT(!aFileName->_is_nil());
3490 aFileName->SetValue(file);
3491 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3492 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3493 ASSERT(!aFileType->_is_nil());
3494 aFileType->SetValue("FICHIERMED");
3498 // Update Python script
3499 // set name of mesh before export
3500 TPythonDump() << _gen_i << ".SetName("
3501 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3503 // check names of groups
3509 //================================================================================
3511 * \brief Export to MED file
3513 //================================================================================
3515 void SMESH_Mesh_i::ExportMED(const char* file,
3516 CORBA::Boolean auto_groups,
3517 CORBA::Long version,
3518 CORBA::Boolean overwrite,
3519 CORBA::Boolean autoDimension)
3520 throw(SALOME::SALOME_Exception)
3522 //MESSAGE("MED minor version: "<< minor);
3525 _preMeshInfo->FullLoadFromFile();
3527 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3528 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3530 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3532 << "auto_groups=" <<auto_groups << ", "
3533 << "minor=" << version << ", "
3534 << "overwrite=" << overwrite << ", "
3535 << "meshPart=None, "
3536 << "autoDimension=" << autoDimension << " )";
3538 SMESH_CATCH( SMESH::throwCorbaException );
3541 //================================================================================
3543 * \brief Export a mesh to a SAUV file
3545 //================================================================================
3547 void SMESH_Mesh_i::ExportSAUV (const char* file,
3548 CORBA::Boolean auto_groups)
3549 throw(SALOME::SALOME_Exception)
3551 Unexpect aCatch(SALOME_SalomeException);
3553 _preMeshInfo->FullLoadFromFile();
3555 string aMeshName = prepareMeshNameAndGroups(file, true);
3556 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3557 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3558 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3562 //================================================================================
3564 * \brief Export a mesh to a DAT file
3566 //================================================================================
3568 void SMESH_Mesh_i::ExportDAT (const char *file)
3569 throw(SALOME::SALOME_Exception)
3571 Unexpect aCatch(SALOME_SalomeException);
3573 _preMeshInfo->FullLoadFromFile();
3575 // Update Python script
3576 // check names of groups
3578 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3581 PrepareForWriting(file);
3582 _impl->ExportDAT(file);
3585 //================================================================================
3587 * \brief Export a mesh to an UNV file
3589 //================================================================================
3591 void SMESH_Mesh_i::ExportUNV (const char *file)
3592 throw(SALOME::SALOME_Exception)
3594 Unexpect aCatch(SALOME_SalomeException);
3596 _preMeshInfo->FullLoadFromFile();
3598 // Update Python script
3599 // check names of groups
3601 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3604 PrepareForWriting(file);
3605 _impl->ExportUNV(file);
3608 //================================================================================
3610 * \brief Export a mesh to an STL file
3612 //================================================================================
3614 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3615 throw(SALOME::SALOME_Exception)
3617 Unexpect aCatch(SALOME_SalomeException);
3619 _preMeshInfo->FullLoadFromFile();
3621 // Update Python script
3622 // check names of groups
3624 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3625 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3627 CORBA::String_var name;
3628 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3629 if ( !so->_is_nil() )
3630 name = so->GetName();
3633 PrepareForWriting( file );
3634 _impl->ExportSTL( file, isascii, name.in() );
3637 //================================================================================
3639 * \brief Export a part of mesh to a med file
3641 //================================================================================
3643 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3645 CORBA::Boolean auto_groups,
3646 CORBA::Long version,
3647 CORBA::Boolean overwrite,
3648 CORBA::Boolean autoDimension,
3649 const GEOM::ListOfFields& fields,
3650 const char* geomAssocFields,
3651 CORBA::Double ZTolerance)
3652 throw (SALOME::SALOME_Exception)
3654 MESSAGE("MED version: "<< version);
3657 _preMeshInfo->FullLoadFromFile();
3660 bool have0dField = false;
3661 if ( fields.length() > 0 )
3663 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3664 if ( shapeToMesh->_is_nil() )
3665 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3667 for ( size_t i = 0; i < fields.length(); ++i )
3669 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3670 THROW_SALOME_CORBA_EXCEPTION
3671 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3672 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3673 if ( fieldShape->_is_nil() )
3674 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3675 if ( !fieldShape->IsSame( shapeToMesh ) )
3676 THROW_SALOME_CORBA_EXCEPTION
3677 ( "Field defined not on shape", SALOME::BAD_PARAM);
3678 if ( fields[i]->GetDimension() == 0 )
3681 if ( geomAssocFields )
3682 for ( int i = 0; geomAssocFields[i]; ++i )
3683 switch ( geomAssocFields[i] ) {
3684 case 'v':case 'e':case 'f':case 's': break;
3685 case 'V':case 'E':case 'F':case 'S': break;
3686 default: THROW_SALOME_CORBA_EXCEPTION
3687 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3691 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3695 string aMeshName = "Mesh";
3696 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3697 if ( CORBA::is_nil( meshPart ) ||
3698 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3700 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3701 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3702 0, autoDimension, /*addODOnVertices=*/have0dField,
3704 meshDS = _impl->GetMeshDS();
3709 _preMeshInfo->FullLoadFromFile();
3711 PrepareForWriting(file, overwrite);
3713 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3714 if ( !SO->_is_nil() ) {
3715 CORBA::String_var name = SO->GetName();
3719 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3720 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3721 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3722 meshDS = tmpDSDeleter._obj = partDS;
3727 if ( _impl->HasShapeToMesh() )
3729 DriverMED_W_Field fieldWriter;
3730 fieldWriter.SetFile( file );
3731 fieldWriter.SetMeshName( aMeshName );
3732 fieldWriter.AddODOnVertices( have0dField );
3734 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3738 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3739 goList->length( fields.length() );
3740 for ( size_t i = 0; i < fields.length(); ++i )
3742 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3745 TPythonDump() << _this() << ".ExportPartToMED( "
3746 << meshPart << ", r'"
3748 << auto_groups << ", "
3750 << overwrite << ", "
3751 << autoDimension << ", "
3753 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3754 << TVar( ZTolerance )
3757 SMESH_CATCH( SMESH::throwCorbaException );
3760 //================================================================================
3762 * Write GEOM fields to MED file
3764 //================================================================================
3766 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3767 SMESHDS_Mesh* meshDS,
3768 const GEOM::ListOfFields& fields,
3769 const char* geomAssocFields)
3771 #define METH "SMESH_Mesh_i::exportMEDFields() "
3773 if (( fields.length() < 1 ) &&
3774 ( !geomAssocFields || !geomAssocFields[0] ))
3777 std::vector< std::vector< double > > dblVals;
3778 std::vector< std::vector< int > > intVals;
3779 std::vector< int > subIdsByDim[ 4 ];
3780 const double noneDblValue = 0.;
3781 const double noneIntValue = 0;
3783 for ( size_t iF = 0; iF < fields.length(); ++iF )
3787 int dim = fields[ iF ]->GetDimension();
3788 SMDSAbs_ElementType elemType;
3789 TopAbs_ShapeEnum shapeType;
3791 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3792 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3793 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3794 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3796 continue; // skip fields on whole shape
3798 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3799 if ( dataType == GEOM::FDT_String )
3801 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3802 if ( stepIDs->length() < 1 )
3804 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3805 if ( comps->length() < 1 )
3807 CORBA::String_var name = fields[ iF ]->GetName();
3809 if ( !fieldWriter.Set( meshDS,
3813 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3816 for ( size_t iC = 0; iC < comps->length(); ++iC )
3817 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3819 dblVals.resize( comps->length() );
3820 intVals.resize( comps->length() );
3822 // find sub-shape IDs
3824 std::vector< int >& subIds = subIdsByDim[ dim ];
3825 if ( subIds.empty() )
3826 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3827 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3828 subIds.push_back( id );
3832 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3836 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3838 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3839 if ( step->_is_nil() )
3842 CORBA::Long stamp = step->GetStamp();
3843 CORBA::Long id = step->GetID();
3844 fieldWriter.SetDtIt( int( stamp ), int( id ));
3846 // fill dblVals or intVals
3847 for ( size_t iC = 0; iC < comps->length(); ++iC )
3848 if ( dataType == GEOM::FDT_Double )
3850 dblVals[ iC ].clear();
3851 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3855 intVals[ iC ].clear();
3856 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3860 case GEOM::FDT_Double:
3862 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3863 if ( dblStep->_is_nil() ) continue;
3864 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3865 if ( vv->length() != subIds.size() * comps->length() )
3866 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3867 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3868 for ( size_t iC = 0; iC < comps->length(); ++iC )
3869 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3874 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3875 if ( intStep->_is_nil() ) continue;
3876 GEOM::ListOfLong_var vv = intStep->GetValues();
3877 if ( vv->length() != subIds.size() * comps->length() )
3878 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3879 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3880 for ( size_t iC = 0; iC < comps->length(); ++iC )
3881 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3884 case GEOM::FDT_Bool:
3886 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3887 if ( boolStep->_is_nil() ) continue;
3888 GEOM::short_array_var vv = boolStep->GetValues();
3889 if ( vv->length() != subIds.size() * comps->length() )
3890 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3891 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3892 for ( size_t iC = 0; iC < comps->length(); ++iC )
3893 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3899 // pass values to fieldWriter
3900 elemIt = fieldWriter.GetOrderedElems();
3901 if ( dataType == GEOM::FDT_Double )
3902 while ( elemIt->more() )
3904 const SMDS_MeshElement* e = elemIt->next();
3905 const int shapeID = e->getshapeId();
3906 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3907 for ( size_t iC = 0; iC < comps->length(); ++iC )
3908 fieldWriter.AddValue( noneDblValue );
3910 for ( size_t iC = 0; iC < comps->length(); ++iC )
3911 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3914 while ( elemIt->more() )
3916 const SMDS_MeshElement* e = elemIt->next();
3917 const int shapeID = e->getshapeId();
3918 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3919 for ( size_t iC = 0; iC < comps->length(); ++iC )
3920 fieldWriter.AddValue( (double) noneIntValue );
3922 for ( size_t iC = 0; iC < comps->length(); ++iC )
3923 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3927 fieldWriter.Perform();
3928 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3929 if ( res && res->IsKO() )
3931 if ( res->myComment.empty() )
3932 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3934 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3940 if ( !geomAssocFields || !geomAssocFields[0] )
3943 // write geomAssocFields
3945 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3946 shapeDim[ TopAbs_COMPOUND ] = 3;
3947 shapeDim[ TopAbs_COMPSOLID ] = 3;
3948 shapeDim[ TopAbs_SOLID ] = 3;
3949 shapeDim[ TopAbs_SHELL ] = 2;
3950 shapeDim[ TopAbs_FACE ] = 2;
3951 shapeDim[ TopAbs_WIRE ] = 1;
3952 shapeDim[ TopAbs_EDGE ] = 1;
3953 shapeDim[ TopAbs_VERTEX ] = 0;
3954 shapeDim[ TopAbs_SHAPE ] = 3;
3956 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3958 std::vector< std::string > compNames;
3959 switch ( geomAssocFields[ iF ]) {
3961 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3962 compNames.push_back( "dim" );
3965 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3968 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3971 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3975 compNames.push_back( "id" );
3976 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3977 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3979 fieldWriter.SetDtIt( -1, -1 );
3981 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3985 if ( compNames.size() == 2 ) // _vertices_
3986 while ( elemIt->more() )
3988 const SMDS_MeshElement* e = elemIt->next();
3989 const int shapeID = e->getshapeId();
3992 fieldWriter.AddValue( (double) -1 );
3993 fieldWriter.AddValue( (double) -1 );
3997 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3998 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3999 fieldWriter.AddValue( (double) shapeID );
4003 while ( elemIt->more() )
4005 const SMDS_MeshElement* e = elemIt->next();
4006 const int shapeID = e->getshapeId();
4008 fieldWriter.AddValue( (double) -1 );
4010 fieldWriter.AddValue( (double) shapeID );
4014 fieldWriter.Perform();
4015 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4016 if ( res && res->IsKO() )
4018 if ( res->myComment.empty() )
4019 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4021 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4024 } // loop on geomAssocFields
4029 //================================================================================
4031 * \brief Export a part of mesh to a DAT file
4033 //================================================================================
4035 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4037 throw (SALOME::SALOME_Exception)
4039 Unexpect aCatch(SALOME_SalomeException);
4041 _preMeshInfo->FullLoadFromFile();
4043 PrepareForWriting(file);
4045 SMESH_MeshPartDS partDS( meshPart );
4046 _impl->ExportDAT(file,&partDS);
4048 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4049 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4051 //================================================================================
4053 * \brief Export a part of mesh to an UNV file
4055 //================================================================================
4057 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4059 throw (SALOME::SALOME_Exception)
4061 Unexpect aCatch(SALOME_SalomeException);
4063 _preMeshInfo->FullLoadFromFile();
4065 PrepareForWriting(file);
4067 SMESH_MeshPartDS partDS( meshPart );
4068 _impl->ExportUNV(file, &partDS);
4070 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4071 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4073 //================================================================================
4075 * \brief Export a part of mesh to an STL file
4077 //================================================================================
4079 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4081 ::CORBA::Boolean isascii)
4082 throw (SALOME::SALOME_Exception)
4084 Unexpect aCatch(SALOME_SalomeException);
4086 _preMeshInfo->FullLoadFromFile();
4088 PrepareForWriting(file);
4090 CORBA::String_var name;
4091 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4092 if ( !so->_is_nil() )
4093 name = so->GetName();
4095 SMESH_MeshPartDS partDS( meshPart );
4096 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4098 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4099 << meshPart<< ", r'" << file << "', " << isascii << ")";
4102 //================================================================================
4104 * \brief Export a part of mesh to an STL file
4106 //================================================================================
4108 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4110 CORBA::Boolean overwrite,
4111 CORBA::Boolean groupElemsByType)
4112 throw (SALOME::SALOME_Exception)
4115 Unexpect aCatch(SALOME_SalomeException);
4117 _preMeshInfo->FullLoadFromFile();
4119 PrepareForWriting(file,overwrite);
4121 std::string meshName("");
4122 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4123 if ( !so->_is_nil() )
4125 CORBA::String_var name = so->GetName();
4126 meshName = name.in();
4130 SMESH_MeshPartDS partDS( meshPart );
4131 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4133 SMESH_CATCH( SMESH::throwCorbaException );
4135 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4136 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4138 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4142 //================================================================================
4144 * \brief Export a part of mesh to a GMF file
4146 //================================================================================
4148 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4150 bool withRequiredGroups)
4151 throw (SALOME::SALOME_Exception)
4153 Unexpect aCatch(SALOME_SalomeException);
4155 _preMeshInfo->FullLoadFromFile();
4157 PrepareForWriting(file,/*overwrite=*/true);
4159 SMESH_MeshPartDS partDS( meshPart );
4160 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4162 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4163 << meshPart<< ", r'"
4165 << withRequiredGroups << ")";
4168 //=============================================================================
4170 * Return computation progress [0.,1]
4172 //=============================================================================
4174 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4178 return _impl->GetComputeProgress();
4180 SMESH_CATCH( SMESH::doNothing );
4184 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4186 Unexpect aCatch(SALOME_SalomeException);
4188 return _preMeshInfo->NbNodes();
4190 return _impl->NbNodes();
4193 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4195 Unexpect aCatch(SALOME_SalomeException);
4197 return _preMeshInfo->NbElements();
4199 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4202 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4204 Unexpect aCatch(SALOME_SalomeException);
4206 return _preMeshInfo->Nb0DElements();
4208 return _impl->Nb0DElements();
4211 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4213 Unexpect aCatch(SALOME_SalomeException);
4215 return _preMeshInfo->NbBalls();
4217 return _impl->NbBalls();
4220 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4222 Unexpect aCatch(SALOME_SalomeException);
4224 return _preMeshInfo->NbEdges();
4226 return _impl->NbEdges();
4229 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4230 throw(SALOME::SALOME_Exception)
4232 Unexpect aCatch(SALOME_SalomeException);
4234 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4236 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4239 //=============================================================================
4241 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4243 Unexpect aCatch(SALOME_SalomeException);
4245 return _preMeshInfo->NbFaces();
4247 return _impl->NbFaces();
4250 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4252 Unexpect aCatch(SALOME_SalomeException);
4254 return _preMeshInfo->NbTriangles();
4256 return _impl->NbTriangles();
4259 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4261 Unexpect aCatch(SALOME_SalomeException);
4263 return _preMeshInfo->NbBiQuadTriangles();
4265 return _impl->NbBiQuadTriangles();
4268 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4270 Unexpect aCatch(SALOME_SalomeException);
4272 return _preMeshInfo->NbQuadrangles();
4274 return _impl->NbQuadrangles();
4277 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4279 Unexpect aCatch(SALOME_SalomeException);
4281 return _preMeshInfo->NbBiQuadQuadrangles();
4283 return _impl->NbBiQuadQuadrangles();
4286 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4288 Unexpect aCatch(SALOME_SalomeException);
4290 return _preMeshInfo->NbPolygons();
4292 return _impl->NbPolygons();
4295 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4297 Unexpect aCatch(SALOME_SalomeException);
4299 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4301 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4304 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4305 throw(SALOME::SALOME_Exception)
4307 Unexpect aCatch(SALOME_SalomeException);
4309 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4311 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4314 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4315 throw(SALOME::SALOME_Exception)
4317 Unexpect aCatch(SALOME_SalomeException);
4319 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4321 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4324 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4325 throw(SALOME::SALOME_Exception)
4327 Unexpect aCatch(SALOME_SalomeException);
4329 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4331 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4334 //=============================================================================
4336 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4338 Unexpect aCatch(SALOME_SalomeException);
4340 return _preMeshInfo->NbVolumes();
4342 return _impl->NbVolumes();
4345 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4347 Unexpect aCatch(SALOME_SalomeException);
4349 return _preMeshInfo->NbTetras();
4351 return _impl->NbTetras();
4354 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4356 Unexpect aCatch(SALOME_SalomeException);
4358 return _preMeshInfo->NbHexas();
4360 return _impl->NbHexas();
4363 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4365 Unexpect aCatch(SALOME_SalomeException);
4367 return _preMeshInfo->NbTriQuadHexas();
4369 return _impl->NbTriQuadraticHexas();
4372 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4374 Unexpect aCatch(SALOME_SalomeException);
4376 return _preMeshInfo->NbPyramids();
4378 return _impl->NbPyramids();
4381 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4383 Unexpect aCatch(SALOME_SalomeException);
4385 return _preMeshInfo->NbPrisms();
4387 return _impl->NbPrisms();
4390 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4392 Unexpect aCatch(SALOME_SalomeException);
4394 return _preMeshInfo->NbHexPrisms();
4396 return _impl->NbHexagonalPrisms();
4399 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4401 Unexpect aCatch(SALOME_SalomeException);
4403 return _preMeshInfo->NbPolyhedrons();
4405 return _impl->NbPolyhedrons();
4408 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4409 throw(SALOME::SALOME_Exception)
4411 Unexpect aCatch(SALOME_SalomeException);
4413 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4415 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4418 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4419 throw(SALOME::SALOME_Exception)
4421 Unexpect aCatch(SALOME_SalomeException);
4423 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4425 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4428 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4429 throw(SALOME::SALOME_Exception)
4431 Unexpect aCatch(SALOME_SalomeException);
4433 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4435 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4438 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4439 throw(SALOME::SALOME_Exception)
4441 Unexpect aCatch(SALOME_SalomeException);
4443 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4445 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4448 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4449 throw(SALOME::SALOME_Exception)
4451 Unexpect aCatch(SALOME_SalomeException);
4453 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4455 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4458 //=============================================================================
4460 * Returns nb of published sub-meshes
4462 //=============================================================================
4464 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4466 Unexpect aCatch(SALOME_SalomeException);
4467 return _mapSubMesh_i.size();
4470 //=============================================================================
4472 * Dumps mesh into a string
4474 //=============================================================================
4476 char* SMESH_Mesh_i::Dump()
4480 return CORBA::string_dup( os.str().c_str() );
4483 //=============================================================================
4485 * Method of SMESH_IDSource interface
4487 //=============================================================================
4489 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4491 return GetElementsId();
4494 //=============================================================================
4496 * Returns ids of all elements
4498 //=============================================================================
4500 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4501 throw (SALOME::SALOME_Exception)
4503 Unexpect aCatch(SALOME_SalomeException);
4505 _preMeshInfo->FullLoadFromFile();
4507 SMESH::long_array_var aResult = new SMESH::long_array();
4508 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4510 if ( aSMESHDS_Mesh == NULL )
4511 return aResult._retn();
4513 long nbElements = NbElements();
4514 aResult->length( nbElements );
4515 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4516 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4517 aResult[i] = anIt->next()->GetID();
4519 return aResult._retn();
4523 //=============================================================================
4525 * Returns ids of all elements of given type
4527 //=============================================================================
4529 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4530 throw (SALOME::SALOME_Exception)
4532 Unexpect aCatch(SALOME_SalomeException);
4534 _preMeshInfo->FullLoadFromFile();
4536 SMESH::long_array_var aResult = new SMESH::long_array();
4537 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4539 if ( aSMESHDS_Mesh == NULL )
4540 return aResult._retn();
4542 long nbElements = NbElements();
4544 // No sense in returning ids of elements along with ids of nodes:
4545 // when theElemType == SMESH::ALL, return node ids only if
4546 // there are no elements
4547 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4548 return GetNodesId();
4550 aResult->length( nbElements );
4554 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4555 while ( i < nbElements && anIt->more() )
4556 aResult[i++] = anIt->next()->GetID();
4558 aResult->length( i );
4560 return aResult._retn();
4563 //=============================================================================
4565 * Returns ids of all nodes
4567 //=============================================================================
4569 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4570 throw (SALOME::SALOME_Exception)
4572 Unexpect aCatch(SALOME_SalomeException);
4574 _preMeshInfo->FullLoadFromFile();
4576 SMESH::long_array_var aResult = new SMESH::long_array();
4577 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4579 if ( aMeshDS == NULL )
4580 return aResult._retn();
4582 long nbNodes = NbNodes();
4583 aResult->length( nbNodes );
4584 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4585 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4586 aResult[i] = anIt->next()->GetID();
4588 return aResult._retn();
4591 //=============================================================================
4595 //=============================================================================
4597 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4598 throw (SALOME::SALOME_Exception)
4600 SMESH::ElementType type = SMESH::ALL;
4604 _preMeshInfo->FullLoadFromFile();
4606 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4608 SMESH_CATCH( SMESH::throwCorbaException );
4613 //=============================================================================
4617 //=============================================================================
4619 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4620 throw (SALOME::SALOME_Exception)
4623 _preMeshInfo->FullLoadFromFile();
4625 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4627 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4629 return ( SMESH::EntityType ) e->GetEntityType();
4632 //=============================================================================
4636 //=============================================================================
4638 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4639 throw (SALOME::SALOME_Exception)
4642 _preMeshInfo->FullLoadFromFile();
4644 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4646 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4648 return ( SMESH::GeometryType ) e->GetGeomType();
4651 //=============================================================================
4653 * Returns ID of elements for given submesh
4655 //=============================================================================
4656 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4657 throw (SALOME::SALOME_Exception)
4659 SMESH::long_array_var aResult = new SMESH::long_array();
4663 _preMeshInfo->FullLoadFromFile();
4665 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4666 if(!SM) return aResult._retn();
4668 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4669 if(!SDSM) return aResult._retn();
4671 aResult->length(SDSM->NbElements());
4673 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4675 while ( eIt->more() ) {
4676 aResult[i++] = eIt->next()->GetID();
4679 SMESH_CATCH( SMESH::throwCorbaException );
4681 return aResult._retn();
4684 //=============================================================================
4686 * Returns ID of nodes for given submesh
4687 * If param all==true - returns all nodes, else -
4688 * returns only nodes on shapes.
4690 //=============================================================================
4692 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4694 throw (SALOME::SALOME_Exception)
4696 SMESH::long_array_var aResult = new SMESH::long_array();
4700 _preMeshInfo->FullLoadFromFile();
4702 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4703 if(!SM) return aResult._retn();
4705 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4706 if(!SDSM) return aResult._retn();
4709 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4710 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4711 while ( nIt->more() ) {
4712 const SMDS_MeshNode* elem = nIt->next();
4713 theElems.insert( elem->GetID() );
4716 else { // all nodes of submesh elements
4717 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4718 while ( eIt->more() ) {
4719 const SMDS_MeshElement* anElem = eIt->next();
4720 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4721 while ( nIt->more() ) {
4722 const SMDS_MeshElement* elem = nIt->next();
4723 theElems.insert( elem->GetID() );
4728 aResult->length(theElems.size());
4729 set<int>::iterator itElem;
4731 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4732 aResult[i++] = *itElem;
4734 SMESH_CATCH( SMESH::throwCorbaException );
4736 return aResult._retn();
4739 //=============================================================================
4741 * Returns type of elements for given submesh
4743 //=============================================================================
4745 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4746 throw (SALOME::SALOME_Exception)
4748 SMESH::ElementType type = SMESH::ALL;
4752 _preMeshInfo->FullLoadFromFile();
4754 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4755 if(!SM) return SMESH::ALL;
4757 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4758 if(!SDSM) return SMESH::ALL;
4760 if(SDSM->NbElements()==0)
4761 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4763 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4764 const SMDS_MeshElement* anElem = eIt->next();
4766 type = ( SMESH::ElementType ) anElem->GetType();
4768 SMESH_CATCH( SMESH::throwCorbaException );
4774 //=============================================================================
4776 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4778 //=============================================================================
4780 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4783 _preMeshInfo->FullLoadFromFile();
4785 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4786 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4791 //=============================================================================
4793 * Get XYZ coordinates of node as list of double
4794 * If there is not node for given ID - returns empty list
4796 //=============================================================================
4798 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4801 _preMeshInfo->FullLoadFromFile();
4803 SMESH::double_array_var aResult = new SMESH::double_array();
4804 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4805 if ( aMeshDS == NULL )
4806 return aResult._retn();
4809 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4811 return aResult._retn();
4815 aResult[0] = aNode->X();
4816 aResult[1] = aNode->Y();
4817 aResult[2] = aNode->Z();
4818 return aResult._retn();
4822 //=============================================================================
4824 * For given node returns list of IDs of inverse elements
4825 * If there is not node for given ID - returns empty list
4827 //=============================================================================
4829 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4830 SMESH::ElementType elemType)
4833 _preMeshInfo->FullLoadFromFile();
4835 SMESH::long_array_var aResult = new SMESH::long_array();
4836 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4837 if ( aMeshDS == NULL )
4838 return aResult._retn();
4841 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4843 return aResult._retn();
4845 // find inverse elements
4846 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4847 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4848 aResult->length( aNode->NbInverseElements( type ));
4849 for( int i = 0; eIt->more(); ++i )
4851 const SMDS_MeshElement* elem = eIt->next();
4852 aResult[ i ] = elem->GetID();
4854 return aResult._retn();
4857 //=============================================================================
4859 * \brief Return position of a node on shape
4861 //=============================================================================
4863 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4866 _preMeshInfo->FullLoadFromFile();
4868 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4869 aNodePosition->shapeID = 0;
4870 aNodePosition->shapeType = GEOM::SHAPE;
4872 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4873 if ( !mesh ) return aNodePosition;
4875 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4877 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4879 aNodePosition->shapeID = aNode->getshapeId();
4880 switch ( pos->GetTypeOfPosition() ) {
4882 aNodePosition->shapeType = GEOM::EDGE;
4883 aNodePosition->params.length(1);
4884 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4886 case SMDS_TOP_FACE: {
4887 SMDS_FacePositionPtr fPos = pos;
4888 aNodePosition->shapeType = GEOM::FACE;
4889 aNodePosition->params.length(2);
4890 aNodePosition->params[0] = fPos->GetUParameter();
4891 aNodePosition->params[1] = fPos->GetVParameter();
4894 case SMDS_TOP_VERTEX:
4895 aNodePosition->shapeType = GEOM::VERTEX;
4897 case SMDS_TOP_3DSPACE:
4898 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4899 aNodePosition->shapeType = GEOM::SOLID;
4900 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4901 aNodePosition->shapeType = GEOM::SHELL;
4907 return aNodePosition;
4910 //=============================================================================
4912 * \brief Return position of an element on shape
4914 //=============================================================================
4916 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4919 _preMeshInfo->FullLoadFromFile();
4921 SMESH::ElementPosition anElementPosition;
4922 anElementPosition.shapeID = 0;
4923 anElementPosition.shapeType = GEOM::SHAPE;
4925 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4926 if ( !mesh ) return anElementPosition;
4928 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4930 anElementPosition.shapeID = anElem->getshapeId();
4931 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4932 if ( !aSp.IsNull() ) {
4933 switch ( aSp.ShapeType() ) {
4935 anElementPosition.shapeType = GEOM::EDGE;
4938 anElementPosition.shapeType = GEOM::FACE;
4941 anElementPosition.shapeType = GEOM::VERTEX;
4944 anElementPosition.shapeType = GEOM::SOLID;
4947 anElementPosition.shapeType = GEOM::SHELL;
4953 return anElementPosition;
4956 //=============================================================================
4958 * If given element is node returns IDs of shape from position
4959 * If there is not node for given ID - returns -1
4961 //=============================================================================
4963 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4966 _preMeshInfo->FullLoadFromFile();
4968 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4969 if ( aMeshDS == NULL )
4973 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4975 return aNode->getshapeId();
4982 //=============================================================================
4984 * For given element returns ID of result shape after
4985 * ::FindShape() from SMESH_MeshEditor
4986 * If there is not element for given ID - returns -1
4988 //=============================================================================
4990 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4993 _preMeshInfo->FullLoadFromFile();
4995 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4996 if ( aMeshDS == NULL )
4999 // try to find element
5000 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5004 ::SMESH_MeshEditor aMeshEditor(_impl);
5005 int index = aMeshEditor.FindShape( elem );
5013 //=============================================================================
5015 * Returns number of nodes for given element
5016 * If there is not element for given ID - returns -1
5018 //=============================================================================
5020 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5023 _preMeshInfo->FullLoadFromFile();
5025 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5026 if ( aMeshDS == NULL ) return -1;
5027 // try to find element
5028 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5029 if(!elem) return -1;
5030 return elem->NbNodes();
5034 //=============================================================================
5036 * Returns ID of node by given index for given element
5037 * If there is not element for given ID - returns -1
5038 * If there is not node for given index - returns -2
5040 //=============================================================================
5042 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5045 _preMeshInfo->FullLoadFromFile();
5047 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5048 if ( aMeshDS == NULL ) return -1;
5049 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5050 if(!elem) return -1;
5051 if( index>=elem->NbNodes() || index<0 ) return -1;
5052 return elem->GetNode(index)->GetID();
5055 //=============================================================================
5057 * Returns IDs of nodes of given element
5059 //=============================================================================
5061 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5064 _preMeshInfo->FullLoadFromFile();
5066 SMESH::long_array_var aResult = new SMESH::long_array();
5067 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5069 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5071 aResult->length( elem->NbNodes() );
5072 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5073 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5074 aResult[ i ] = n->GetID();
5077 return aResult._retn();
5080 //=============================================================================
5082 * Returns true if given node is medium node
5083 * in given quadratic element
5085 //=============================================================================
5087 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5090 _preMeshInfo->FullLoadFromFile();
5092 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5093 if ( aMeshDS == NULL ) return false;
5095 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5096 if(!aNode) return false;
5097 // try to find element
5098 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5099 if(!elem) return false;
5101 return elem->IsMediumNode(aNode);
5105 //=============================================================================
5107 * Returns true if given node is medium node
5108 * in one of quadratic elements
5110 //=============================================================================
5112 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5113 SMESH::ElementType theElemType)
5116 _preMeshInfo->FullLoadFromFile();
5118 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5119 if ( aMeshDS == NULL ) return false;
5122 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5123 if(!aNode) return false;
5125 SMESH_MesherHelper aHelper( *(_impl) );
5127 SMDSAbs_ElementType aType;
5128 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5129 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5130 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5131 else aType = SMDSAbs_All;
5133 return aHelper.IsMedium(aNode,aType);
5137 //=============================================================================
5139 * Returns number of edges for given element
5141 //=============================================================================
5143 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5146 _preMeshInfo->FullLoadFromFile();
5148 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5149 if ( aMeshDS == NULL ) return -1;
5150 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5151 if(!elem) return -1;
5152 return elem->NbEdges();
5156 //=============================================================================
5158 * Returns number of faces for given element
5160 //=============================================================================
5162 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5165 _preMeshInfo->FullLoadFromFile();
5167 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5168 if ( aMeshDS == NULL ) return -1;
5169 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5170 if(!elem) return -1;
5171 return elem->NbFaces();
5174 //=======================================================================
5175 //function : GetElemFaceNodes
5176 //purpose : Returns nodes of given face (counted from zero) for given element.
5177 //=======================================================================
5179 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5180 CORBA::Short faceIndex)
5183 _preMeshInfo->FullLoadFromFile();
5185 SMESH::long_array_var aResult = new SMESH::long_array();
5186 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5188 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5190 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5191 if ( faceIndex < vtool.NbFaces() )
5193 aResult->length( vtool.NbFaceNodes( faceIndex ));
5194 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5195 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5196 aResult[ i ] = nn[ i ]->GetID();
5200 return aResult._retn();
5203 //=======================================================================
5204 //function : GetFaceNormal
5205 //purpose : Returns three components of normal of given mesh face.
5206 //=======================================================================
5208 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5209 CORBA::Boolean normalized)
5212 _preMeshInfo->FullLoadFromFile();
5214 SMESH::double_array_var aResult = new SMESH::double_array();
5216 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5219 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5221 aResult->length( 3 );
5222 aResult[ 0 ] = normal.X();
5223 aResult[ 1 ] = normal.Y();
5224 aResult[ 2 ] = normal.Z();
5227 return aResult._retn();
5230 //=======================================================================
5231 //function : FindElementByNodes
5232 //purpose : Returns an element based on all given nodes.
5233 //=======================================================================
5235 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5238 _preMeshInfo->FullLoadFromFile();
5240 CORBA::Long elemID(0);
5241 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5243 vector< const SMDS_MeshNode * > nn( nodes.length() );
5244 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5245 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5248 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5249 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5250 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5251 _impl->NbVolumes( ORDER_QUADRATIC )))
5252 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5254 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5259 //================================================================================
5261 * \brief Return elements including all given nodes.
5263 //================================================================================
5265 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5266 SMESH::ElementType elemType)
5269 _preMeshInfo->FullLoadFromFile();
5271 SMESH::long_array_var result = new SMESH::long_array();
5273 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5275 vector< const SMDS_MeshNode * > nn( nodes.length() );
5276 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5277 nn[i] = mesh->FindNode( nodes[i] );
5279 std::vector<const SMDS_MeshElement *> elems;
5280 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5281 result->length( elems.size() );
5282 for ( size_t i = 0; i < elems.size(); ++i )
5283 result[i] = elems[i]->GetID();
5285 return result._retn();
5288 //=============================================================================
5290 * Returns true if given element is polygon
5292 //=============================================================================
5294 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5297 _preMeshInfo->FullLoadFromFile();
5299 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5300 if ( aMeshDS == NULL ) return false;
5301 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5302 if(!elem) return false;
5303 return elem->IsPoly();
5307 //=============================================================================
5309 * Returns true if given element is quadratic
5311 //=============================================================================
5313 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5316 _preMeshInfo->FullLoadFromFile();
5318 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5319 if ( aMeshDS == NULL ) return false;
5320 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5321 if(!elem) return false;
5322 return elem->IsQuadratic();
5325 //=============================================================================
5327 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5329 //=============================================================================
5331 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5334 _preMeshInfo->FullLoadFromFile();
5336 if ( const SMDS_BallElement* ball =
5337 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5338 return ball->GetDiameter();
5343 //=============================================================================
5345 * Returns bary center for given element
5347 //=============================================================================
5349 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5352 _preMeshInfo->FullLoadFromFile();
5354 SMESH::double_array_var aResult = new SMESH::double_array();
5355 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5356 if ( aMeshDS == NULL )
5357 return aResult._retn();
5359 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5361 return aResult._retn();
5363 if(elem->GetType()==SMDSAbs_Volume) {
5364 SMDS_VolumeTool aTool;
5365 if(aTool.Set(elem)) {
5367 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5372 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5374 double x=0., y=0., z=0.;
5375 for(; anIt->more(); ) {
5377 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5391 return aResult._retn();
5394 //================================================================================
5396 * \brief Create a group of elements preventing computation of a sub-shape
5398 //================================================================================
5400 SMESH::ListOfGroups*
5401 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5402 const char* theGroupName )
5403 throw ( SALOME::SALOME_Exception )
5405 Unexpect aCatch(SALOME_SalomeException);
5407 if ( !theGroupName || strlen( theGroupName) == 0 )
5408 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5410 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5411 ::SMESH_MeshEditor::ElemFeatures elemType;
5413 // submesh by subshape id
5414 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5415 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5418 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5419 if ( error && error->HasBadElems() )
5421 // sort bad elements by type
5422 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5423 const list<const SMDS_MeshElement*>& badElems =
5424 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5425 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5426 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5427 for ( ; elemIt != elemEnd; ++elemIt )
5429 const SMDS_MeshElement* elem = *elemIt;
5430 if ( !elem ) continue;
5432 if ( elem->GetID() < 1 )
5434 // elem is a temporary element, make a real element
5435 vector< const SMDS_MeshNode* > nodes;
5436 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5437 while ( nIt->more() && elem )
5439 nodes.push_back( nIt->next() );
5440 if ( nodes.back()->GetID() < 1 )
5441 elem = 0; // a temporary element on temporary nodes
5445 ::SMESH_MeshEditor editor( _impl );
5446 elem = editor.AddElement( nodes, elemType.Init( elem ));
5450 elemsByType[ elem->GetType() ].push_back( elem );
5453 // how many groups to create?
5455 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5456 nbTypes += int( !elemsByType[ i ].empty() );
5457 groups->length( nbTypes );
5460 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5462 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5463 if ( elems.empty() ) continue;
5465 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5466 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5468 SMESH::SMESH_Mesh_var mesh = _this();
5469 SALOMEDS::SObject_wrap aSO =
5470 _gen_i->PublishGroup( mesh, groups[ iG ],
5471 GEOM::GEOM_Object::_nil(), theGroupName);
5473 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5474 if ( !grp_i ) continue;
5476 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5477 for ( size_t iE = 0; iE < elems.size(); ++iE )
5478 grpDS->SMDSGroup().Add( elems[ iE ]);
5483 return groups._retn();
5486 //=============================================================================
5488 * Create and publish group servants if any groups were imported or created anyhow
5490 //=============================================================================
5492 void SMESH_Mesh_i::CreateGroupServants()
5494 SMESH::SMESH_Mesh_var aMesh = _this();
5497 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5498 while ( groupIt->more() )
5500 ::SMESH_Group* group = groupIt->next();
5501 int anId = group->GetID();
5503 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5504 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5506 addedIDs.insert( anId );
5508 SMESH_GroupBase_i* aGroupImpl;
5510 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5511 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5513 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5514 shape = groupOnGeom->GetShape();
5517 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5520 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5521 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5522 aGroupImpl->Register();
5524 // register CORBA object for persistence
5525 int nextId = _gen_i->RegisterObject( groupVar );
5526 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5527 else { nextId = 0; } // avoid "unused variable" warning in release mode
5529 // publishing the groups in the study
5530 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5531 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5533 if ( !addedIDs.empty() )
5536 set<int>::iterator id = addedIDs.begin();
5537 for ( ; id != addedIDs.end(); ++id )
5539 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5540 int i = std::distance( _mapGroups.begin(), it );
5541 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5546 //=============================================================================
5548 * \brief Return true if all sub-meshes are computed OK - to update an icon
5550 //=============================================================================
5552 bool SMESH_Mesh_i::IsComputedOK()
5554 return _impl->IsComputedOK();
5557 //=============================================================================
5559 * \brief Return groups cantained in _mapGroups by their IDs
5561 //=============================================================================
5563 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5565 int nbGroups = groupIDs.size();
5566 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5567 aList->length( nbGroups );
5569 list<int>::const_iterator ids = groupIDs.begin();
5570 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5572 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5573 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5574 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5576 aList->length( nbGroups );
5577 return aList._retn();
5580 //=============================================================================
5582 * \brief Return information about imported file
5584 //=============================================================================
5586 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5588 SMESH::MedFileInfo_var res( _medFileInfo );
5589 if ( !res.operator->() ) {
5590 res = new SMESH::MedFileInfo;
5592 res->fileSize = res->major = res->minor = res->release = -1;
5597 //=======================================================================
5598 //function : FileInfoToString
5599 //purpose : Persistence of file info
5600 //=======================================================================
5602 std::string SMESH_Mesh_i::FileInfoToString()
5605 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5607 s = SMESH_Comment( _medFileInfo->fileSize )
5608 << " " << _medFileInfo->major
5609 << " " << _medFileInfo->minor
5610 << " " << _medFileInfo->release
5611 << " " << _medFileInfo->fileName;
5616 //=======================================================================
5617 //function : FileInfoFromString
5618 //purpose : Persistence of file info
5619 //=======================================================================
5621 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5623 std::string size, major, minor, release, fileName;
5624 std::istringstream is(info);
5625 is >> size >> major >> minor >> release;
5626 fileName = info.data() + ( size.size() + 1 +
5629 release.size()+ 1 );
5631 _medFileInfo = new SMESH::MedFileInfo();
5632 _medFileInfo->fileName = fileName.c_str();
5633 _medFileInfo->fileSize = atoi( size.c_str() );
5634 _medFileInfo->major = atoi( major.c_str() );
5635 _medFileInfo->minor = atoi( minor.c_str() );
5636 _medFileInfo->release = atoi( release.c_str() );
5639 //=============================================================================
5641 * \brief Pass names of mesh groups from study to mesh DS
5643 //=============================================================================
5645 void SMESH_Mesh_i::checkGroupNames()
5647 int nbGrp = NbGroups();
5651 SMESH::ListOfGroups* grpList = 0;
5652 // avoid dump of "GetGroups"
5654 // store python dump into a local variable inside local scope
5655 SMESH::TPythonDump pDump; // do not delete this line of code
5656 grpList = GetGroups();
5659 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5660 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5663 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5664 if ( aGrpSO->_is_nil() )
5666 // correct name of the mesh group if necessary
5667 const char* guiName = aGrpSO->GetName();
5668 if ( strcmp(guiName, aGrp->GetName()) )
5669 aGrp->SetName( guiName );
5673 //=============================================================================
5675 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5677 //=============================================================================
5678 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5680 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5684 //=============================================================================
5686 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5688 //=============================================================================
5690 char* SMESH_Mesh_i::GetParameters()
5692 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5695 //=============================================================================
5697 * \brief Returns list of notebook variables used for last Mesh operation
5699 //=============================================================================
5700 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5702 SMESH::string_array_var aResult = new SMESH::string_array();
5703 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5705 CORBA::String_var aParameters = GetParameters();
5706 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5707 if ( aSections->length() > 0 ) {
5708 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5709 aResult->length( aVars.length() );
5710 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5711 aResult[i] = CORBA::string_dup( aVars[i] );
5714 return aResult._retn();
5717 //=======================================================================
5718 //function : GetTypes
5719 //purpose : Returns types of elements it contains
5720 //=======================================================================
5722 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5725 return _preMeshInfo->GetTypes();
5727 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5731 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5732 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5733 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5734 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5735 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5736 if (_impl->NbNodes() &&
5737 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5738 types->length( nbTypes );
5740 return types._retn();
5743 //=======================================================================
5744 //function : GetMesh
5745 //purpose : Returns self
5746 //=======================================================================
5748 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5750 return SMESH::SMESH_Mesh::_duplicate( _this() );
5753 //=======================================================================
5754 //function : IsMeshInfoCorrect
5755 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5756 // * happen if mesh data is not yet fully loaded from the file of study.
5757 //=======================================================================
5759 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5761 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5764 //=============================================================================
5766 * \brief Returns number of mesh elements per each \a EntityType
5768 //=============================================================================
5770 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5773 return _preMeshInfo->GetMeshInfo();
5775 SMESH::long_array_var aRes = new SMESH::long_array();
5776 aRes->length(SMESH::Entity_Last);
5777 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5779 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5781 return aRes._retn();
5782 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5783 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5784 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5785 return aRes._retn();
5788 //=============================================================================
5790 * \brief Returns number of mesh elements per each \a ElementType
5792 //=============================================================================
5794 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5796 SMESH::long_array_var aRes = new SMESH::long_array();
5797 aRes->length(SMESH::NB_ELEMENT_TYPES);
5798 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5801 const SMDS_MeshInfo* meshInfo = 0;
5803 meshInfo = _preMeshInfo;
5804 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5805 meshInfo = & meshDS->GetMeshInfo();
5808 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5809 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5811 return aRes._retn();
5814 //=============================================================================
5816 * Collect statistic of mesh elements given by iterator
5818 //=============================================================================
5820 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5821 SMESH::long_array& theInfo)
5823 if (!theItr) return;
5824 while (theItr->more())
5825 theInfo[ theItr->next()->GetEntityType() ]++;
5827 //=============================================================================
5829 * Returns mesh unstructed grid information.
5831 //=============================================================================
5833 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5835 SALOMEDS::TMPFile_var SeqFile;
5836 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5837 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5839 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5840 aWriter->WriteToOutputStringOn();
5841 aWriter->SetInputData(aGrid);
5842 aWriter->SetFileTypeToBinary();
5844 char* str = aWriter->GetOutputString();
5845 int size = aWriter->GetOutputStringLength();
5847 //Allocate octet buffer of required size
5848 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5849 //Copy ostrstream content to the octet buffer
5850 memcpy(OctetBuf, str, size);
5851 //Create and return TMPFile
5852 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5856 return SeqFile._retn();
5859 //=============================================================================
5860 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5861 * SMESH::ElementType type) */
5863 using namespace SMESH::Controls;
5864 //-----------------------------------------------------------------------------
5865 struct PredicateIterator : public SMDS_ElemIterator
5867 SMDS_ElemIteratorPtr _elemIter;
5868 PredicatePtr _predicate;
5869 const SMDS_MeshElement* _elem;
5870 SMDSAbs_ElementType _type;
5872 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5873 PredicatePtr predicate,
5874 SMDSAbs_ElementType type):
5875 _elemIter(iterator), _predicate(predicate), _type(type)
5883 virtual const SMDS_MeshElement* next()
5885 const SMDS_MeshElement* res = _elem;
5887 while ( _elemIter->more() && !_elem )
5889 if ((_elem = _elemIter->next()) &&
5890 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5891 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5898 //-----------------------------------------------------------------------------
5899 struct IDSourceIterator : public SMDS_ElemIterator
5901 const CORBA::Long* _idPtr;
5902 const CORBA::Long* _idEndPtr;
5903 SMESH::long_array_var _idArray;
5904 const SMDS_Mesh* _mesh;
5905 const SMDSAbs_ElementType _type;
5906 const SMDS_MeshElement* _elem;
5908 IDSourceIterator( const SMDS_Mesh* mesh,
5909 const CORBA::Long* ids,
5911 SMDSAbs_ElementType type):
5912 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5914 if ( _idPtr && nbIds && _mesh )
5917 IDSourceIterator( const SMDS_Mesh* mesh,
5918 SMESH::long_array* idArray,
5919 SMDSAbs_ElementType type):
5920 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5922 if ( idArray && _mesh )
5924 _idPtr = &_idArray[0];
5925 _idEndPtr = _idPtr + _idArray->length();
5933 virtual const SMDS_MeshElement* next()
5935 const SMDS_MeshElement* res = _elem;
5937 while ( _idPtr < _idEndPtr && !_elem )
5939 if ( _type == SMDSAbs_Node )
5941 _elem = _mesh->FindNode( *_idPtr++ );
5943 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5944 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5952 //-----------------------------------------------------------------------------
5954 struct NodeOfElemIterator : public SMDS_ElemIterator
5956 TColStd_MapOfInteger _checkedNodeIDs;
5957 SMDS_ElemIteratorPtr _elemIter;
5958 SMDS_ElemIteratorPtr _nodeIter;
5959 const SMDS_MeshElement* _node;
5961 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5963 if ( _elemIter && _elemIter->more() )
5965 _nodeIter = _elemIter->next()->nodesIterator();
5973 virtual const SMDS_MeshElement* next()
5975 const SMDS_MeshElement* res = _node;
5977 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5979 if ( _nodeIter->more() )
5981 _node = _nodeIter->next();
5982 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5987 _nodeIter = _elemIter->next()->nodesIterator();
5995 //=============================================================================
5997 * Return iterator on elements of given type in given object
5999 //=============================================================================
6001 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6002 SMESH::ElementType theType)
6004 SMDS_ElemIteratorPtr elemIt;
6005 bool typeOK = ( theType == SMESH::ALL );
6006 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6008 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6009 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6010 if ( !mesh_i ) return elemIt;
6011 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6013 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6015 elemIt = meshDS->elementsIterator( elemType );
6018 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6020 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6023 elemIt = sm->GetElements();
6024 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6026 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6027 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6031 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6033 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6034 if ( groupDS && ( elemType == groupDS->GetType() ||
6035 elemType == SMDSAbs_Node ||
6036 elemType == SMDSAbs_All ))
6038 elemIt = groupDS->GetElements();
6039 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6042 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6044 if ( filter_i->GetElementType() == theType ||
6045 filter_i->GetElementType() == SMESH::ALL ||
6046 elemType == SMDSAbs_Node ||
6047 elemType == SMDSAbs_All)
6049 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6050 if ( pred_i && pred_i->GetPredicate() )
6052 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6053 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6054 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6055 elemIt = SMDS_ElemIteratorPtr
6056 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6057 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6063 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6064 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6065 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6067 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6068 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6071 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6072 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6076 SMESH::long_array_var ids = theObject->GetIDs();
6077 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6079 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6082 if ( elemIt && elemIt->more() && !typeOK )
6084 if ( elemType == SMDSAbs_Node )
6086 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6090 elemIt = SMDS_ElemIteratorPtr();
6096 //=============================================================================
6097 namespace // Finding concurrent hypotheses
6098 //=============================================================================
6102 * \brief mapping of mesh dimension into shape type
6104 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6106 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6108 case 0: aType = TopAbs_VERTEX; break;
6109 case 1: aType = TopAbs_EDGE; break;
6110 case 2: aType = TopAbs_FACE; break;
6112 default:aType = TopAbs_SOLID; break;
6117 //-----------------------------------------------------------------------------
6119 * \brief Internal structure used to find concurrent submeshes
6121 * It represents a pair < submesh, concurrent dimension >, where
6122 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6123 * with another submesh. In other words, it is dimension of a hypothesis assigned
6130 int _dim; //!< a dimension the algo can build (concurrent dimension)
6131 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6132 TopTools_MapOfShape _shapeMap;
6133 SMESH_subMesh* _subMesh;
6134 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6136 //-----------------------------------------------------------------------------
6137 // Return the algorithm
6138 const SMESH_Algo* GetAlgo() const
6139 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6141 //-----------------------------------------------------------------------------
6143 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6145 const TopoDS_Shape& theShape)
6147 _subMesh = (SMESH_subMesh*)theSubMesh;
6148 SetShape( theDim, theShape );
6151 //-----------------------------------------------------------------------------
6153 void SetShape(const int theDim,
6154 const TopoDS_Shape& theShape)
6157 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6158 if (_dim >= _ownDim)
6159 _shapeMap.Add( theShape );
6161 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6162 for( ; anExp.More(); anExp.Next() )
6163 _shapeMap.Add( anExp.Current() );
6167 //-----------------------------------------------------------------------------
6168 //! Check sharing of sub-shapes
6169 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6170 const TopTools_MapOfShape& theToFind,
6171 const TopAbs_ShapeEnum theType)
6173 bool isShared = false;
6174 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6175 for (; !isShared && anItr.More(); anItr.Next() )
6177 const TopoDS_Shape aSubSh = anItr.Key();
6178 // check for case when concurrent dimensions are same
6179 isShared = theToFind.Contains( aSubSh );
6180 // check for sub-shape with concurrent dimension
6181 TopExp_Explorer anExp( aSubSh, theType );
6182 for ( ; !isShared && anExp.More(); anExp.Next() )
6183 isShared = theToFind.Contains( anExp.Current() );
6188 //-----------------------------------------------------------------------------
6189 //! check algorithms
6190 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6191 const SMESHDS_Hypothesis* theA2)
6193 if ( !theA1 || !theA2 ||
6194 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6195 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6196 return false; // one of the hypothesis is not algorithm
6197 // check algorithm names (should be equal)
6198 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6202 //-----------------------------------------------------------------------------
6203 //! Check if sub-shape hypotheses are concurrent
6204 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6206 if ( _subMesh == theOther->_subMesh )
6207 return false; // same sub-shape - should not be
6209 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6210 // any of the two submeshes is not on COMPOUND shape )
6211 // -> no concurrency
6212 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6213 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6214 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6215 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6216 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6219 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6220 if ( !checkSubShape )
6223 // check algorithms to be same
6224 const SMESH_Algo* a1 = this->GetAlgo();
6225 const SMESH_Algo* a2 = theOther->GetAlgo();
6226 bool isSame = checkAlgo( a1, a2 );
6230 return false; // pb?
6231 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6234 // check hypothesises for concurrence (skip first as algorithm)
6236 // pointers should be same, because it is referened from mesh hypothesis partition
6237 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6238 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6239 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6240 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6242 // the submeshes are concurrent if their algorithms has different parameters
6243 return nbSame != theOther->_hypotheses.size() - 1;
6246 // Return true if algorithm of this SMESH_DimHyp is used if no
6247 // sub-mesh order is imposed by the user
6248 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6250 // NeedDiscreteBoundary() algo has a higher priority
6251 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6252 theOther->GetAlgo()->NeedDiscreteBoundary() )
6253 return !this->GetAlgo()->NeedDiscreteBoundary();
6255 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6258 }; // end of SMESH_DimHyp
6259 //-----------------------------------------------------------------------------
6261 typedef list<const SMESH_DimHyp*> TDimHypList;
6263 //-----------------------------------------------------------------------------
6265 void addDimHypInstance(const int theDim,
6266 const TopoDS_Shape& theShape,
6267 const SMESH_Algo* theAlgo,
6268 const SMESH_subMesh* theSubMesh,
6269 const list <const SMESHDS_Hypothesis*>& theHypList,
6270 TDimHypList* theDimHypListArr )
6272 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6273 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6274 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6275 dimHyp->_hypotheses.push_front(theAlgo);
6276 listOfdimHyp.push_back( dimHyp );
6279 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6280 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6281 theHypList.begin(), theHypList.end() );
6284 //-----------------------------------------------------------------------------
6285 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6286 TDimHypList& theListOfConcurr)
6288 if ( theListOfConcurr.empty() )
6290 theListOfConcurr.push_back( theDimHyp );
6294 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6295 while ( hypIt != theListOfConcurr.end() &&
6296 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6298 theListOfConcurr.insert( hypIt, theDimHyp );
6302 //-----------------------------------------------------------------------------
6303 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6304 const TDimHypList& theListOfDimHyp,
6305 TDimHypList& theListOfConcurrHyp,
6306 set<int>& theSetOfConcurrId )
6308 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6309 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6311 const SMESH_DimHyp* curDimHyp = *rIt;
6312 if ( curDimHyp == theDimHyp )
6313 break; // meet own dimHyp pointer in same dimension
6315 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6316 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6318 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6323 //-----------------------------------------------------------------------------
6324 void unionLists(TListOfInt& theListOfId,
6325 TListOfListOfInt& theListOfListOfId,
6328 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6329 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6331 continue; //skip already treated lists
6332 // check if other list has any same submesh object
6333 TListOfInt& otherListOfId = *it;
6334 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6335 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6338 // union two lists (from source into target)
6339 TListOfInt::iterator it2 = otherListOfId.begin();
6340 for ( ; it2 != otherListOfId.end(); it2++ ) {
6341 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6342 theListOfId.push_back(*it2);
6344 // clear source list
6345 otherListOfId.clear();
6348 //-----------------------------------------------------------------------------
6350 //! free memory allocated for dimension-hypothesis objects
6351 void removeDimHyps( TDimHypList* theArrOfList )
6353 for (int i = 0; i < 4; i++ ) {
6354 TDimHypList& listOfdimHyp = theArrOfList[i];
6355 TDimHypList::const_iterator it = listOfdimHyp.begin();
6356 for ( ; it != listOfdimHyp.end(); it++ )
6361 //-----------------------------------------------------------------------------
6363 * \brief find common submeshes with given submesh
6364 * \param theSubMeshList list of already collected submesh to check
6365 * \param theSubMesh given submesh to intersect with other
6366 * \param theCommonSubMeshes collected common submeshes
6368 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6369 const SMESH_subMesh* theSubMesh,
6370 set<const SMESH_subMesh*>& theCommon )
6374 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6375 for ( ; it != theSubMeshList.end(); it++ )
6376 theSubMesh->FindIntersection( *it, theCommon );
6377 theSubMeshList.push_back( theSubMesh );
6378 //theCommon.insert( theSubMesh );
6381 //-----------------------------------------------------------------------------
6382 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6384 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6385 for ( ; listsIt != smLists.end(); ++listsIt )
6387 const TListOfInt& smIDs = *listsIt;
6388 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6396 //=============================================================================
6398 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6400 //=============================================================================
6402 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6404 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6405 if ( isSubMeshInList( submeshID, anOrder ))
6408 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6409 return isSubMeshInList( submeshID, allConurrent );
6412 //=============================================================================
6414 * \brief Return submesh objects list in meshing order
6416 //=============================================================================
6418 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6420 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6422 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6424 return aResult._retn();
6426 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6427 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6428 anOrder.splice( anOrder.end(), allConurrent );
6431 TListOfListOfInt::iterator listIt = anOrder.begin();
6432 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6433 unionLists( *listIt, anOrder, listIndx + 1 );
6435 // convert submesh ids into interface instances
6436 // and dump command into python
6437 convertMeshOrder( anOrder, aResult, false );
6439 return aResult._retn();
6442 //=============================================================================
6444 * \brief Finds concurrent sub-meshes
6446 //=============================================================================
6448 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6450 TListOfListOfInt anOrder;
6451 ::SMESH_Mesh& mesh = GetImpl();
6453 // collect submeshes and detect concurrent algorithms and hypothesises
6454 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6456 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6457 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6458 ::SMESH_subMesh* sm = (*i_sm).second;
6460 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6462 // list of assigned hypothesises
6463 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6464 // Find out dimensions where the submesh can be concurrent.
6465 // We define the dimensions by algo of each of hypotheses in hypList
6466 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6467 for( ; hypIt != hypList.end(); hypIt++ ) {
6468 SMESH_Algo* anAlgo = 0;
6469 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6470 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6471 // hyp it-self is algo
6472 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6474 // try to find algorithm with help of sub-shapes
6475 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6476 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6477 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6480 continue; // no algorithm assigned to a current submesh
6482 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6483 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6485 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6486 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6487 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6489 } // end iterations on submesh
6491 // iterate on created dimension-hypotheses and check for concurrents
6492 for ( int i = 0; i < 4; i++ ) {
6493 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6494 // check for concurrents in own and other dimensions (step-by-step)
6495 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6496 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6497 const SMESH_DimHyp* dimHyp = *dhIt;
6498 TDimHypList listOfConcurr;
6499 set<int> setOfConcurrIds;
6500 // looking for concurrents and collect into own list
6501 for ( int j = i; j < 4; j++ )
6502 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6503 // check if any concurrents found
6504 if ( listOfConcurr.size() > 0 ) {
6505 // add own submesh to list of concurrent
6506 addInOrderOfPriority( dimHyp, listOfConcurr );
6507 list<int> listOfConcurrIds;
6508 TDimHypList::iterator hypIt = listOfConcurr.begin();
6509 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6510 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6511 anOrder.push_back( listOfConcurrIds );
6516 removeDimHyps(dimHypListArr);
6518 // now, minimize the number of concurrent groups
6519 // Here we assume that lists of submeshes can have same submesh
6520 // in case of multi-dimension algorithms, as result
6521 // list with common submesh has to be united into one list
6523 TListOfListOfInt::iterator listIt = anOrder.begin();
6524 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6525 unionLists( *listIt, anOrder, listIndx + 1 );
6531 //=============================================================================
6533 * \brief Set submesh object order
6534 * \param theSubMeshArray submesh array order
6536 //=============================================================================
6538 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6541 _preMeshInfo->ForgetOrLoad();
6544 ::SMESH_Mesh& mesh = GetImpl();
6546 TPythonDump aPythonDump; // prevent dump of called methods
6547 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6549 TListOfListOfInt subMeshOrder;
6550 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6552 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6553 TListOfInt subMeshIds;
6555 aPythonDump << ", ";
6556 aPythonDump << "[ ";
6557 // Collect subMeshes which should be clear
6558 // do it list-by-list, because modification of submesh order
6559 // take effect between concurrent submeshes only
6560 set<const SMESH_subMesh*> subMeshToClear;
6561 list<const SMESH_subMesh*> subMeshList;
6562 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6564 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6566 aPythonDump << ", ";
6567 aPythonDump << subMesh;
6568 subMeshIds.push_back( subMesh->GetId() );
6569 // detect common parts of submeshes
6570 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6571 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6573 aPythonDump << " ]";
6574 subMeshOrder.push_back( subMeshIds );
6576 // clear collected sub-meshes
6577 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6578 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6579 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6581 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6582 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6583 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6586 aPythonDump << " ])";
6588 mesh.SetMeshOrder( subMeshOrder );
6591 SMESH::SMESH_Mesh_var me = _this();
6592 _gen_i->UpdateIcons( me );
6597 //=============================================================================
6599 * \brief Convert submesh ids into submesh interfaces
6601 //=============================================================================
6603 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6604 SMESH::submesh_array_array& theResOrder,
6605 const bool theIsDump)
6607 int nbSet = theIdsOrder.size();
6608 TPythonDump aPythonDump; // prevent dump of called methods
6610 aPythonDump << "[ ";
6611 theResOrder.length(nbSet);
6612 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6614 for( ; it != theIdsOrder.end(); it++ ) {
6615 // translate submesh identificators into submesh objects
6616 // takeing into account real number of concurrent lists
6617 const TListOfInt& aSubOrder = (*it);
6618 if (!aSubOrder.size())
6621 aPythonDump << "[ ";
6622 // convert shape indices into interfaces
6623 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6624 aResSubSet->length(aSubOrder.size());
6625 TListOfInt::const_iterator subIt = aSubOrder.begin();
6627 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6628 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6630 SMESH::SMESH_subMesh_var subMesh =
6631 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6634 aPythonDump << ", ";
6635 aPythonDump << subMesh;
6637 aResSubSet[ j++ ] = subMesh;
6640 aPythonDump << " ]";
6642 theResOrder[ listIndx++ ] = aResSubSet;
6644 // correct number of lists
6645 theResOrder.length( listIndx );
6648 // finilise python dump
6649 aPythonDump << " ]";
6650 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6654 namespace // utils used by SMESH_MeshPartDS
6657 * \brief Class used to access to protected data of SMDS_MeshInfo
6659 struct TMeshInfo : public SMDS_MeshInfo
6661 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6664 * \brief Element holing its ID only
6666 struct TElemID : public SMDS_LinearEdge
6668 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6672 //================================================================================
6674 // Implementation of SMESH_MeshPartDS
6676 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6677 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6679 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6680 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6683 _meshDS = mesh_i->GetImpl().GetMeshDS();
6685 SetPersistentId( _meshDS->GetPersistentId() );
6687 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6689 // <meshPart> is the whole mesh
6690 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6692 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6693 myGroupSet = _meshDS->GetGroups();
6698 SMESH::long_array_var anIDs = meshPart->GetIDs();
6699 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6700 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6702 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6703 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6704 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6709 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6710 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6711 if ( _elements[ e->GetType() ].insert( e ).second )
6714 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6715 while ( nIt->more() )
6717 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6718 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6725 ShapeToMesh( _meshDS->ShapeToMesh() );
6727 _meshDS = 0; // to enforce iteration on _elements and _nodes
6730 // -------------------------------------------------------------------------------------
6731 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6732 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6735 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6736 for ( ; partIt != meshPart.end(); ++partIt )
6737 if ( const SMDS_MeshElement * e = *partIt )
6738 if ( _elements[ e->GetType() ].insert( e ).second )
6741 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6742 while ( nIt->more() )
6744 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6745 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6751 // -------------------------------------------------------------------------------------
6752 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6754 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6756 TElemID elem( IDelem );
6757 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6758 if ( !_elements[ iType ].empty() )
6760 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6761 if ( it != _elements[ iType ].end() )
6766 // -------------------------------------------------------------------------------------
6767 bool SMESH_MeshPartDS::HasNumerationHoles()
6769 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6771 return ( MinNodeID() != 1 ||
6772 MaxNodeID() != NbNodes() ||
6773 MinElementID() != 1 ||
6774 MaxElementID() != NbElements() );
6776 // -------------------------------------------------------------------------------------
6777 int SMESH_MeshPartDS::MaxNodeID() const
6779 if ( _meshDS ) return _meshDS->MaxNodeID();
6780 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6782 // -------------------------------------------------------------------------------------
6783 int SMESH_MeshPartDS::MinNodeID() const
6785 if ( _meshDS ) return _meshDS->MinNodeID();
6786 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6788 // -------------------------------------------------------------------------------------
6789 int SMESH_MeshPartDS::MaxElementID() const
6791 if ( _meshDS ) return _meshDS->MaxElementID();
6793 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6794 if ( !_elements[ iType ].empty() )
6795 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6798 // -------------------------------------------------------------------------------------
6799 int SMESH_MeshPartDS::MinElementID() const
6801 if ( _meshDS ) return _meshDS->MinElementID();
6803 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6804 if ( !_elements[ iType ].empty() )
6805 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6808 // -------------------------------------------------------------------------------------
6809 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6811 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6813 typedef SMDS_SetIterator
6814 <const SMDS_MeshElement*,
6815 TIDSortedElemSet::const_iterator,
6816 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6817 SMDS_MeshElement::GeomFilter
6820 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6822 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6823 _elements[type].end(),
6824 SMDS_MeshElement::GeomFilter( geomType )));
6826 // -------------------------------------------------------------------------------------
6827 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6829 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6831 typedef SMDS_SetIterator
6832 <const SMDS_MeshElement*,
6833 TIDSortedElemSet::const_iterator,
6834 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6835 SMDS_MeshElement::EntityFilter
6838 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6840 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6841 _elements[type].end(),
6842 SMDS_MeshElement::EntityFilter( entity )));
6844 // -------------------------------------------------------------------------------------
6845 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6847 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6848 if ( type == SMDSAbs_All && !_meshDS )
6850 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6852 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6853 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6855 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6857 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6858 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6860 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6861 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6863 // -------------------------------------------------------------------------------------
6864 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6865 iterType SMESH_MeshPartDS::methName() const \
6867 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6868 return _meshDS ? _meshDS->methName() : iterType \
6869 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6871 // -------------------------------------------------------------------------------------
6872 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6873 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6874 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6875 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6876 #undef _GET_ITER_DEFINE
6878 // END Implementation of SMESH_MeshPartDS
6880 //================================================================================