1 // Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_MapIteratorOfMapOfShape.hxx>
76 #include <TopTools_MapOfShape.hxx>
77 #include <TopoDS_Compound.hxx>
84 #include <vtkUnstructuredGridWriter.h>
86 // to pass CORBA exception through SMESH_TRY
87 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
89 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
92 static int MYDEBUG = 0;
94 static int MYDEBUG = 0;
98 using SMESH::TPythonDump;
100 int SMESH_Mesh_i::_idGenerator = 0;
102 //=============================================================================
106 //=============================================================================
108 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
110 : SALOME::GenericObj_i( thePOA )
114 _id = _idGenerator++;
116 _previewEditor = NULL;
121 //=============================================================================
125 //=============================================================================
127 SMESH_Mesh_i::~SMESH_Mesh_i()
130 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
131 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
132 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
134 aGroup->UnRegister();
135 SMESH::SMESH_GroupBase_var( itGr->second );
140 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
141 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
142 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
144 aSubMesh->UnRegister();
145 SMESH::SMESH_subMesh_var( itSM->second );
147 _mapSubMeshIor.clear();
149 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
150 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
151 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
152 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
153 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
154 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
157 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
161 // clear cached shapes if no more meshes remain; (the cache is blame,
162 // together with publishing, of spent time increasing in issue 22874)
163 if ( _impl->NbMeshes() == 1 )
164 _gen_i->GetShapeReader()->ClearClientBuffer();
166 delete _editor; _editor = NULL;
167 delete _previewEditor; _previewEditor = NULL;
168 delete _impl; _impl = NULL;
169 delete _preMeshInfo; _preMeshInfo = NULL;
172 //=============================================================================
176 * Associates <this> mesh with <theShape> and puts a reference
177 * to <theShape> into the current study;
178 * the previous shape is substituted by the new one.
180 //=============================================================================
182 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
183 throw (SALOME::SALOME_Exception)
185 Unexpect aCatch(SALOME_SalomeException);
187 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
189 catch(SALOME_Exception & S_ex) {
190 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
192 // to track changes of GEOM groups
193 SMESH::SMESH_Mesh_var mesh = _this();
194 addGeomGroupData( theShapeObject, mesh );
195 if ( !CORBA::is_nil( theShapeObject ))
196 _mainShapeTick = theShapeObject->GetTick();
199 //================================================================================
201 * \brief return true if mesh has a shape to build a shape on
203 //================================================================================
205 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
206 throw (SALOME::SALOME_Exception)
208 Unexpect aCatch(SALOME_SalomeException);
211 res = _impl->HasShapeToMesh();
213 catch(SALOME_Exception & S_ex) {
214 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
219 //=======================================================================
220 //function : GetShapeToMesh
222 //=======================================================================
224 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
225 throw (SALOME::SALOME_Exception)
227 Unexpect aCatch(SALOME_SalomeException);
228 GEOM::GEOM_Object_var aShapeObj;
230 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
233 aShapeObj = _gen_i->ShapeToGeomObject( S );
234 if ( aShapeObj->_is_nil() )
236 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
237 // find GEOM_Object by entry (IPAL52735)
238 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
239 for ( ; data != _geomGroupData.end(); ++data )
240 if ( data->_smeshObject->_is_equivalent( _this() ))
242 SALOMEDS::SObject_wrap so = SMESH_Gen_i::getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
243 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
244 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
250 catch(SALOME_Exception & S_ex) {
251 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
253 return aShapeObj._retn();
256 //================================================================================
258 * \brief Return false if the mesh is not yet fully loaded from the study file
260 //================================================================================
262 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
264 Unexpect aCatch(SALOME_SalomeException);
265 return !_preMeshInfo;
268 //================================================================================
270 * \brief Load full mesh data from the study file
272 //================================================================================
274 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->FullLoadFromFile();
281 //================================================================================
283 * \brief Remove all nodes and elements
285 //================================================================================
287 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
289 Unexpect aCatch(SALOME_SalomeException);
291 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
295 //CheckGeomGroupModif(); // issue 20145
297 catch(SALOME_Exception & S_ex) {
298 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
301 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
303 SMESH::SMESH_Mesh_var mesh = _this();
304 _gen_i->UpdateIcons( mesh );
307 //================================================================================
309 * \brief Remove all nodes and elements for indicated shape
311 //================================================================================
313 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
314 throw (SALOME::SALOME_Exception)
316 Unexpect aCatch(SALOME_SalomeException);
318 _preMeshInfo->FullLoadFromFile();
321 _impl->ClearSubMesh( ShapeID );
323 catch(SALOME_Exception & S_ex) {
324 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
326 _impl->GetMeshDS()->Modified();
328 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
331 //=============================================================================
333 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
335 //=============================================================================
337 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
339 SMESH::DriverMED_ReadStatus res;
342 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
343 res = SMESH::DRS_OK; break;
344 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
345 res = SMESH::DRS_EMPTY; break;
346 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
347 res = SMESH::DRS_WARN_RENUMBER; break;
348 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
349 res = SMESH::DRS_WARN_SKIP_ELEM; break;
350 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
351 res = SMESH::DRS_WARN_DESCENDING; break;
352 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
354 res = SMESH::DRS_FAIL; break;
359 //=============================================================================
361 * Convert ::SMESH_ComputeError to SMESH::ComputeError
363 //=============================================================================
365 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
367 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
368 errVar->subShapeID = -1;
369 errVar->hasBadMesh = false;
371 if ( !errorPtr || errorPtr->IsOK() )
373 errVar->code = SMESH::COMPERR_OK;
377 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
378 errVar->comment = errorPtr->myComment.c_str();
380 return errVar._retn();
383 //=============================================================================
387 * Imports mesh data from MED file
389 //=============================================================================
391 SMESH::DriverMED_ReadStatus
392 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
393 throw ( SALOME::SALOME_Exception )
395 Unexpect aCatch(SALOME_SalomeException);
398 status = _impl->MEDToMesh( theFileName, theMeshName );
400 catch( SALOME_Exception& S_ex ) {
401 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
404 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
407 CreateGroupServants();
409 int major, minor, release;
410 major = minor = release = 0;
411 MED::GetMEDVersion(theFileName, major, minor, release);
412 _medFileInfo = new SMESH::MedFileInfo();
413 _medFileInfo->fileName = theFileName;
414 _medFileInfo->fileSize = 0;
415 _medFileInfo->major = major;
416 _medFileInfo->minor = minor;
417 _medFileInfo->release = release;
418 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
420 return ConvertDriverMEDReadStatus(status);
423 //================================================================================
425 * \brief Imports mesh data from the CGNS file
427 //================================================================================
429 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
430 const int theMeshIndex,
431 std::string& theMeshName )
432 throw ( SALOME::SALOME_Exception )
434 Unexpect aCatch(SALOME_SalomeException);
437 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
439 catch( SALOME_Exception& S_ex ) {
440 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
443 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
446 CreateGroupServants();
448 _medFileInfo = new SMESH::MedFileInfo();
449 _medFileInfo->fileName = theFileName;
450 _medFileInfo->major = 0;
451 _medFileInfo->minor = 0;
452 _medFileInfo->release = 0;
453 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
455 return ConvertDriverMEDReadStatus(status);
458 //================================================================================
460 * \brief Return string representation of a MED file version comprising nbDigits
462 //================================================================================
464 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
466 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
468 return CORBA::string_dup( ver.c_str() );
471 //=============================================================================
475 * Imports mesh data from MED file
477 //=============================================================================
479 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->UNVToMesh( theFileName );
487 CreateGroupServants();
489 _medFileInfo = new SMESH::MedFileInfo();
490 _medFileInfo->fileName = theFileName;
491 _medFileInfo->major = 0;
492 _medFileInfo->minor = 0;
493 _medFileInfo->release = 0;
494 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
496 SMESH_CATCH( SMESH::throwCorbaException );
501 //=============================================================================
505 * Imports mesh data from STL file
507 //=============================================================================
508 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
509 throw ( SALOME::SALOME_Exception )
513 // Read mesh with name = <theMeshName> into SMESH_Mesh
514 std::string name = _impl->STLToMesh( theFileName );
517 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
518 _gen_i->SetName( meshSO, name.c_str() );
520 _medFileInfo = new SMESH::MedFileInfo();
521 _medFileInfo->fileName = theFileName;
522 _medFileInfo->major = 0;
523 _medFileInfo->minor = 0;
524 _medFileInfo->release = 0;
525 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
527 SMESH_CATCH( SMESH::throwCorbaException );
532 //================================================================================
534 * \brief Function used in SMESH_CATCH by ImportGMFFile()
536 //================================================================================
540 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
542 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
546 //================================================================================
548 * \brief Imports data from a GMF file and returns an error description
550 //================================================================================
552 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
553 bool theMakeRequiredGroups )
554 throw (SALOME::SALOME_Exception)
556 SMESH_ComputeErrorPtr error;
559 #define SMESH_CAUGHT error =
562 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
564 _medFileInfo = new SMESH::MedFileInfo();
565 _medFileInfo->fileName = theFileName;
566 _medFileInfo->major = 0;
567 _medFileInfo->minor = 0;
568 _medFileInfo->release = 0;
569 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
571 SMESH_CATCH( exceptionToComputeError );
575 CreateGroupServants();
577 return ConvertComputeError( error );
580 //=============================================================================
584 //=============================================================================
586 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
588 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
589 (SMESH_Hypothesis::Hypothesis_Status theStatus)
592 RETURNCASE( HYP_OK );
593 RETURNCASE( HYP_MISSING );
594 RETURNCASE( HYP_CONCURRENT );
595 RETURNCASE( HYP_BAD_PARAMETER );
596 RETURNCASE( HYP_HIDDEN_ALGO );
597 RETURNCASE( HYP_HIDING_ALGO );
598 RETURNCASE( HYP_UNKNOWN_FATAL );
599 RETURNCASE( HYP_INCOMPATIBLE );
600 RETURNCASE( HYP_NOTCONFORM );
601 RETURNCASE( HYP_ALREADY_EXIST );
602 RETURNCASE( HYP_BAD_DIM );
603 RETURNCASE( HYP_BAD_SUBSHAPE );
604 RETURNCASE( HYP_BAD_GEOMETRY );
605 RETURNCASE( HYP_NEED_SHAPE );
606 RETURNCASE( HYP_INCOMPAT_HYPS );
609 return SMESH::HYP_UNKNOWN_FATAL;
612 //=============================================================================
616 * calls internal addHypothesis() and then adds a reference to <anHyp> under
617 * the SObject actually having a reference to <aSubShape>.
618 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
620 //=============================================================================
622 SMESH::Hypothesis_Status
623 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
624 SMESH::SMESH_Hypothesis_ptr anHyp,
625 CORBA::String_out anErrorText)
626 throw(SALOME::SALOME_Exception)
628 Unexpect aCatch(SALOME_SalomeException);
630 _preMeshInfo->ForgetOrLoad();
633 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
634 anErrorText = error.c_str();
636 SMESH::SMESH_Mesh_var mesh( _this() );
637 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
639 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
640 _gen_i->UpdateIcons( mesh );
642 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
644 // Update Python script
645 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
646 << aSubShape << ", " << anHyp << " )";
648 return ConvertHypothesisStatus(status);
651 //=============================================================================
655 //=============================================================================
657 SMESH_Hypothesis::Hypothesis_Status
658 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
659 SMESH::SMESH_Hypothesis_ptr anHyp,
660 std::string* anErrorText)
662 if(MYDEBUG) MESSAGE("addHypothesis");
664 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
665 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
667 if (CORBA::is_nil( anHyp ))
668 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
670 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
673 TopoDS_Shape myLocSubShape;
674 //use PseudoShape in case if mesh has no shape
676 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
678 myLocSubShape = _impl->GetShapeToMesh();
680 const int hypId = anHyp->GetId();
682 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
683 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
685 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
687 // assure there is a corresponding submesh
688 if ( !_impl->IsMainShape( myLocSubShape )) {
689 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
690 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
691 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
694 else if ( anErrorText )
696 *anErrorText = error;
699 catch(SALOME_Exception & S_ex)
701 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
706 //=============================================================================
710 //=============================================================================
712 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
713 SMESH::SMESH_Hypothesis_ptr anHyp)
714 throw(SALOME::SALOME_Exception)
716 Unexpect aCatch(SALOME_SalomeException);
718 _preMeshInfo->ForgetOrLoad();
720 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
721 SMESH::SMESH_Mesh_var mesh = _this();
723 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
725 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
726 _gen_i->UpdateIcons( mesh );
728 // Update Python script
729 if(_impl->HasShapeToMesh())
730 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
731 << aSubShape << ", " << anHyp << " )";
733 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
736 return ConvertHypothesisStatus(status);
739 //=============================================================================
743 //=============================================================================
745 SMESH_Hypothesis::Hypothesis_Status
746 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
747 SMESH::SMESH_Hypothesis_ptr anHyp)
749 if(MYDEBUG) MESSAGE("removeHypothesis()");
751 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
752 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
754 if (CORBA::is_nil( anHyp ))
755 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
757 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
760 TopoDS_Shape myLocSubShape;
761 //use PseudoShape in case if mesh has no shape
762 if( _impl->HasShapeToMesh() )
763 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
765 myLocSubShape = _impl->GetShapeToMesh();
767 const int hypId = anHyp->GetId();
768 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
769 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
771 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
775 catch(SALOME_Exception & S_ex)
777 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
782 //=============================================================================
786 //=============================================================================
788 SMESH::ListOfHypothesis *
789 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
790 throw(SALOME::SALOME_Exception)
792 Unexpect aCatch(SALOME_SalomeException);
793 if (MYDEBUG) MESSAGE("GetHypothesisList");
794 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
795 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
797 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
800 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
801 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
802 myLocSubShape = _impl->GetShapeToMesh();
803 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
804 int i = 0, n = aLocalList.size();
807 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
808 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
809 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
811 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
812 if ( id_hypptr != _mapHypo.end() )
813 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
817 catch(SALOME_Exception & S_ex) {
818 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
821 return aList._retn();
824 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
826 Unexpect aCatch(SALOME_SalomeException);
827 if (MYDEBUG) MESSAGE("GetSubMeshes");
829 SMESH::submesh_array_var aList = new SMESH::submesh_array();
832 TPythonDump aPythonDump;
833 if ( !_mapSubMeshIor.empty() )
837 aList->length( _mapSubMeshIor.size() );
839 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
840 for ( ; it != _mapSubMeshIor.end(); it++ ) {
841 if ( CORBA::is_nil( it->second )) continue;
842 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
844 if (i > 1) aPythonDump << ", ";
845 aPythonDump << it->second;
849 catch(SALOME_Exception & S_ex) {
850 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
853 // Update Python script
854 if ( !_mapSubMeshIor.empty() )
855 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
857 return aList._retn();
860 //=============================================================================
864 //=============================================================================
866 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
867 const char* theName )
868 throw(SALOME::SALOME_Exception)
870 Unexpect aCatch(SALOME_SalomeException);
871 if (CORBA::is_nil(aSubShape))
872 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
874 SMESH::SMESH_subMesh_var subMesh;
875 SMESH::SMESH_Mesh_var aMesh = _this();
877 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
879 //Get or Create the SMESH_subMesh object implementation
881 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
883 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
885 TopoDS_Iterator it( myLocSubShape );
887 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
889 subMesh = getSubMesh( subMeshId );
891 // create a new subMesh object servant if there is none for the shape
892 if ( subMesh->_is_nil() )
893 subMesh = createSubMesh( aSubShape );
894 if ( _gen_i->CanPublishInStudy( subMesh ))
896 SALOMEDS::SObject_wrap aSO =
897 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
898 if ( !aSO->_is_nil()) {
899 // Update Python script
900 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
901 << aSubShape << ", '" << theName << "' )";
905 catch(SALOME_Exception & S_ex) {
906 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
908 return subMesh._retn();
911 //=============================================================================
915 //=============================================================================
917 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
918 throw (SALOME::SALOME_Exception)
922 if ( theSubMesh->_is_nil() )
925 GEOM::GEOM_Object_var aSubShape;
926 // Remove submesh's SObject
927 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
928 if ( !anSO->_is_nil() ) {
929 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
930 SALOMEDS::SObject_wrap anObj, aRef;
931 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
932 anObj->ReferencedObject( aRef.inout() ))
934 CORBA::Object_var obj = aRef->GetObject();
935 aSubShape = GEOM::GEOM_Object::_narrow( obj );
937 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
938 // aSubShape = theSubMesh->GetSubShape();
940 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
941 builder->RemoveObjectWithChildren( anSO );
943 // Update Python script
944 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
947 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
949 _preMeshInfo->ForgetOrLoad();
951 SMESH_CATCH( SMESH::throwCorbaException );
954 //=============================================================================
958 //=============================================================================
960 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
961 const char* theName )
962 throw(SALOME::SALOME_Exception)
964 Unexpect aCatch(SALOME_SalomeException);
966 _preMeshInfo->FullLoadFromFile();
968 SMESH::SMESH_Group_var aNewGroup =
969 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
971 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
973 SMESH::SMESH_Mesh_var mesh = _this();
974 SALOMEDS::SObject_wrap aSO =
975 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
976 if ( !aSO->_is_nil())
977 // Update Python script
978 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
979 << theElemType << ", '" << theName << "' )";
981 return aNewGroup._retn();
984 //=============================================================================
988 //=============================================================================
989 SMESH::SMESH_GroupOnGeom_ptr
990 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
992 GEOM::GEOM_Object_ptr theGeomObj)
993 throw(SALOME::SALOME_Exception)
995 Unexpect aCatch(SALOME_SalomeException);
997 _preMeshInfo->FullLoadFromFile();
999 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1001 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1002 if ( !aShape.IsNull() )
1005 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
1007 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1009 SMESH::SMESH_Mesh_var mesh = _this();
1010 SALOMEDS::SObject_wrap aSO =
1011 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1012 if ( !aSO->_is_nil())
1013 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1014 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1018 return aNewGroup._retn();
1021 //================================================================================
1023 * \brief Creates a group whose contents is defined by filter
1024 * \param theElemType - group type
1025 * \param theName - group name
1026 * \param theFilter - the filter
1027 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1029 //================================================================================
1031 SMESH::SMESH_GroupOnFilter_ptr
1032 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1033 const char* theName,
1034 SMESH::Filter_ptr theFilter )
1035 throw (SALOME::SALOME_Exception)
1037 Unexpect aCatch(SALOME_SalomeException);
1039 _preMeshInfo->FullLoadFromFile();
1041 if ( CORBA::is_nil( theFilter ))
1042 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1044 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1046 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1048 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1049 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1052 if ( !aNewGroup->_is_nil() )
1053 aNewGroup->SetFilter( theFilter );
1055 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1057 SMESH::SMESH_Mesh_var mesh = _this();
1058 SALOMEDS::SObject_wrap aSO =
1059 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1061 if ( !aSO->_is_nil())
1062 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1063 << theElemType << ", '" << theName << "', " << theFilter << " )";
1065 return aNewGroup._retn();
1068 //=============================================================================
1072 //=============================================================================
1074 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1075 throw (SALOME::SALOME_Exception)
1077 if ( theGroup->_is_nil() )
1082 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1086 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1087 if ( !aGroupSO->_is_nil() )
1089 // Update Python script
1090 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1092 // Remove group's SObject
1093 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1094 builder->RemoveObjectWithChildren( aGroupSO );
1096 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1098 // Remove the group from SMESH data structures
1099 removeGroup( aGroup->GetLocalID() );
1101 SMESH_CATCH( SMESH::throwCorbaException );
1104 //=============================================================================
1106 * Remove group with its contents
1108 //=============================================================================
1110 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1111 throw (SALOME::SALOME_Exception)
1115 _preMeshInfo->FullLoadFromFile();
1117 if ( theGroup->_is_nil() )
1120 vector<int> nodeIds; // to remove nodes becoming free
1121 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1122 if ( !isNodal && !theGroup->IsEmpty() )
1124 CORBA::Long elemID = theGroup->GetID( 1 );
1125 int nbElemNodes = GetElemNbNodes( elemID );
1126 if ( nbElemNodes > 0 )
1127 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1130 // Retrieve contents
1131 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1132 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1133 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1134 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1135 elems.assign( elemBeg, elemEnd );
1137 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1140 RemoveGroup( theGroup );
1143 for ( size_t i = 0; i < elems.size(); ++i )
1145 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1149 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1150 nodeIds.push_back( nIt->next()->GetID() );
1152 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1156 _impl->GetMeshDS()->RemoveElement( elems[i] );
1160 // Remove free nodes
1161 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1162 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1163 if ( n->NbInverseElements() == 0 )
1164 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1166 // Update Python script (theGroup must be alive for this)
1167 pyDump << SMESH::SMESH_Mesh_var(_this())
1168 << ".RemoveGroupWithContents( " << theGroup << " )";
1170 SMESH_CATCH( SMESH::throwCorbaException );
1173 //================================================================================
1175 * \brief Get the list of groups existing in the mesh
1176 * \retval SMESH::ListOfGroups * - list of groups
1178 //================================================================================
1180 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1182 Unexpect aCatch(SALOME_SalomeException);
1183 if (MYDEBUG) MESSAGE("GetGroups");
1185 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1188 TPythonDump aPythonDump;
1189 if ( !_mapGroups.empty() )
1191 aPythonDump << "[ ";
1193 aList->length( _mapGroups.size() );
1195 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1196 for ( ; it != _mapGroups.end(); it++ ) {
1197 if ( CORBA::is_nil( it->second )) continue;
1198 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1200 if (i > 1) aPythonDump << ", ";
1201 aPythonDump << it->second;
1205 catch(SALOME_Exception & S_ex) {
1206 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1208 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1210 return aList._retn();
1213 //=============================================================================
1215 * Get number of groups existing in the mesh
1217 //=============================================================================
1219 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1221 Unexpect aCatch(SALOME_SalomeException);
1222 return _mapGroups.size();
1225 //=============================================================================
1227 * New group including all mesh elements present in initial groups is created.
1229 //=============================================================================
1231 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1232 SMESH::SMESH_GroupBase_ptr theGroup2,
1233 const char* theName )
1234 throw (SALOME::SALOME_Exception)
1236 SMESH::SMESH_Group_var aResGrp;
1240 _preMeshInfo->FullLoadFromFile();
1242 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1243 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1245 if ( theGroup1->GetType() != theGroup2->GetType() )
1246 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1251 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1252 if ( aResGrp->_is_nil() )
1253 return SMESH::SMESH_Group::_nil();
1255 aResGrp->AddFrom( theGroup1 );
1256 aResGrp->AddFrom( theGroup2 );
1258 // Update Python script
1259 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1260 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1262 SMESH_CATCH( SMESH::throwCorbaException );
1264 return aResGrp._retn();
1267 //=============================================================================
1269 * \brief New group including all mesh elements present in initial groups is created.
1270 * \param theGroups list of groups
1271 * \param theName name of group to be created
1272 * \return pointer to the new group
1274 //=============================================================================
1276 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1277 const char* theName )
1278 throw (SALOME::SALOME_Exception)
1280 SMESH::SMESH_Group_var aResGrp;
1283 _preMeshInfo->FullLoadFromFile();
1286 return SMESH::SMESH_Group::_nil();
1291 SMESH::ElementType aType = SMESH::ALL;
1292 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1294 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1295 if ( CORBA::is_nil( aGrp ) )
1297 if ( aType == SMESH::ALL )
1298 aType = aGrp->GetType();
1299 else if ( aType != aGrp->GetType() )
1300 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1303 if ( aType == SMESH::ALL )
1304 return SMESH::SMESH_Group::_nil();
1309 aResGrp = CreateGroup( aType, theName );
1310 if ( aResGrp->_is_nil() )
1311 return SMESH::SMESH_Group::_nil();
1313 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1314 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1316 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1317 if ( !CORBA::is_nil( aGrp ) )
1319 aResGrp->AddFrom( aGrp );
1320 if ( g > 0 ) pyDump << ", ";
1324 pyDump << " ], '" << theName << "' )";
1326 SMESH_CATCH( SMESH::throwCorbaException );
1328 return aResGrp._retn();
1331 //=============================================================================
1333 * New group is created. All mesh elements that are
1334 * present in both initial groups are added to the new one.
1336 //=============================================================================
1338 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1339 SMESH::SMESH_GroupBase_ptr theGroup2,
1340 const char* theName )
1341 throw (SALOME::SALOME_Exception)
1343 SMESH::SMESH_Group_var aResGrp;
1348 _preMeshInfo->FullLoadFromFile();
1350 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1351 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1353 if ( theGroup1->GetType() != theGroup2->GetType() )
1354 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1358 // Create Intersection
1359 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1360 if ( aResGrp->_is_nil() )
1361 return aResGrp._retn();
1363 SMESHDS_GroupBase* groupDS1 = 0;
1364 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1365 groupDS1 = grp_i->GetGroupDS();
1367 SMESHDS_GroupBase* groupDS2 = 0;
1368 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1369 groupDS2 = grp_i->GetGroupDS();
1371 SMESHDS_Group* resGroupDS = 0;
1372 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1373 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1375 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1377 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1378 while ( elemIt1->more() )
1380 const SMDS_MeshElement* e = elemIt1->next();
1381 if ( groupDS2->Contains( e ))
1382 resGroupDS->SMDSGroup().Add( e );
1385 // Update Python script
1386 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1387 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1389 SMESH_CATCH( SMESH::throwCorbaException );
1391 return aResGrp._retn();
1394 //=============================================================================
1396 \brief Intersect list of groups. New group is created. All mesh elements that
1397 are present in all initial groups simultaneously are added to the new one.
1398 \param theGroups list of groups
1399 \param theName name of group to be created
1400 \return pointer on the group
1402 //=============================================================================
1403 SMESH::SMESH_Group_ptr
1404 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1405 const char* theName )
1406 throw (SALOME::SALOME_Exception)
1408 SMESH::SMESH_Group_var aResGrp;
1413 _preMeshInfo->FullLoadFromFile();
1416 return SMESH::SMESH_Group::_nil();
1418 // check types and get SMESHDS_GroupBase's
1419 SMESH::ElementType aType = SMESH::ALL;
1420 vector< SMESHDS_GroupBase* > groupVec;
1421 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1423 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1424 if ( CORBA::is_nil( aGrp ) )
1426 if ( aType == SMESH::ALL )
1427 aType = aGrp->GetType();
1428 else if ( aType != aGrp->GetType() )
1429 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1432 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1433 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1435 if ( grpDS->IsEmpty() )
1440 groupVec.push_back( grpDS );
1443 if ( aType == SMESH::ALL ) // all groups are nil
1444 return SMESH::SMESH_Group::_nil();
1449 aResGrp = CreateGroup( aType, theName );
1451 SMESHDS_Group* resGroupDS = 0;
1452 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1453 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1454 if ( !resGroupDS || groupVec.empty() )
1455 return aResGrp._retn();
1458 size_t i, nb = groupVec.size();
1459 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1460 while ( elemIt1->more() )
1462 const SMDS_MeshElement* e = elemIt1->next();
1464 for ( i = 1; ( i < nb && inAll ); ++i )
1465 inAll = groupVec[i]->Contains( e );
1468 resGroupDS->SMDSGroup().Add( e );
1471 // Update Python script
1472 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1473 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1475 SMESH_CATCH( SMESH::throwCorbaException );
1477 return aResGrp._retn();
1480 //=============================================================================
1482 * New group is created. All mesh elements that are present in
1483 * a main group but is not present in a tool group are added to the new one
1485 //=============================================================================
1487 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1488 SMESH::SMESH_GroupBase_ptr theGroup2,
1489 const char* theName )
1490 throw (SALOME::SALOME_Exception)
1492 SMESH::SMESH_Group_var aResGrp;
1497 _preMeshInfo->FullLoadFromFile();
1499 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1500 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1502 if ( theGroup1->GetType() != theGroup2->GetType() )
1503 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1507 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1508 if ( aResGrp->_is_nil() )
1509 return aResGrp._retn();
1511 SMESHDS_GroupBase* groupDS1 = 0;
1512 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1513 groupDS1 = grp_i->GetGroupDS();
1515 SMESHDS_GroupBase* groupDS2 = 0;
1516 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1517 groupDS2 = grp_i->GetGroupDS();
1519 SMESHDS_Group* resGroupDS = 0;
1520 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1521 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1523 if ( groupDS1 && groupDS2 && resGroupDS )
1525 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1526 while ( elemIt1->more() )
1528 const SMDS_MeshElement* e = elemIt1->next();
1529 if ( !groupDS2->Contains( e ))
1530 resGroupDS->SMDSGroup().Add( e );
1533 // Update Python script
1534 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1535 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1537 SMESH_CATCH( SMESH::throwCorbaException );
1539 return aResGrp._retn();
1542 //=============================================================================
1544 \brief Cut lists of groups. New group is created. All mesh elements that are
1545 present in main groups but do not present in tool groups are added to the new one
1546 \param theMainGroups list of main groups
1547 \param theToolGroups list of tool groups
1548 \param theName name of group to be created
1549 \return pointer on the group
1551 //=============================================================================
1552 SMESH::SMESH_Group_ptr
1553 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1554 const SMESH::ListOfGroups& theToolGroups,
1555 const char* theName )
1556 throw (SALOME::SALOME_Exception)
1558 SMESH::SMESH_Group_var aResGrp;
1563 _preMeshInfo->FullLoadFromFile();
1566 return SMESH::SMESH_Group::_nil();
1568 // check types and get SMESHDS_GroupBase's
1569 SMESH::ElementType aType = SMESH::ALL;
1570 vector< SMESHDS_GroupBase* > toolGroupVec;
1571 vector< SMDS_ElemIteratorPtr > mainIterVec;
1573 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1575 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1576 if ( CORBA::is_nil( aGrp ) )
1578 if ( aType == SMESH::ALL )
1579 aType = aGrp->GetType();
1580 else if ( aType != aGrp->GetType() )
1581 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1583 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1584 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1585 if ( !grpDS->IsEmpty() )
1586 mainIterVec.push_back( grpDS->GetElements() );
1588 if ( aType == SMESH::ALL ) // all main groups are nil
1589 return SMESH::SMESH_Group::_nil();
1590 if ( mainIterVec.empty() ) // all main groups are empty
1591 return aResGrp._retn();
1593 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1595 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1596 if ( CORBA::is_nil( aGrp ) )
1598 if ( aType != aGrp->GetType() )
1599 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1601 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1602 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1603 toolGroupVec.push_back( grpDS );
1609 aResGrp = CreateGroup( aType, theName );
1611 SMESHDS_Group* resGroupDS = 0;
1612 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1613 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1615 return aResGrp._retn();
1618 size_t i, nb = toolGroupVec.size();
1619 SMDS_ElemIteratorPtr mainElemIt
1620 ( new SMDS_IteratorOnIterators
1621 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1622 while ( mainElemIt->more() )
1624 const SMDS_MeshElement* e = mainElemIt->next();
1626 for ( i = 0; ( i < nb && !isIn ); ++i )
1627 isIn = toolGroupVec[i]->Contains( e );
1630 resGroupDS->SMDSGroup().Add( e );
1633 // Update Python script
1634 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1635 << ".CutListOfGroups( " << theMainGroups << ", "
1636 << theToolGroups << ", '" << theName << "' )";
1638 SMESH_CATCH( SMESH::throwCorbaException );
1640 return aResGrp._retn();
1643 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1645 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1646 bool & toStopChecking )
1648 toStopChecking = ( nbCommon < nbChecked );
1649 return nbCommon == nbNodes;
1651 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1652 bool & toStopChecking )
1654 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1655 return nbCommon == nbCorners;
1657 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1658 bool & toStopChecking )
1660 return nbCommon > 0;
1662 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1663 bool & toStopChecking )
1665 return nbCommon >= (nbNodes+1) / 2;
1669 //=============================================================================
1671 * Create a group of entities basing on nodes of other groups.
1672 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1673 * \param [in] anElemType - a type of elements to include to the new group.
1674 * \param [in] theName - a name of the new group.
1675 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1676 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1677 * new group provided that it is based on nodes of an element of \a aListOfGroups
1678 * \return SMESH_Group - the created group
1680 // IMP 19939, bug 22010, IMP 22635
1681 //=============================================================================
1683 SMESH::SMESH_Group_ptr
1684 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1685 SMESH::ElementType theElemType,
1686 const char* theName,
1687 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1688 CORBA::Boolean theUnderlyingOnly)
1689 throw (SALOME::SALOME_Exception)
1691 SMESH::SMESH_Group_var aResGrp;
1695 _preMeshInfo->FullLoadFromFile();
1697 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1699 if ( !theName || !aMeshDS )
1700 return SMESH::SMESH_Group::_nil();
1702 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1704 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1705 SMESH_Comment nbCoNoStr( "SMESH.");
1706 switch ( theNbCommonNodes ) {
1707 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1708 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1709 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1710 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1711 default: return aResGrp._retn();
1713 int nbChecked, nbCommon, nbNodes, nbCorners;
1719 aResGrp = CreateGroup( theElemType, theName );
1720 if ( aResGrp->_is_nil() )
1721 return SMESH::SMESH_Group::_nil();
1723 SMESHDS_GroupBase* groupBaseDS =
1724 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1725 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1727 vector<bool> isNodeInGroups;
1729 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1731 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1732 if ( CORBA::is_nil( aGrp ) )
1734 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1735 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1738 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1739 if ( !elIt ) continue;
1741 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1743 while ( elIt->more() ) {
1744 const SMDS_MeshElement* el = elIt->next();
1745 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1746 while ( nIt->more() )
1747 resGroupCore.Add( nIt->next() );
1750 // get elements of theElemType based on nodes of every element of group
1751 else if ( theUnderlyingOnly )
1753 while ( elIt->more() )
1755 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1756 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1757 TIDSortedElemSet checkedElems;
1758 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1759 while ( nIt->more() )
1761 const SMDS_MeshNode* n = nIt->next();
1762 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1763 // check nodes of elements of theElemType around el
1764 while ( elOfTypeIt->more() )
1766 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1767 if ( !checkedElems.insert( elOfType ).second ) continue;
1768 nbNodes = elOfType->NbNodes();
1769 nbCorners = elOfType->NbCornerNodes();
1771 bool toStopChecking = false;
1772 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1773 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1774 if ( elNodes.count( nIt2->next() ) &&
1775 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1777 resGroupCore.Add( elOfType );
1784 // get all nodes of elements of groups
1787 while ( elIt->more() )
1789 const SMDS_MeshElement* el = elIt->next(); // an element of group
1790 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1791 while ( nIt->more() )
1793 const SMDS_MeshNode* n = nIt->next();
1794 if ( n->GetID() >= (int) isNodeInGroups.size() )
1795 isNodeInGroups.resize( n->GetID() + 1, false );
1796 isNodeInGroups[ n->GetID() ] = true;
1802 // Get elements of theElemType based on a certain number of nodes of elements of groups
1803 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1805 const SMDS_MeshNode* n;
1806 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1807 const int isNodeInGroupsSize = isNodeInGroups.size();
1808 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1810 if ( !isNodeInGroups[ iN ] ||
1811 !( n = aMeshDS->FindNode( iN )))
1814 // check nodes of elements of theElemType around n
1815 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1816 while ( elOfTypeIt->more() )
1818 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1819 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1824 nbNodes = elOfType->NbNodes();
1825 nbCorners = elOfType->NbCornerNodes();
1827 bool toStopChecking = false;
1828 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1829 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1831 const int nID = nIt->next()->GetID();
1832 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1833 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1835 resGroupCore.Add( elOfType );
1843 // Update Python script
1844 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1845 << ".CreateDimGroup( "
1846 << theGroups << ", " << theElemType << ", '" << theName << "', "
1847 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1849 SMESH_CATCH( SMESH::throwCorbaException );
1851 return aResGrp._retn();
1854 //================================================================================
1856 * \brief Remember GEOM group data
1858 //================================================================================
1860 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1861 CORBA::Object_ptr theSmeshObj)
1863 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1866 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
1867 if ( groupSO->_is_nil() )
1870 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1871 GEOM::GEOM_IGroupOperations_wrap groupOp =
1872 geomGen->GetIGroupOperations();
1873 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1876 _geomGroupData.push_back( TGeomGroupData() );
1877 TGeomGroupData & groupData = _geomGroupData.back();
1879 CORBA::String_var entry = groupSO->GetID();
1880 groupData._groupEntry = entry.in();
1882 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1883 groupData._indices.insert( ids[i] );
1885 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1886 // shape index in SMESHDS
1887 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1888 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1891 //================================================================================
1893 * Remove GEOM group data relating to removed smesh object
1895 //================================================================================
1897 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1899 list<TGeomGroupData>::iterator
1900 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1901 for ( ; data != dataEnd; ++data ) {
1902 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1903 _geomGroupData.erase( data );
1909 //================================================================================
1911 * \brief Return new group contents if it has been changed and update group data
1913 //================================================================================
1915 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1917 TopoDS_Shape newShape;
1920 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
1921 if ( !groupSO->_is_nil() )
1923 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1924 if ( CORBA::is_nil( groupObj )) return newShape;
1925 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1927 // get indices of group items
1928 set<int> curIndices;
1929 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1930 GEOM::GEOM_IGroupOperations_wrap groupOp =
1931 geomGen->GetIGroupOperations();
1932 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1933 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
1934 curIndices.insert( ids[i] );
1936 if ( groupData._indices == curIndices )
1937 return newShape; // group not changed
1940 groupData._indices = curIndices;
1942 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1943 if ( !geomClient ) return newShape;
1944 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1945 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1946 newShape = _gen_i->GeomObjectToShape( geomGroup );
1949 if ( newShape.IsNull() ) {
1950 // geom group becomes empty - return empty compound
1951 TopoDS_Compound compound;
1952 BRep_Builder().MakeCompound(compound);
1953 newShape = compound;
1960 //-----------------------------------------------------------------------------
1962 * \brief Storage of shape and index used in CheckGeomGroupModif()
1964 struct TIndexedShape
1967 TopoDS_Shape _shape;
1968 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1970 //-----------------------------------------------------------------------------
1972 * \brief Data to re-create a group on geometry
1974 struct TGroupOnGeomData
1978 SMDSAbs_ElementType _type;
1980 Quantity_Color _color;
1984 //=============================================================================
1986 * \brief Update data if geometry changes
1990 //=============================================================================
1992 void SMESH_Mesh_i::CheckGeomModif()
1994 if ( !_impl->HasShapeToMesh() ) return;
1996 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1997 //if ( mainGO->_is_nil() ) return;
1999 // Update after group modification
2001 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
2002 called by other mesh (IPAL52735) */
2003 mainGO->GetType() == GEOM_GROUP ||
2004 mainGO->GetTick() == _mainShapeTick )
2006 CheckGeomGroupModif();
2010 // Update after shape transformation like Translate
2012 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2013 if ( !geomClient ) return;
2014 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
2015 if ( geomGen->_is_nil() ) return;
2017 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2018 geomClient->RemoveShapeFromBuffer( ior.in() );
2020 // Update data taking into account that
2021 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2024 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2025 if ( newShape.IsNull() )
2028 _mainShapeTick = mainGO->GetTick();
2030 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2032 // store data of groups on geometry
2033 vector< TGroupOnGeomData > groupsData;
2034 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2035 groupsData.reserve( groups.size() );
2036 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2037 for ( ; g != groups.end(); ++g )
2038 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2040 TGroupOnGeomData data;
2041 data._oldID = group->GetID();
2042 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2043 data._type = group->GetType();
2044 data._name = group->GetStoreName();
2045 data._color = group->GetColor();
2046 groupsData.push_back( data );
2048 // store assigned hypotheses
2049 vector< pair< int, THypList > > ids2Hyps;
2050 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2051 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2053 const TopoDS_Shape& s = s2hyps.Key();
2054 const THypList& hyps = s2hyps.ChangeValue();
2055 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2058 // change shape to mesh
2059 int oldNbSubShapes = meshDS->MaxShapeIndex();
2060 _impl->ShapeToMesh( TopoDS_Shape() );
2061 _impl->ShapeToMesh( newShape );
2063 // re-add shapes of geom groups
2064 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2065 for ( ; data != _geomGroupData.end(); ++data )
2067 TopoDS_Shape newShape = newGroupShape( *data );
2068 if ( !newShape.IsNull() )
2070 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2072 TopoDS_Compound compound;
2073 BRep_Builder().MakeCompound( compound );
2074 BRep_Builder().Add( compound, newShape );
2075 newShape = compound;
2077 _impl->GetSubMesh( newShape );
2080 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2081 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2082 SALOME::INTERNAL_ERROR );
2084 // re-assign hypotheses
2085 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2087 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2088 const THypList& hyps = ids2Hyps[i].second;
2089 THypList::const_iterator h = hyps.begin();
2090 for ( ; h != hyps.end(); ++h )
2091 _impl->AddHypothesis( s, (*h)->GetID() );
2095 for ( size_t i = 0; i < groupsData.size(); ++i )
2097 const TGroupOnGeomData& data = groupsData[i];
2099 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2100 if ( i2g == _mapGroups.end() ) continue;
2102 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2103 if ( !gr_i ) continue;
2106 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2107 meshDS->IndexToShape( data._shapeID ));
2110 _mapGroups.erase( i2g );
2114 g->GetGroupDS()->SetColor( data._color );
2115 gr_i->changeLocalId( id );
2116 _mapGroups[ id ] = i2g->second;
2117 if ( data._oldID != id )
2118 _mapGroups.erase( i2g );
2122 // update _mapSubMesh
2123 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2124 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2125 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2129 //=============================================================================
2131 * \brief Update objects depending on changed geom groups
2133 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2134 * issue 0020210: Update of a smesh group after modification of the associated geom group
2136 //=============================================================================
2138 void SMESH_Mesh_i::CheckGeomGroupModif()
2140 if ( !_impl->HasShapeToMesh() ) return;
2142 CORBA::Long nbEntities = NbNodes() + NbElements();
2144 // Check if group contents changed
2146 typedef map< string, TopoDS_Shape > TEntry2Geom;
2147 TEntry2Geom newGroupContents;
2149 list<TGeomGroupData>::iterator
2150 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2151 for ( ; data != dataEnd; ++data )
2153 pair< TEntry2Geom::iterator, bool > it_new =
2154 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2155 bool processedGroup = !it_new.second;
2156 TopoDS_Shape& newShape = it_new.first->second;
2157 if ( !processedGroup )
2158 newShape = newGroupShape( *data );
2159 if ( newShape.IsNull() )
2160 continue; // no changes
2163 _preMeshInfo->ForgetOrLoad();
2165 if ( processedGroup ) { // update group indices
2166 list<TGeomGroupData>::iterator data2 = data;
2167 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2168 data->_indices = data2->_indices;
2171 // Update SMESH objects according to new GEOM group contents
2173 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2174 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2176 int oldID = submesh->GetId();
2177 if ( !_mapSubMeshIor.count( oldID ))
2179 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2181 // update hypotheses
2182 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2183 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2184 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2186 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2187 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2189 // care of submeshes
2190 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2191 int newID = newSubmesh->GetId();
2192 if ( newID != oldID ) {
2193 _mapSubMesh [ newID ] = newSubmesh;
2194 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2195 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2196 _mapSubMesh. erase(oldID);
2197 _mapSubMesh_i. erase(oldID);
2198 _mapSubMeshIor.erase(oldID);
2199 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2204 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2205 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2206 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2208 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2210 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2211 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2212 ds->SetShape( newShape );
2217 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2218 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2220 // Remove groups and submeshes basing on removed sub-shapes
2222 TopTools_MapOfShape newShapeMap;
2223 TopoDS_Iterator shapeIt( newShape );
2224 for ( ; shapeIt.More(); shapeIt.Next() )
2225 newShapeMap.Add( shapeIt.Value() );
2227 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2228 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2230 if ( newShapeMap.Contains( shapeIt.Value() ))
2232 TopTools_IndexedMapOfShape oldShapeMap;
2233 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2234 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2236 const TopoDS_Shape& oldShape = oldShapeMap(i);
2237 int oldInd = meshDS->ShapeToIndex( oldShape );
2239 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2240 if ( i_smIor != _mapSubMeshIor.end() ) {
2241 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2244 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2245 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2247 // check if a group bases on oldInd shape
2248 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2249 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2250 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2251 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2253 RemoveGroup( i_grp->second ); // several groups can base on same shape
2254 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2259 // Reassign hypotheses and update groups after setting the new shape to mesh
2261 // collect anassigned hypotheses
2262 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2263 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2264 TShapeHypList assignedHyps;
2265 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2267 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2268 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2269 if ( !hyps.empty() ) {
2270 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2271 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2272 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2275 // collect shapes supporting groups
2276 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2277 TShapeTypeList groupData;
2278 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2279 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2280 for ( ; grIt != groups.end(); ++grIt )
2282 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2284 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2286 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2288 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2289 _impl->ShapeToMesh( newShape );
2291 // reassign hypotheses
2292 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2293 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2295 TIndexedShape& geom = indS_hyps->first;
2296 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2297 int oldID = geom._index;
2298 int newID = meshDS->ShapeToIndex( geom._shape );
2299 if ( oldID == 1 ) { // main shape
2301 geom._shape = newShape;
2305 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2306 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2307 // care of sub-meshes
2308 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2309 if ( newID != oldID ) {
2310 _mapSubMesh [ newID ] = newSubmesh;
2311 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2312 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2313 _mapSubMesh. erase(oldID);
2314 _mapSubMesh_i. erase(oldID);
2315 _mapSubMeshIor.erase(oldID);
2316 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2320 TShapeTypeList::iterator geomType = groupData.begin();
2321 for ( ; geomType != groupData.end(); ++geomType )
2323 const TIndexedShape& geom = geomType->first;
2324 int oldID = geom._index;
2325 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2328 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2329 CORBA::String_var name = groupSO->GetName();
2331 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2333 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2334 group_i->changeLocalId( newID );
2337 break; // everything has been updated
2340 } // loop on group data
2344 CORBA::Long newNbEntities = NbNodes() + NbElements();
2345 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2346 if ( newNbEntities != nbEntities )
2348 // Add all SObjects with icons to soToUpdateIcons
2349 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2351 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2352 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2353 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2355 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2356 i_gr != _mapGroups.end(); ++i_gr ) // groups
2357 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2360 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2361 for ( ; so != soToUpdateIcons.end(); ++so )
2362 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2365 //=============================================================================
2367 * \brief Create standalone group from a group on geometry or filter
2369 //=============================================================================
2371 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2372 throw (SALOME::SALOME_Exception)
2374 SMESH::SMESH_Group_var aGroup;
2379 _preMeshInfo->FullLoadFromFile();
2381 if ( theGroup->_is_nil() )
2382 return aGroup._retn();
2384 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2386 return aGroup._retn();
2388 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2390 const int anId = aGroupToRem->GetLocalID();
2391 if ( !_impl->ConvertToStandalone( anId ) )
2392 return aGroup._retn();
2393 removeGeomGroupData( theGroup );
2395 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2397 // remove old instance of group from own map
2398 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2399 _mapGroups.erase( anId );
2401 SALOMEDS::StudyBuilder_var builder;
2402 SALOMEDS::SObject_wrap aGroupSO;
2403 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2404 if ( !aStudy->_is_nil() ) {
2405 builder = aStudy->NewBuilder();
2406 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2407 if ( !aGroupSO->_is_nil() )
2409 // remove reference to geometry
2410 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2411 for ( ; chItr->More(); chItr->Next() )
2412 // Remove group's child SObject
2413 builder->RemoveObject( chItr->Value() );
2415 // Update Python script
2416 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2417 << ".ConvertToStandalone( " << aGroupSO << " )";
2419 // change icon of Group on Filter
2422 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2423 const int isEmpty = ( elemTypes->length() == 0 );
2426 SALOMEDS::GenericAttribute_wrap anAttr =
2427 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2428 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2429 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2435 // remember new group in own map
2436 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2437 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2439 // register CORBA object for persistence
2440 _gen_i->RegisterObject( aGroup );
2442 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2443 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2444 //aGroup->Register();
2445 aGroupToRem->UnRegister();
2447 SMESH_CATCH( SMESH::throwCorbaException );
2449 return aGroup._retn();
2452 //=============================================================================
2456 //=============================================================================
2458 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2460 if(MYDEBUG) MESSAGE( "createSubMesh" );
2461 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2462 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2465 SMESH_subMesh_i * subMeshServant;
2468 subMeshId = mySubMesh->GetId();
2469 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2471 else // "invalid sub-mesh"
2473 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2474 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2475 if ( _mapSubMesh.empty() )
2478 subMeshId = _mapSubMesh.begin()->first - 1;
2479 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2482 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2484 _mapSubMesh [subMeshId] = mySubMesh;
2485 _mapSubMesh_i [subMeshId] = subMeshServant;
2486 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2488 subMeshServant->Register();
2490 // register CORBA object for persistence
2491 int nextId = _gen_i->RegisterObject( subMesh );
2492 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2493 else { nextId = 0; } // avoid "unused variable" warning
2495 // to track changes of GEOM groups
2496 if ( subMeshId > 0 )
2497 addGeomGroupData( theSubShapeObject, subMesh );
2499 return subMesh._retn();
2502 //=======================================================================
2503 //function : getSubMesh
2505 //=======================================================================
2507 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2509 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2510 if ( it == _mapSubMeshIor.end() )
2511 return SMESH::SMESH_subMesh::_nil();
2513 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2516 //=============================================================================
2520 //=============================================================================
2522 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2523 GEOM::GEOM_Object_ptr theSubShapeObject )
2525 bool isHypChanged = false;
2526 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2527 return isHypChanged;
2529 const int subMeshId = theSubMesh->GetId();
2531 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2533 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end() &&
2534 _mapSubMesh[ subMeshId ])
2536 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2539 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2540 isHypChanged = !hyps.empty();
2541 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2542 for ( ; hyp != hyps.end(); ++hyp )
2543 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2550 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2551 isHypChanged = ( aHypList->length() > 0 );
2552 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2553 removeHypothesis( theSubShapeObject, aHypList[i] );
2556 catch( const SALOME::SALOME_Exception& ) {
2557 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2559 removeGeomGroupData( theSubShapeObject );
2563 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2564 if ( id_smi != _mapSubMesh_i.end() )
2565 id_smi->second->UnRegister();
2567 // remove a CORBA object
2568 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2569 if ( id_smptr != _mapSubMeshIor.end() )
2570 SMESH::SMESH_subMesh_var( id_smptr->second );
2572 _mapSubMesh.erase(subMeshId);
2573 _mapSubMesh_i.erase(subMeshId);
2574 _mapSubMeshIor.erase(subMeshId);
2576 return isHypChanged;
2579 //=============================================================================
2583 //=============================================================================
2585 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2586 const char* theName,
2587 const TopoDS_Shape& theShape,
2588 const SMESH_PredicatePtr& thePredicate )
2590 std::string newName;
2591 if ( !theName || !theName[0] )
2593 std::set< std::string > presentNames;
2594 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2595 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2597 CORBA::String_var name = i_gr->second->GetName();
2598 presentNames.insert( name.in() );
2601 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2602 } while ( !presentNames.insert( newName ).second );
2603 theName = newName.c_str();
2606 SMESH::SMESH_GroupBase_var aGroup;
2607 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2609 SMESH_GroupBase_i* aGroupImpl;
2610 if ( !theShape.IsNull() )
2611 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2612 else if ( thePredicate )
2613 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2615 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2617 aGroup = aGroupImpl->_this();
2618 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2619 aGroupImpl->Register();
2621 // register CORBA object for persistence
2622 int nextId = _gen_i->RegisterObject( aGroup );
2623 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2624 else { nextId = 0; } // avoid "unused variable" warning in release mode
2626 // to track changes of GEOM groups
2627 if ( !theShape.IsNull() ) {
2628 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2629 addGeomGroupData( geom, aGroup );
2632 return aGroup._retn();
2635 //=============================================================================
2637 * SMESH_Mesh_i::removeGroup
2639 * Should be called by ~SMESH_Group_i()
2641 //=============================================================================
2643 void SMESH_Mesh_i::removeGroup( const int theId )
2645 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2646 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2647 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2648 _mapGroups.erase( theId );
2649 removeGeomGroupData( group );
2650 if ( !_impl->RemoveGroup( theId ))
2652 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2653 RemoveGroup( group );
2655 group->UnRegister();
2659 //=============================================================================
2663 //=============================================================================
2665 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2666 throw(SALOME::SALOME_Exception)
2668 SMESH::log_array_var aLog;
2672 _preMeshInfo->FullLoadFromFile();
2674 list < SMESHDS_Command * >logDS = _impl->GetLog();
2675 aLog = new SMESH::log_array;
2677 int lg = logDS.size();
2680 list < SMESHDS_Command * >::iterator its = logDS.begin();
2681 while(its != logDS.end()){
2682 SMESHDS_Command *com = *its;
2683 int comType = com->GetType();
2685 int lgcom = com->GetNumber();
2687 const list < int >&intList = com->GetIndexes();
2688 int inum = intList.size();
2690 list < int >::const_iterator ii = intList.begin();
2691 const list < double >&coordList = com->GetCoords();
2692 int rnum = coordList.size();
2694 list < double >::const_iterator ir = coordList.begin();
2695 aLog[indexLog].commandType = comType;
2696 aLog[indexLog].number = lgcom;
2697 aLog[indexLog].coords.length(rnum);
2698 aLog[indexLog].indexes.length(inum);
2699 for(int i = 0; i < rnum; i++){
2700 aLog[indexLog].coords[i] = *ir;
2701 //MESSAGE(" "<<i<<" "<<ir.Value());
2704 for(int i = 0; i < inum; i++){
2705 aLog[indexLog].indexes[i] = *ii;
2706 //MESSAGE(" "<<i<<" "<<ii.Value());
2715 SMESH_CATCH( SMESH::throwCorbaException );
2717 return aLog._retn();
2721 //=============================================================================
2725 //=============================================================================
2727 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2731 SMESH_CATCH( SMESH::throwCorbaException );
2734 //=============================================================================
2738 //=============================================================================
2740 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2745 //=============================================================================
2748 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2749 // issue 0020918: groups removal is caused by hyp modification
2750 // issue 0021208: to forget not loaded mesh data at hyp modification
2751 struct TCallUp_i : public SMESH_Mesh::TCallUp
2753 SMESH_Mesh_i* _mesh;
2754 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2755 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2756 virtual void HypothesisModified (int theHypID) { _mesh->onHypothesisModified( theHypID ); }
2757 virtual void Load () { _mesh->Load(); }
2761 //================================================================================
2763 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2765 //================================================================================
2767 void SMESH_Mesh_i::onHypothesisModified(int theHypID)
2770 _preMeshInfo->ForgetOrLoad();
2772 SMESH::SMESH_Mesh_var mesh = _this();
2773 _gen_i->UpdateIcons( mesh );
2775 // mark a hypothesis as valid after edition
2776 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
2777 SALOMEDS::SObject_wrap hypRoot;
2778 if ( !smeshComp->_is_nil() &&
2779 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
2781 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
2782 for ( ; anIter->More(); anIter->Next() )
2784 SALOMEDS::SObject_wrap hypSO = anIter->Value();
2785 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
2786 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
2787 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
2788 _gen_i->HighLightInvalid( hyp, false );
2793 //=============================================================================
2797 //=============================================================================
2799 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2801 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2804 _impl->SetCallUp( new TCallUp_i(this));
2807 //=============================================================================
2811 //=============================================================================
2813 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2815 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2819 //=============================================================================
2821 * Return mesh editor
2823 //=============================================================================
2825 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2826 throw (SALOME::SALOME_Exception)
2828 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2832 _preMeshInfo->FullLoadFromFile();
2834 // Create MeshEditor
2836 _editor = new SMESH_MeshEditor_i( this, false );
2837 aMeshEdVar = _editor->_this();
2839 // Update Python script
2840 TPythonDump() << _editor << " = "
2841 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2843 SMESH_CATCH( SMESH::throwCorbaException );
2845 return aMeshEdVar._retn();
2848 //=============================================================================
2850 * Return mesh edition previewer
2852 //=============================================================================
2854 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2855 throw (SALOME::SALOME_Exception)
2857 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2861 _preMeshInfo->FullLoadFromFile();
2863 if ( !_previewEditor )
2864 _previewEditor = new SMESH_MeshEditor_i( this, true );
2865 aMeshEdVar = _previewEditor->_this();
2867 SMESH_CATCH( SMESH::throwCorbaException );
2869 return aMeshEdVar._retn();
2872 //================================================================================
2874 * \brief Return true if the mesh has been edited since a last total re-compute
2875 * and those modifications may prevent successful partial re-compute
2877 //================================================================================
2879 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2881 Unexpect aCatch(SALOME_SalomeException);
2882 return _impl->HasModificationsToDiscard();
2885 //================================================================================
2887 * \brief Returns a random unique color
2889 //================================================================================
2891 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2893 const int MAX_ATTEMPTS = 100;
2895 double tolerance = 0.5;
2896 SALOMEDS::Color col;
2900 // generate random color
2901 double red = (double)rand() / RAND_MAX;
2902 double green = (double)rand() / RAND_MAX;
2903 double blue = (double)rand() / RAND_MAX;
2904 // check existence in the list of the existing colors
2905 bool matched = false;
2906 std::list<SALOMEDS::Color>::const_iterator it;
2907 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2908 SALOMEDS::Color color = *it;
2909 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2910 matched = tol < tolerance;
2912 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2913 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2921 //=============================================================================
2923 * Sets auto-color mode. If it is on, groups get unique random colors
2925 //=============================================================================
2927 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2929 Unexpect aCatch(SALOME_SalomeException);
2930 _impl->SetAutoColor(theAutoColor);
2932 TPythonDump pyDump; // not to dump group->SetColor() from below code
2933 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2935 std::list<SALOMEDS::Color> aReservedColors;
2936 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2937 for ( ; it != _mapGroups.end(); it++ ) {
2938 if ( CORBA::is_nil( it->second )) continue;
2939 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2940 it->second->SetColor( aColor );
2941 aReservedColors.push_back( aColor );
2945 //=============================================================================
2947 * Returns true if auto-color mode is on
2949 //=============================================================================
2951 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2953 Unexpect aCatch(SALOME_SalomeException);
2954 return _impl->GetAutoColor();
2957 //=============================================================================
2959 * Checks if there are groups with equal names
2961 //=============================================================================
2963 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2965 return _impl->HasDuplicatedGroupNamesMED();
2968 //================================================================================
2970 * \brief Care of a file before exporting mesh into it
2972 //================================================================================
2974 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2976 SMESH_File aFile( file );
2978 if (aFile.exists()) {
2979 // existing filesystem node
2980 if ( !aFile.isDirectory() ) {
2981 if ( aFile.openForWriting() ) {
2982 if ( overwrite && ! aFile.remove()) {
2983 msg << "Can't replace " << aFile.getName();
2986 msg << "Can't write into " << aFile.getName();
2989 msg << "Location " << aFile.getName() << " is not a file";
2993 // nonexisting file; check if it can be created
2994 if ( !aFile.openForWriting() ) {
2995 msg << "You cannot create the file "
2997 << ". Check the directory existence and access rights";
3005 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3009 //================================================================================
3011 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3012 * \param file - file name
3013 * \param overwrite - to erase the file or not
3014 * \retval string - mesh name
3016 //================================================================================
3018 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3019 CORBA::Boolean overwrite)
3022 PrepareForWriting(file, overwrite);
3023 string aMeshName = "Mesh";
3024 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3025 if ( !aStudy->_is_nil() ) {
3026 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3027 if ( !aMeshSO->_is_nil() ) {
3028 CORBA::String_var name = aMeshSO->GetName();
3030 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3031 if ( !aStudy->GetProperties()->IsLocked() )
3033 SALOMEDS::GenericAttribute_wrap anAttr;
3034 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3035 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3036 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3037 ASSERT(!aFileName->_is_nil());
3038 aFileName->SetValue(file);
3039 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3040 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3041 ASSERT(!aFileType->_is_nil());
3042 aFileType->SetValue("FICHIERMED");
3046 // Update Python script
3047 // set name of mesh before export
3048 TPythonDump() << _gen_i << ".SetName("
3049 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3051 // check names of groups
3057 //================================================================================
3059 * \brief Export to MED file
3061 //================================================================================
3063 void SMESH_Mesh_i::ExportMED(const char* file,
3064 CORBA::Boolean auto_groups,
3066 CORBA::Boolean overwrite,
3067 CORBA::Boolean autoDimension)
3068 throw(SALOME::SALOME_Exception)
3070 //MESSAGE("MED minor version: "<< minor);
3073 _preMeshInfo->FullLoadFromFile();
3075 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3076 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor, 0, autoDimension );
3078 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3080 << "auto_groups=" <<auto_groups << ", "
3081 << "minor=" << minor << ", "
3082 << "overwrite=" << overwrite << ", "
3083 << "meshPart=None, "
3084 << "autoDimension=" << autoDimension << " )";
3086 SMESH_CATCH( SMESH::throwCorbaException );
3089 //================================================================================
3091 * \brief Export a mesh to a SAUV file
3093 //================================================================================
3095 void SMESH_Mesh_i::ExportSAUV (const char* file,
3096 CORBA::Boolean auto_groups)
3097 throw(SALOME::SALOME_Exception)
3099 Unexpect aCatch(SALOME_SalomeException);
3101 _preMeshInfo->FullLoadFromFile();
3103 string aMeshName = prepareMeshNameAndGroups(file, true);
3104 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3105 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3106 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3110 //================================================================================
3112 * \brief Export a mesh to a DAT file
3114 //================================================================================
3116 void SMESH_Mesh_i::ExportDAT (const char *file)
3117 throw(SALOME::SALOME_Exception)
3119 Unexpect aCatch(SALOME_SalomeException);
3121 _preMeshInfo->FullLoadFromFile();
3123 // Update Python script
3124 // check names of groups
3126 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3129 PrepareForWriting(file);
3130 _impl->ExportDAT(file);
3133 //================================================================================
3135 * \brief Export a mesh to an UNV file
3137 //================================================================================
3139 void SMESH_Mesh_i::ExportUNV (const char *file)
3140 throw(SALOME::SALOME_Exception)
3142 Unexpect aCatch(SALOME_SalomeException);
3144 _preMeshInfo->FullLoadFromFile();
3146 // Update Python script
3147 // check names of groups
3149 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3152 PrepareForWriting(file);
3153 _impl->ExportUNV(file);
3156 //================================================================================
3158 * \brief Export a mesh to an STL file
3160 //================================================================================
3162 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3163 throw(SALOME::SALOME_Exception)
3165 Unexpect aCatch(SALOME_SalomeException);
3167 _preMeshInfo->FullLoadFromFile();
3169 // Update Python script
3170 // check names of groups
3172 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3173 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3175 CORBA::String_var name;
3176 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3177 if ( !so->_is_nil() )
3178 name = so->GetName();
3181 PrepareForWriting( file );
3182 _impl->ExportSTL( file, isascii, name.in() );
3185 //================================================================================
3187 * \brief Export a part of mesh to a med file
3189 //================================================================================
3191 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3193 CORBA::Boolean auto_groups,
3195 CORBA::Boolean overwrite,
3196 CORBA::Boolean autoDimension,
3197 const GEOM::ListOfFields& fields,
3198 const char* geomAssocFields)
3199 throw (SALOME::SALOME_Exception)
3201 //MESSAGE("MED minor version: "<< minor);
3204 _preMeshInfo->FullLoadFromFile();
3207 bool have0dField = false;
3208 if ( fields.length() > 0 )
3210 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3211 if ( shapeToMesh->_is_nil() )
3212 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3214 for ( size_t i = 0; i < fields.length(); ++i )
3216 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3217 THROW_SALOME_CORBA_EXCEPTION
3218 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3219 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3220 if ( fieldShape->_is_nil() )
3221 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3222 if ( !fieldShape->IsSame( shapeToMesh ) )
3223 THROW_SALOME_CORBA_EXCEPTION
3224 ( "Field defined not on shape", SALOME::BAD_PARAM);
3225 if ( fields[i]->GetDimension() == 0 )
3228 if ( geomAssocFields )
3229 for ( int i = 0; geomAssocFields[i]; ++i )
3230 switch ( geomAssocFields[i] ) {
3231 case 'v':case 'e':case 'f':case 's': break;
3232 case 'V':case 'E':case 'F':case 'S': break;
3233 default: THROW_SALOME_CORBA_EXCEPTION
3234 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3238 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3242 string aMeshName = "Mesh";
3243 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3244 if ( CORBA::is_nil( meshPart ) ||
3245 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3247 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3248 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
3249 0, autoDimension, /*addODOnVertices=*/have0dField);
3250 meshDS = _impl->GetMeshDS();
3255 _preMeshInfo->FullLoadFromFile();
3257 PrepareForWriting(file, overwrite);
3259 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3260 if ( !SO->_is_nil() ) {
3261 CORBA::String_var name = SO->GetName();
3265 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3266 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, minor,
3267 partDS, autoDimension, /*addODOnVertices=*/have0dField);
3268 meshDS = tmpDSDeleter._obj = partDS;
3273 if ( _impl->HasShapeToMesh() )
3275 DriverMED_W_Field fieldWriter;
3276 fieldWriter.SetFile( file );
3277 fieldWriter.SetMeshName( aMeshName );
3278 fieldWriter.AddODOnVertices( have0dField );
3280 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3284 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3285 goList->length( fields.length() );
3286 for ( size_t i = 0; i < fields.length(); ++i )
3288 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3291 TPythonDump() << _this() << ".ExportPartToMED( "
3292 << meshPart << ", r'"
3294 << auto_groups << ", "
3296 << overwrite << ", "
3297 << autoDimension << ", "
3299 << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3301 SMESH_CATCH( SMESH::throwCorbaException );
3304 //================================================================================
3306 * Write GEOM fields to MED file
3308 //================================================================================
3310 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3311 SMESHDS_Mesh* meshDS,
3312 const GEOM::ListOfFields& fields,
3313 const char* geomAssocFields)
3315 #define METH "SMESH_Mesh_i::exportMEDFields() "
3317 if (( fields.length() < 1 ) &&
3318 ( !geomAssocFields || !geomAssocFields[0] ))
3321 std::vector< std::vector< double > > dblVals;
3322 std::vector< std::vector< int > > intVals;
3323 std::vector< int > subIdsByDim[ 4 ];
3324 const double noneDblValue = 0.;
3325 const double noneIntValue = 0;
3327 for ( size_t iF = 0; iF < fields.length(); ++iF )
3331 int dim = fields[ iF ]->GetDimension();
3332 SMDSAbs_ElementType elemType;
3333 TopAbs_ShapeEnum shapeType;
3335 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3336 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3337 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3338 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3340 continue; // skip fields on whole shape
3342 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3343 if ( dataType == GEOM::FDT_String )
3345 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3346 if ( stepIDs->length() < 1 )
3348 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3349 if ( comps->length() < 1 )
3351 CORBA::String_var name = fields[ iF ]->GetName();
3353 if ( !fieldWriter.Set( meshDS,
3357 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3360 for ( size_t iC = 0; iC < comps->length(); ++iC )
3361 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3363 dblVals.resize( comps->length() );
3364 intVals.resize( comps->length() );
3366 // find sub-shape IDs
3368 std::vector< int >& subIds = subIdsByDim[ dim ];
3369 if ( subIds.empty() )
3370 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3371 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3372 subIds.push_back( id );
3376 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3380 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3382 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3383 if ( step->_is_nil() )
3386 CORBA::Long stamp = step->GetStamp();
3387 CORBA::Long id = step->GetID();
3388 fieldWriter.SetDtIt( int( stamp ), int( id ));
3390 // fill dblVals or intVals
3391 for ( size_t iC = 0; iC < comps->length(); ++iC )
3392 if ( dataType == GEOM::FDT_Double )
3394 dblVals[ iC ].clear();
3395 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3399 intVals[ iC ].clear();
3400 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3404 case GEOM::FDT_Double:
3406 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3407 if ( dblStep->_is_nil() ) continue;
3408 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3409 if ( vv->length() != subIds.size() * comps->length() )
3410 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3411 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3412 for ( size_t iC = 0; iC < comps->length(); ++iC )
3413 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3418 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3419 if ( intStep->_is_nil() ) continue;
3420 GEOM::ListOfLong_var vv = intStep->GetValues();
3421 if ( vv->length() != subIds.size() * comps->length() )
3422 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3423 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3424 for ( size_t iC = 0; iC < comps->length(); ++iC )
3425 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3428 case GEOM::FDT_Bool:
3430 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3431 if ( boolStep->_is_nil() ) continue;
3432 GEOM::short_array_var vv = boolStep->GetValues();
3433 if ( vv->length() != subIds.size() * comps->length() )
3434 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3435 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3436 for ( size_t iC = 0; iC < comps->length(); ++iC )
3437 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3443 // pass values to fieldWriter
3444 elemIt = fieldWriter.GetOrderedElems();
3445 if ( dataType == GEOM::FDT_Double )
3446 while ( elemIt->more() )
3448 const SMDS_MeshElement* e = elemIt->next();
3449 const int shapeID = e->getshapeId();
3450 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3451 for ( size_t iC = 0; iC < comps->length(); ++iC )
3452 fieldWriter.AddValue( noneDblValue );
3454 for ( size_t iC = 0; iC < comps->length(); ++iC )
3455 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3458 while ( elemIt->more() )
3460 const SMDS_MeshElement* e = elemIt->next();
3461 const int shapeID = e->getshapeId();
3462 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3463 for ( size_t iC = 0; iC < comps->length(); ++iC )
3464 fieldWriter.AddValue( (double) noneIntValue );
3466 for ( size_t iC = 0; iC < comps->length(); ++iC )
3467 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3471 fieldWriter.Perform();
3472 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3473 if ( res && res->IsKO() )
3475 if ( res->myComment.empty() )
3476 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3478 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3484 if ( !geomAssocFields || !geomAssocFields[0] )
3487 // write geomAssocFields
3489 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3490 shapeDim[ TopAbs_COMPOUND ] = 3;
3491 shapeDim[ TopAbs_COMPSOLID ] = 3;
3492 shapeDim[ TopAbs_SOLID ] = 3;
3493 shapeDim[ TopAbs_SHELL ] = 2;
3494 shapeDim[ TopAbs_FACE ] = 2;
3495 shapeDim[ TopAbs_WIRE ] = 1;
3496 shapeDim[ TopAbs_EDGE ] = 1;
3497 shapeDim[ TopAbs_VERTEX ] = 0;
3498 shapeDim[ TopAbs_SHAPE ] = 3;
3500 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3502 std::vector< std::string > compNames;
3503 switch ( geomAssocFields[ iF ]) {
3505 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3506 compNames.push_back( "dim" );
3509 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3512 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3515 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3519 compNames.push_back( "id" );
3520 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3521 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3523 fieldWriter.SetDtIt( -1, -1 );
3525 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3529 if ( compNames.size() == 2 ) // _vertices_
3530 while ( elemIt->more() )
3532 const SMDS_MeshElement* e = elemIt->next();
3533 const int shapeID = e->getshapeId();
3536 fieldWriter.AddValue( (double) -1 );
3537 fieldWriter.AddValue( (double) -1 );
3541 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3542 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3543 fieldWriter.AddValue( (double) shapeID );
3547 while ( elemIt->more() )
3549 const SMDS_MeshElement* e = elemIt->next();
3550 const int shapeID = e->getshapeId();
3552 fieldWriter.AddValue( (double) -1 );
3554 fieldWriter.AddValue( (double) shapeID );
3558 fieldWriter.Perform();
3559 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3560 if ( res && res->IsKO() )
3562 if ( res->myComment.empty() )
3563 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3565 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3568 } // loop on geomAssocFields
3573 //================================================================================
3575 * \brief Export a part of mesh to a DAT file
3577 //================================================================================
3579 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3581 throw (SALOME::SALOME_Exception)
3583 Unexpect aCatch(SALOME_SalomeException);
3585 _preMeshInfo->FullLoadFromFile();
3587 PrepareForWriting(file);
3589 SMESH_MeshPartDS partDS( meshPart );
3590 _impl->ExportDAT(file,&partDS);
3592 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3593 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3595 //================================================================================
3597 * \brief Export a part of mesh to an UNV file
3599 //================================================================================
3601 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3603 throw (SALOME::SALOME_Exception)
3605 Unexpect aCatch(SALOME_SalomeException);
3607 _preMeshInfo->FullLoadFromFile();
3609 PrepareForWriting(file);
3611 SMESH_MeshPartDS partDS( meshPart );
3612 _impl->ExportUNV(file, &partDS);
3614 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3615 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3617 //================================================================================
3619 * \brief Export a part of mesh to an STL file
3621 //================================================================================
3623 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3625 ::CORBA::Boolean isascii)
3626 throw (SALOME::SALOME_Exception)
3628 Unexpect aCatch(SALOME_SalomeException);
3630 _preMeshInfo->FullLoadFromFile();
3632 PrepareForWriting(file);
3634 CORBA::String_var name;
3635 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3636 if ( !so->_is_nil() )
3637 name = so->GetName();
3639 SMESH_MeshPartDS partDS( meshPart );
3640 _impl->ExportSTL( file, isascii, name.in(), &partDS );
3642 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3643 << meshPart<< ", r'" << file << "', " << isascii << ")";
3646 //================================================================================
3648 * \brief Export a part of mesh to an STL file
3650 //================================================================================
3652 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3654 CORBA::Boolean overwrite,
3655 CORBA::Boolean groupElemsByType)
3656 throw (SALOME::SALOME_Exception)
3659 Unexpect aCatch(SALOME_SalomeException);
3661 _preMeshInfo->FullLoadFromFile();
3663 PrepareForWriting(file,overwrite);
3665 std::string meshName("");
3666 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
3667 if ( !so->_is_nil() )
3669 CORBA::String_var name = so->GetName();
3670 meshName = name.in();
3674 SMESH_MeshPartDS partDS( meshPart );
3675 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
3677 SMESH_CATCH( SMESH::throwCorbaException );
3679 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3680 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3682 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3686 //================================================================================
3688 * \brief Export a part of mesh to a GMF file
3690 //================================================================================
3692 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3694 bool withRequiredGroups)
3695 throw (SALOME::SALOME_Exception)
3697 Unexpect aCatch(SALOME_SalomeException);
3699 _preMeshInfo->FullLoadFromFile();
3701 PrepareForWriting(file,/*overwrite=*/true);
3703 SMESH_MeshPartDS partDS( meshPart );
3704 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3706 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3707 << meshPart<< ", r'"
3709 << withRequiredGroups << ")";
3712 //=============================================================================
3714 * Return computation progress [0.,1]
3716 //=============================================================================
3718 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3722 return _impl->GetComputeProgress();
3724 SMESH_CATCH( SMESH::doNothing );
3728 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 return _preMeshInfo->NbNodes();
3734 return _impl->NbNodes();
3737 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3739 Unexpect aCatch(SALOME_SalomeException);
3741 return _preMeshInfo->NbElements();
3743 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3746 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3748 Unexpect aCatch(SALOME_SalomeException);
3750 return _preMeshInfo->Nb0DElements();
3752 return _impl->Nb0DElements();
3755 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3757 Unexpect aCatch(SALOME_SalomeException);
3759 return _preMeshInfo->NbBalls();
3761 return _impl->NbBalls();
3764 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3766 Unexpect aCatch(SALOME_SalomeException);
3768 return _preMeshInfo->NbEdges();
3770 return _impl->NbEdges();
3773 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3774 throw(SALOME::SALOME_Exception)
3776 Unexpect aCatch(SALOME_SalomeException);
3778 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3780 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3783 //=============================================================================
3785 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3787 Unexpect aCatch(SALOME_SalomeException);
3789 return _preMeshInfo->NbFaces();
3791 return _impl->NbFaces();
3794 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3796 Unexpect aCatch(SALOME_SalomeException);
3798 return _preMeshInfo->NbTriangles();
3800 return _impl->NbTriangles();
3803 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3805 Unexpect aCatch(SALOME_SalomeException);
3807 return _preMeshInfo->NbBiQuadTriangles();
3809 return _impl->NbBiQuadTriangles();
3812 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3814 Unexpect aCatch(SALOME_SalomeException);
3816 return _preMeshInfo->NbQuadrangles();
3818 return _impl->NbQuadrangles();
3821 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3823 Unexpect aCatch(SALOME_SalomeException);
3825 return _preMeshInfo->NbBiQuadQuadrangles();
3827 return _impl->NbBiQuadQuadrangles();
3830 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
3832 Unexpect aCatch(SALOME_SalomeException);
3834 return _preMeshInfo->NbPolygons();
3836 return _impl->NbPolygons();
3839 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3841 Unexpect aCatch(SALOME_SalomeException);
3843 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3845 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3848 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3849 throw(SALOME::SALOME_Exception)
3851 Unexpect aCatch(SALOME_SalomeException);
3853 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3855 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3858 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3859 throw(SALOME::SALOME_Exception)
3861 Unexpect aCatch(SALOME_SalomeException);
3863 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3865 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3868 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3869 throw(SALOME::SALOME_Exception)
3871 Unexpect aCatch(SALOME_SalomeException);
3873 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3875 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3878 //=============================================================================
3880 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3882 Unexpect aCatch(SALOME_SalomeException);
3884 return _preMeshInfo->NbVolumes();
3886 return _impl->NbVolumes();
3889 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3891 Unexpect aCatch(SALOME_SalomeException);
3893 return _preMeshInfo->NbTetras();
3895 return _impl->NbTetras();
3898 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3900 Unexpect aCatch(SALOME_SalomeException);
3902 return _preMeshInfo->NbHexas();
3904 return _impl->NbHexas();
3907 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3909 Unexpect aCatch(SALOME_SalomeException);
3911 return _preMeshInfo->NbTriQuadHexas();
3913 return _impl->NbTriQuadraticHexas();
3916 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3918 Unexpect aCatch(SALOME_SalomeException);
3920 return _preMeshInfo->NbPyramids();
3922 return _impl->NbPyramids();
3925 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3927 Unexpect aCatch(SALOME_SalomeException);
3929 return _preMeshInfo->NbPrisms();
3931 return _impl->NbPrisms();
3934 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3936 Unexpect aCatch(SALOME_SalomeException);
3938 return _preMeshInfo->NbHexPrisms();
3940 return _impl->NbHexagonalPrisms();
3943 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3945 Unexpect aCatch(SALOME_SalomeException);
3947 return _preMeshInfo->NbPolyhedrons();
3949 return _impl->NbPolyhedrons();
3952 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3953 throw(SALOME::SALOME_Exception)
3955 Unexpect aCatch(SALOME_SalomeException);
3957 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3959 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3962 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3963 throw(SALOME::SALOME_Exception)
3965 Unexpect aCatch(SALOME_SalomeException);
3967 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3969 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3972 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3973 throw(SALOME::SALOME_Exception)
3975 Unexpect aCatch(SALOME_SalomeException);
3977 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3979 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3982 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3983 throw(SALOME::SALOME_Exception)
3985 Unexpect aCatch(SALOME_SalomeException);
3987 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3989 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3992 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3993 throw(SALOME::SALOME_Exception)
3995 Unexpect aCatch(SALOME_SalomeException);
3997 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3999 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4002 //=============================================================================
4004 * Returns nb of published sub-meshes
4006 //=============================================================================
4008 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4010 Unexpect aCatch(SALOME_SalomeException);
4011 return _mapSubMesh_i.size();
4014 //=============================================================================
4016 * Dumps mesh into a string
4018 //=============================================================================
4020 char* SMESH_Mesh_i::Dump()
4024 return CORBA::string_dup( os.str().c_str() );
4027 //=============================================================================
4029 * Method of SMESH_IDSource interface
4031 //=============================================================================
4033 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4035 return GetElementsId();
4038 //=============================================================================
4040 * Returns ids of all elements
4042 //=============================================================================
4044 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4045 throw (SALOME::SALOME_Exception)
4047 Unexpect aCatch(SALOME_SalomeException);
4049 _preMeshInfo->FullLoadFromFile();
4051 SMESH::long_array_var aResult = new SMESH::long_array();
4052 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4054 if ( aSMESHDS_Mesh == NULL )
4055 return aResult._retn();
4057 long nbElements = NbElements();
4058 aResult->length( nbElements );
4059 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4060 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4061 aResult[i] = anIt->next()->GetID();
4063 return aResult._retn();
4067 //=============================================================================
4069 * Returns ids of all elements of given type
4071 //=============================================================================
4073 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4074 throw (SALOME::SALOME_Exception)
4076 Unexpect aCatch(SALOME_SalomeException);
4078 _preMeshInfo->FullLoadFromFile();
4080 SMESH::long_array_var aResult = new SMESH::long_array();
4081 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4083 if ( aSMESHDS_Mesh == NULL )
4084 return aResult._retn();
4086 long nbElements = NbElements();
4088 // No sense in returning ids of elements along with ids of nodes:
4089 // when theElemType == SMESH::ALL, return node ids only if
4090 // there are no elements
4091 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4092 return GetNodesId();
4094 aResult->length( nbElements );
4098 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4099 while ( i < nbElements && anIt->more() )
4100 aResult[i++] = anIt->next()->GetID();
4102 aResult->length( i );
4104 return aResult._retn();
4107 //=============================================================================
4109 * Returns ids of all nodes
4111 //=============================================================================
4113 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4114 throw (SALOME::SALOME_Exception)
4116 Unexpect aCatch(SALOME_SalomeException);
4118 _preMeshInfo->FullLoadFromFile();
4120 SMESH::long_array_var aResult = new SMESH::long_array();
4121 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4123 if ( aMeshDS == NULL )
4124 return aResult._retn();
4126 long nbNodes = NbNodes();
4127 aResult->length( nbNodes );
4128 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4129 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4130 aResult[i] = anIt->next()->GetID();
4132 return aResult._retn();
4135 //=============================================================================
4139 //=============================================================================
4141 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4142 throw (SALOME::SALOME_Exception)
4144 SMESH::ElementType type = SMESH::ALL;
4148 _preMeshInfo->FullLoadFromFile();
4150 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4152 SMESH_CATCH( SMESH::throwCorbaException );
4157 //=============================================================================
4161 //=============================================================================
4163 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4164 throw (SALOME::SALOME_Exception)
4167 _preMeshInfo->FullLoadFromFile();
4169 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4171 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4173 return ( SMESH::EntityType ) e->GetEntityType();
4176 //=============================================================================
4180 //=============================================================================
4182 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4183 throw (SALOME::SALOME_Exception)
4186 _preMeshInfo->FullLoadFromFile();
4188 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4190 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4192 return ( SMESH::GeometryType ) e->GetGeomType();
4195 //=============================================================================
4197 * Returns ID of elements for given submesh
4199 //=============================================================================
4200 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4201 throw (SALOME::SALOME_Exception)
4203 SMESH::long_array_var aResult = new SMESH::long_array();
4207 _preMeshInfo->FullLoadFromFile();
4209 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4210 if(!SM) return aResult._retn();
4212 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4213 if(!SDSM) return aResult._retn();
4215 aResult->length(SDSM->NbElements());
4217 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4219 while ( eIt->more() ) {
4220 aResult[i++] = eIt->next()->GetID();
4223 SMESH_CATCH( SMESH::throwCorbaException );
4225 return aResult._retn();
4228 //=============================================================================
4230 * Returns ID of nodes for given submesh
4231 * If param all==true - returns all nodes, else -
4232 * returns only nodes on shapes.
4234 //=============================================================================
4236 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4238 throw (SALOME::SALOME_Exception)
4240 SMESH::long_array_var aResult = new SMESH::long_array();
4244 _preMeshInfo->FullLoadFromFile();
4246 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4247 if(!SM) return aResult._retn();
4249 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4250 if(!SDSM) return aResult._retn();
4253 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4254 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4255 while ( nIt->more() ) {
4256 const SMDS_MeshNode* elem = nIt->next();
4257 theElems.insert( elem->GetID() );
4260 else { // all nodes of submesh elements
4261 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4262 while ( eIt->more() ) {
4263 const SMDS_MeshElement* anElem = eIt->next();
4264 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4265 while ( nIt->more() ) {
4266 const SMDS_MeshElement* elem = nIt->next();
4267 theElems.insert( elem->GetID() );
4272 aResult->length(theElems.size());
4273 set<int>::iterator itElem;
4275 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4276 aResult[i++] = *itElem;
4278 SMESH_CATCH( SMESH::throwCorbaException );
4280 return aResult._retn();
4283 //=============================================================================
4285 * Returns type of elements for given submesh
4287 //=============================================================================
4289 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4290 throw (SALOME::SALOME_Exception)
4292 SMESH::ElementType type = SMESH::ALL;
4296 _preMeshInfo->FullLoadFromFile();
4298 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4299 if(!SM) return SMESH::ALL;
4301 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4302 if(!SDSM) return SMESH::ALL;
4304 if(SDSM->NbElements()==0)
4305 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4307 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4308 const SMDS_MeshElement* anElem = eIt->next();
4310 type = ( SMESH::ElementType ) anElem->GetType();
4312 SMESH_CATCH( SMESH::throwCorbaException );
4318 //=============================================================================
4320 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4322 //=============================================================================
4324 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4327 _preMeshInfo->FullLoadFromFile();
4329 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4330 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4335 //=============================================================================
4337 * Get XYZ coordinates of node as list of double
4338 * If there is not node for given ID - returns empty list
4340 //=============================================================================
4342 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4345 _preMeshInfo->FullLoadFromFile();
4347 SMESH::double_array_var aResult = new SMESH::double_array();
4348 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4349 if ( aMeshDS == NULL )
4350 return aResult._retn();
4353 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4355 return aResult._retn();
4359 aResult[0] = aNode->X();
4360 aResult[1] = aNode->Y();
4361 aResult[2] = aNode->Z();
4362 return aResult._retn();
4366 //=============================================================================
4368 * For given node returns list of IDs of inverse elements
4369 * If there is not node for given ID - returns empty list
4371 //=============================================================================
4373 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4376 _preMeshInfo->FullLoadFromFile();
4378 SMESH::long_array_var aResult = new SMESH::long_array();
4379 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4380 if ( aMeshDS == NULL )
4381 return aResult._retn();
4384 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4386 return aResult._retn();
4388 // find inverse elements
4389 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4390 aResult->length( aNode->NbInverseElements() );
4391 for( int i = 0; eIt->more(); ++i )
4393 const SMDS_MeshElement* elem = eIt->next();
4394 aResult[ i ] = elem->GetID();
4396 return aResult._retn();
4399 //=============================================================================
4401 * \brief Return position of a node on shape
4403 //=============================================================================
4405 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4408 _preMeshInfo->FullLoadFromFile();
4410 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4411 aNodePosition->shapeID = 0;
4412 aNodePosition->shapeType = GEOM::SHAPE;
4414 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4415 if ( !mesh ) return aNodePosition;
4417 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4419 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4421 aNodePosition->shapeID = aNode->getshapeId();
4422 switch ( pos->GetTypeOfPosition() ) {
4424 aNodePosition->shapeType = GEOM::EDGE;
4425 aNodePosition->params.length(1);
4426 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4428 case SMDS_TOP_FACE: {
4429 SMDS_FacePositionPtr fPos = pos;
4430 aNodePosition->shapeType = GEOM::FACE;
4431 aNodePosition->params.length(2);
4432 aNodePosition->params[0] = fPos->GetUParameter();
4433 aNodePosition->params[1] = fPos->GetVParameter();
4436 case SMDS_TOP_VERTEX:
4437 aNodePosition->shapeType = GEOM::VERTEX;
4439 case SMDS_TOP_3DSPACE:
4440 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4441 aNodePosition->shapeType = GEOM::SOLID;
4442 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4443 aNodePosition->shapeType = GEOM::SHELL;
4449 return aNodePosition;
4452 //=============================================================================
4454 * \brief Return position of an element on shape
4456 //=============================================================================
4458 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4461 _preMeshInfo->FullLoadFromFile();
4463 SMESH::ElementPosition anElementPosition;
4464 anElementPosition.shapeID = 0;
4465 anElementPosition.shapeType = GEOM::SHAPE;
4467 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4468 if ( !mesh ) return anElementPosition;
4470 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4472 anElementPosition.shapeID = anElem->getshapeId();
4473 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4474 if ( !aSp.IsNull() ) {
4475 switch ( aSp.ShapeType() ) {
4477 anElementPosition.shapeType = GEOM::EDGE;
4480 anElementPosition.shapeType = GEOM::FACE;
4483 anElementPosition.shapeType = GEOM::VERTEX;
4486 anElementPosition.shapeType = GEOM::SOLID;
4489 anElementPosition.shapeType = GEOM::SHELL;
4495 return anElementPosition;
4498 //=============================================================================
4500 * If given element is node returns IDs of shape from position
4501 * If there is not node for given ID - returns -1
4503 //=============================================================================
4505 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4508 _preMeshInfo->FullLoadFromFile();
4510 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4511 if ( aMeshDS == NULL )
4515 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4517 return aNode->getshapeId();
4524 //=============================================================================
4526 * For given element returns ID of result shape after
4527 * ::FindShape() from SMESH_MeshEditor
4528 * If there is not element for given ID - returns -1
4530 //=============================================================================
4532 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4535 _preMeshInfo->FullLoadFromFile();
4537 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4538 if ( aMeshDS == NULL )
4541 // try to find element
4542 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4546 ::SMESH_MeshEditor aMeshEditor(_impl);
4547 int index = aMeshEditor.FindShape( elem );
4555 //=============================================================================
4557 * Returns number of nodes for given element
4558 * If there is not element for given ID - returns -1
4560 //=============================================================================
4562 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4565 _preMeshInfo->FullLoadFromFile();
4567 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4568 if ( aMeshDS == NULL ) return -1;
4569 // try to find element
4570 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4571 if(!elem) return -1;
4572 return elem->NbNodes();
4576 //=============================================================================
4578 * Returns ID of node by given index for given element
4579 * If there is not element for given ID - returns -1
4580 * If there is not node for given index - returns -2
4582 //=============================================================================
4584 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4587 _preMeshInfo->FullLoadFromFile();
4589 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4590 if ( aMeshDS == NULL ) return -1;
4591 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4592 if(!elem) return -1;
4593 if( index>=elem->NbNodes() || index<0 ) return -1;
4594 return elem->GetNode(index)->GetID();
4597 //=============================================================================
4599 * Returns IDs of nodes of given element
4601 //=============================================================================
4603 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4606 _preMeshInfo->FullLoadFromFile();
4608 SMESH::long_array_var aResult = new SMESH::long_array();
4609 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4611 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
4613 aResult->length( elem->NbNodes() );
4614 for ( int i = 0; i < elem->NbNodes(); ++i )
4615 aResult[ i ] = elem->GetNode( i )->GetID();
4618 return aResult._retn();
4621 //=============================================================================
4623 * Returns true if given node is medium node
4624 * in given quadratic element
4626 //=============================================================================
4628 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4631 _preMeshInfo->FullLoadFromFile();
4633 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4634 if ( aMeshDS == NULL ) return false;
4636 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4637 if(!aNode) return false;
4638 // try to find element
4639 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
4640 if(!elem) return false;
4642 return elem->IsMediumNode(aNode);
4646 //=============================================================================
4648 * Returns true if given node is medium node
4649 * in one of quadratic elements
4651 //=============================================================================
4653 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4654 SMESH::ElementType theElemType)
4657 _preMeshInfo->FullLoadFromFile();
4659 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4660 if ( aMeshDS == NULL ) return false;
4663 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
4664 if(!aNode) return false;
4666 SMESH_MesherHelper aHelper( *(_impl) );
4668 SMDSAbs_ElementType aType;
4669 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4670 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4671 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4672 else aType = SMDSAbs_All;
4674 return aHelper.IsMedium(aNode,aType);
4678 //=============================================================================
4680 * Returns number of edges for given element
4682 //=============================================================================
4684 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4687 _preMeshInfo->FullLoadFromFile();
4689 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4690 if ( aMeshDS == NULL ) return -1;
4691 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4692 if(!elem) return -1;
4693 return elem->NbEdges();
4697 //=============================================================================
4699 * Returns number of faces for given element
4701 //=============================================================================
4703 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4706 _preMeshInfo->FullLoadFromFile();
4708 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4709 if ( aMeshDS == NULL ) return -1;
4710 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4711 if(!elem) return -1;
4712 return elem->NbFaces();
4715 //=======================================================================
4716 //function : GetElemFaceNodes
4717 //purpose : Returns nodes of given face (counted from zero) for given element.
4718 //=======================================================================
4720 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4721 CORBA::Short faceIndex)
4724 _preMeshInfo->FullLoadFromFile();
4726 SMESH::long_array_var aResult = new SMESH::long_array();
4727 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
4729 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
4731 SMDS_VolumeTool vtool( elem );
4732 if ( faceIndex < vtool.NbFaces() )
4734 aResult->length( vtool.NbFaceNodes( faceIndex ));
4735 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4736 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4737 aResult[ i ] = nn[ i ]->GetID();
4741 return aResult._retn();
4744 //=======================================================================
4745 //function : GetElemFaceNodes
4746 //purpose : Returns three components of normal of given mesh face.
4747 //=======================================================================
4749 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4750 CORBA::Boolean normalized)
4753 _preMeshInfo->FullLoadFromFile();
4755 SMESH::double_array_var aResult = new SMESH::double_array();
4757 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4760 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4762 aResult->length( 3 );
4763 aResult[ 0 ] = normal.X();
4764 aResult[ 1 ] = normal.Y();
4765 aResult[ 2 ] = normal.Z();
4768 return aResult._retn();
4771 //=======================================================================
4772 //function : FindElementByNodes
4773 //purpose : Returns an element based on all given nodes.
4774 //=======================================================================
4776 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4779 _preMeshInfo->FullLoadFromFile();
4781 CORBA::Long elemID(0);
4782 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4784 vector< const SMDS_MeshNode * > nn( nodes.length() );
4785 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4786 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4789 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4790 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4791 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4792 _impl->NbVolumes( ORDER_QUADRATIC )))
4793 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4795 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4800 //================================================================================
4802 * \brief Return elements including all given nodes.
4804 //================================================================================
4806 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
4807 SMESH::ElementType elemType)
4810 _preMeshInfo->FullLoadFromFile();
4812 SMESH::long_array_var result = new SMESH::long_array();
4814 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4816 vector< const SMDS_MeshNode * > nn( nodes.length() );
4817 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4818 nn[i] = mesh->FindNode( nodes[i] );
4820 std::vector<const SMDS_MeshElement *> elems;
4821 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
4822 result->length( elems.size() );
4823 for ( size_t i = 0; i < elems.size(); ++i )
4824 result[i] = elems[i]->GetID();
4826 return result._retn();
4829 //=============================================================================
4831 * Returns true if given element is polygon
4833 //=============================================================================
4835 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4838 _preMeshInfo->FullLoadFromFile();
4840 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4841 if ( aMeshDS == NULL ) return false;
4842 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4843 if(!elem) return false;
4844 return elem->IsPoly();
4848 //=============================================================================
4850 * Returns true if given element is quadratic
4852 //=============================================================================
4854 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4857 _preMeshInfo->FullLoadFromFile();
4859 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4860 if ( aMeshDS == NULL ) return false;
4861 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4862 if(!elem) return false;
4863 return elem->IsQuadratic();
4866 //=============================================================================
4868 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4870 //=============================================================================
4872 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4875 _preMeshInfo->FullLoadFromFile();
4877 if ( const SMDS_BallElement* ball =
4878 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
4879 return ball->GetDiameter();
4884 //=============================================================================
4886 * Returns bary center for given element
4888 //=============================================================================
4890 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4893 _preMeshInfo->FullLoadFromFile();
4895 SMESH::double_array_var aResult = new SMESH::double_array();
4896 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4897 if ( aMeshDS == NULL )
4898 return aResult._retn();
4900 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
4902 return aResult._retn();
4904 if(elem->GetType()==SMDSAbs_Volume) {
4905 SMDS_VolumeTool aTool;
4906 if(aTool.Set(elem)) {
4908 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4913 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4915 double x=0., y=0., z=0.;
4916 for(; anIt->more(); ) {
4918 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4932 return aResult._retn();
4935 //================================================================================
4937 * \brief Create a group of elements preventing computation of a sub-shape
4939 //================================================================================
4941 SMESH::ListOfGroups*
4942 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4943 const char* theGroupName )
4944 throw ( SALOME::SALOME_Exception )
4946 Unexpect aCatch(SALOME_SalomeException);
4948 if ( !theGroupName || strlen( theGroupName) == 0 )
4949 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4951 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4952 ::SMESH_MeshEditor::ElemFeatures elemType;
4954 // submesh by subshape id
4955 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4956 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4959 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4960 if ( error && error->HasBadElems() )
4962 // sort bad elements by type
4963 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4964 const list<const SMDS_MeshElement*>& badElems =
4965 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
4966 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
4967 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
4968 for ( ; elemIt != elemEnd; ++elemIt )
4970 const SMDS_MeshElement* elem = *elemIt;
4971 if ( !elem ) continue;
4973 if ( elem->GetID() < 1 )
4975 // elem is a temporary element, make a real element
4976 vector< const SMDS_MeshNode* > nodes;
4977 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4978 while ( nIt->more() && elem )
4980 nodes.push_back( nIt->next() );
4981 if ( nodes.back()->GetID() < 1 )
4982 elem = 0; // a temporary element on temporary nodes
4986 ::SMESH_MeshEditor editor( _impl );
4987 elem = editor.AddElement( nodes, elemType.Init( elem ));
4991 elemsByType[ elem->GetType() ].push_back( elem );
4994 // how many groups to create?
4996 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4997 nbTypes += int( !elemsByType[ i ].empty() );
4998 groups->length( nbTypes );
5001 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5003 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5004 if ( elems.empty() ) continue;
5006 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5007 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5009 SMESH::SMESH_Mesh_var mesh = _this();
5010 SALOMEDS::SObject_wrap aSO =
5011 _gen_i->PublishGroup( mesh, groups[ iG ],
5012 GEOM::GEOM_Object::_nil(), theGroupName);
5014 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5015 if ( !grp_i ) continue;
5017 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5018 for ( size_t iE = 0; iE < elems.size(); ++iE )
5019 grpDS->SMDSGroup().Add( elems[ iE ]);
5024 return groups._retn();
5027 //=============================================================================
5029 * Create and publish group servants if any groups were imported or created anyhow
5031 //=============================================================================
5033 void SMESH_Mesh_i::CreateGroupServants()
5035 SMESH::SMESH_Mesh_var aMesh = _this();
5038 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5039 while ( groupIt->more() )
5041 ::SMESH_Group* group = groupIt->next();
5042 int anId = group->GetGroupDS()->GetID();
5044 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5045 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5047 addedIDs.insert( anId );
5049 SMESH_GroupBase_i* aGroupImpl;
5051 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5052 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5054 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5055 shape = groupOnGeom->GetShape();
5058 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5061 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5062 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5063 aGroupImpl->Register();
5065 // register CORBA object for persistence
5066 int nextId = _gen_i->RegisterObject( groupVar );
5067 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5068 else { nextId = 0; } // avoid "unused variable" warning in release mode
5070 // publishing the groups in the study
5071 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5072 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5074 if ( !addedIDs.empty() )
5077 set<int>::iterator id = addedIDs.begin();
5078 for ( ; id != addedIDs.end(); ++id )
5080 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5081 int i = std::distance( _mapGroups.begin(), it );
5082 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5087 //=============================================================================
5089 * \brief Return true if all sub-meshes are computed OK - to update an icon
5091 //=============================================================================
5093 bool SMESH_Mesh_i::IsComputedOK()
5095 return _impl->IsComputedOK();
5098 //=============================================================================
5100 * \brief Return groups cantained in _mapGroups by their IDs
5102 //=============================================================================
5104 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5106 int nbGroups = groupIDs.size();
5107 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5108 aList->length( nbGroups );
5110 list<int>::const_iterator ids = groupIDs.begin();
5111 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5113 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5114 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5115 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5117 aList->length( nbGroups );
5118 return aList._retn();
5121 //=============================================================================
5123 * \brief Return information about imported file
5125 //=============================================================================
5127 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5129 SMESH::MedFileInfo_var res( _medFileInfo );
5130 if ( !res.operator->() ) {
5131 res = new SMESH::MedFileInfo;
5133 res->fileSize = res->major = res->minor = res->release = -1;
5138 //=======================================================================
5139 //function : FileInfoToString
5140 //purpose : Persistence of file info
5141 //=======================================================================
5143 std::string SMESH_Mesh_i::FileInfoToString()
5146 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5148 s = SMESH_Comment( _medFileInfo->fileSize )
5149 << " " << _medFileInfo->major
5150 << " " << _medFileInfo->minor
5151 << " " << _medFileInfo->release
5152 << " " << _medFileInfo->fileName;
5157 //=======================================================================
5158 //function : FileInfoFromString
5159 //purpose : Persistence of file info
5160 //=======================================================================
5162 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5164 std::string size, major, minor, release, fileName;
5165 std::istringstream is(info);
5166 is >> size >> major >> minor >> release;
5167 fileName = info.data() + ( size.size() + 1 +
5170 release.size()+ 1 );
5172 _medFileInfo = new SMESH::MedFileInfo();
5173 _medFileInfo->fileName = fileName.c_str();
5174 _medFileInfo->fileSize = atoi( size.c_str() );
5175 _medFileInfo->major = atoi( major.c_str() );
5176 _medFileInfo->minor = atoi( minor.c_str() );
5177 _medFileInfo->release = atoi( release.c_str() );
5180 //=============================================================================
5182 * \brief Pass names of mesh groups from study to mesh DS
5184 //=============================================================================
5186 void SMESH_Mesh_i::checkGroupNames()
5188 int nbGrp = NbGroups();
5192 SMESH::ListOfGroups* grpList = 0;
5193 // avoid dump of "GetGroups"
5195 // store python dump into a local variable inside local scope
5196 SMESH::TPythonDump pDump; // do not delete this line of code
5197 grpList = GetGroups();
5200 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5201 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5204 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5205 if ( aGrpSO->_is_nil() )
5207 // correct name of the mesh group if necessary
5208 const char* guiName = aGrpSO->GetName();
5209 if ( strcmp(guiName, aGrp->GetName()) )
5210 aGrp->SetName( guiName );
5214 //=============================================================================
5216 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5218 //=============================================================================
5219 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5221 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5225 //=============================================================================
5227 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5229 //=============================================================================
5231 char* SMESH_Mesh_i::GetParameters()
5233 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5236 //=============================================================================
5238 * \brief Returns list of notebook variables used for last Mesh operation
5240 //=============================================================================
5241 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5243 SMESH::string_array_var aResult = new SMESH::string_array();
5244 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5246 CORBA::String_var aParameters = GetParameters();
5247 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5248 if ( aSections->length() > 0 ) {
5249 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5250 aResult->length( aVars.length() );
5251 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5252 aResult[i] = CORBA::string_dup( aVars[i] );
5255 return aResult._retn();
5258 //=======================================================================
5259 //function : GetTypes
5260 //purpose : Returns types of elements it contains
5261 //=======================================================================
5263 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5266 return _preMeshInfo->GetTypes();
5268 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5272 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5273 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5274 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5275 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5276 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5277 if (_impl->NbNodes() &&
5278 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5279 types->length( nbTypes );
5281 return types._retn();
5284 //=======================================================================
5285 //function : GetMesh
5286 //purpose : Returns self
5287 //=======================================================================
5289 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5291 return SMESH::SMESH_Mesh::_duplicate( _this() );
5294 //=======================================================================
5295 //function : IsMeshInfoCorrect
5296 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5297 // * happen if mesh data is not yet fully loaded from the file of study.
5298 //=======================================================================
5300 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5302 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5305 //=============================================================================
5307 * \brief Returns number of mesh elements per each \a EntityType
5309 //=============================================================================
5311 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5314 return _preMeshInfo->GetMeshInfo();
5316 SMESH::long_array_var aRes = new SMESH::long_array();
5317 aRes->length(SMESH::Entity_Last);
5318 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5320 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5322 return aRes._retn();
5323 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5324 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5325 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5326 return aRes._retn();
5329 //=============================================================================
5331 * \brief Returns number of mesh elements per each \a ElementType
5333 //=============================================================================
5335 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5337 SMESH::long_array_var aRes = new SMESH::long_array();
5338 aRes->length(SMESH::NB_ELEMENT_TYPES);
5339 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5342 const SMDS_MeshInfo* meshInfo = 0;
5344 meshInfo = _preMeshInfo;
5345 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5346 meshInfo = & meshDS->GetMeshInfo();
5349 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5350 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5352 return aRes._retn();
5355 //=============================================================================
5357 * Collect statistic of mesh elements given by iterator
5359 //=============================================================================
5361 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5362 SMESH::long_array& theInfo)
5364 if (!theItr) return;
5365 while (theItr->more())
5366 theInfo[ theItr->next()->GetEntityType() ]++;
5368 //=============================================================================
5370 * Returns mesh unstructed grid information.
5372 //=============================================================================
5374 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5376 SALOMEDS::TMPFile_var SeqFile;
5377 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5378 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5380 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5381 aWriter->WriteToOutputStringOn();
5382 aWriter->SetInputData(aGrid);
5383 aWriter->SetFileTypeToBinary();
5385 char* str = aWriter->GetOutputString();
5386 int size = aWriter->GetOutputStringLength();
5388 //Allocate octect buffer of required size
5389 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5390 //Copy ostrstream content to the octect buffer
5391 memcpy(OctetBuf, str, size);
5392 //Create and return TMPFile
5393 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5397 return SeqFile._retn();
5400 //=============================================================================
5401 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5402 * SMESH::ElementType type) */
5404 using namespace SMESH::Controls;
5405 //-----------------------------------------------------------------------------
5406 struct PredicateIterator : public SMDS_ElemIterator
5408 SMDS_ElemIteratorPtr _elemIter;
5409 PredicatePtr _predicate;
5410 const SMDS_MeshElement* _elem;
5412 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5413 PredicatePtr predicate):
5414 _elemIter(iterator), _predicate(predicate)
5422 virtual const SMDS_MeshElement* next()
5424 const SMDS_MeshElement* res = _elem;
5426 while ( _elemIter->more() && !_elem )
5428 _elem = _elemIter->next();
5429 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5436 //-----------------------------------------------------------------------------
5437 struct IDSourceIterator : public SMDS_ElemIterator
5439 const CORBA::Long* _idPtr;
5440 const CORBA::Long* _idEndPtr;
5441 SMESH::long_array_var _idArray;
5442 const SMDS_Mesh* _mesh;
5443 const SMDSAbs_ElementType _type;
5444 const SMDS_MeshElement* _elem;
5446 IDSourceIterator( const SMDS_Mesh* mesh,
5447 const CORBA::Long* ids,
5449 SMDSAbs_ElementType type):
5450 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5452 if ( _idPtr && nbIds && _mesh )
5455 IDSourceIterator( const SMDS_Mesh* mesh,
5456 SMESH::long_array* idArray,
5457 SMDSAbs_ElementType type):
5458 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5460 if ( idArray && _mesh )
5462 _idPtr = &_idArray[0];
5463 _idEndPtr = _idPtr + _idArray->length();
5471 virtual const SMDS_MeshElement* next()
5473 const SMDS_MeshElement* res = _elem;
5475 while ( _idPtr < _idEndPtr && !_elem )
5477 if ( _type == SMDSAbs_Node )
5479 _elem = _mesh->FindNode( *_idPtr++ );
5481 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5482 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5490 //-----------------------------------------------------------------------------
5492 struct NodeOfElemIterator : public SMDS_ElemIterator
5494 TColStd_MapOfInteger _checkedNodeIDs;
5495 SMDS_ElemIteratorPtr _elemIter;
5496 SMDS_ElemIteratorPtr _nodeIter;
5497 const SMDS_MeshElement* _node;
5499 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5501 if ( _elemIter && _elemIter->more() )
5503 _nodeIter = _elemIter->next()->nodesIterator();
5511 virtual const SMDS_MeshElement* next()
5513 const SMDS_MeshElement* res = _node;
5515 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
5517 if ( _nodeIter->more() )
5519 _node = _nodeIter->next();
5520 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5525 _nodeIter = _elemIter->next()->nodesIterator();
5533 //=============================================================================
5535 * Return iterator on elements of given type in given object
5537 //=============================================================================
5539 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5540 SMESH::ElementType theType)
5542 SMDS_ElemIteratorPtr elemIt;
5543 bool typeOK = ( theType == SMESH::ALL );
5544 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5546 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5547 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5548 if ( !mesh_i ) return elemIt;
5549 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5551 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5553 elemIt = meshDS->elementsIterator( elemType );
5556 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5558 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5561 elemIt = sm->GetElements();
5562 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5564 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5565 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5569 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5571 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5572 if ( groupDS && ( elemType == groupDS->GetType() ||
5573 elemType == SMDSAbs_Node ||
5574 elemType == SMDSAbs_All ))
5576 elemIt = groupDS->GetElements();
5577 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5580 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5582 if ( filter_i->GetElementType() == theType ||
5583 elemType == SMDSAbs_Node ||
5584 elemType == SMDSAbs_All)
5586 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5587 if ( pred_i && pred_i->GetPredicate() )
5589 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5590 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5591 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5592 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5598 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5599 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5600 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5602 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5605 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5606 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5610 SMESH::long_array_var ids = theObject->GetIDs();
5611 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5613 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5616 if ( elemIt && elemIt->more() && !typeOK )
5618 if ( elemType == SMDSAbs_Node )
5620 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5624 elemIt = SMDS_ElemIteratorPtr();
5630 //=============================================================================
5631 namespace // Finding concurrent hypotheses
5632 //=============================================================================
5636 * \brief mapping of mesh dimension into shape type
5638 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5640 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5642 case 0: aType = TopAbs_VERTEX; break;
5643 case 1: aType = TopAbs_EDGE; break;
5644 case 2: aType = TopAbs_FACE; break;
5646 default:aType = TopAbs_SOLID; break;
5651 //-----------------------------------------------------------------------------
5653 * \brief Internal structure used to find concurrent submeshes
5655 * It represents a pair < submesh, concurrent dimension >, where
5656 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
5657 * with another submesh. In other words, it is dimension of a hypothesis assigned
5664 int _dim; //!< a dimension the algo can build (concurrent dimension)
5665 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5666 TopTools_MapOfShape _shapeMap;
5667 SMESH_subMesh* _subMesh;
5668 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5670 //-----------------------------------------------------------------------------
5671 // Return the algorithm
5672 const SMESH_Algo* GetAlgo() const
5673 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5675 //-----------------------------------------------------------------------------
5677 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5679 const TopoDS_Shape& theShape)
5681 _subMesh = (SMESH_subMesh*)theSubMesh;
5682 SetShape( theDim, theShape );
5685 //-----------------------------------------------------------------------------
5687 void SetShape(const int theDim,
5688 const TopoDS_Shape& theShape)
5691 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5692 if (_dim >= _ownDim)
5693 _shapeMap.Add( theShape );
5695 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5696 for( ; anExp.More(); anExp.Next() )
5697 _shapeMap.Add( anExp.Current() );
5701 //-----------------------------------------------------------------------------
5702 //! Check sharing of sub-shapes
5703 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5704 const TopTools_MapOfShape& theToFind,
5705 const TopAbs_ShapeEnum theType)
5707 bool isShared = false;
5708 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5709 for (; !isShared && anItr.More(); anItr.Next() )
5711 const TopoDS_Shape aSubSh = anItr.Key();
5712 // check for case when concurrent dimensions are same
5713 isShared = theToFind.Contains( aSubSh );
5714 // check for sub-shape with concurrent dimension
5715 TopExp_Explorer anExp( aSubSh, theType );
5716 for ( ; !isShared && anExp.More(); anExp.Next() )
5717 isShared = theToFind.Contains( anExp.Current() );
5722 //-----------------------------------------------------------------------------
5723 //! check algorithms
5724 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5725 const SMESHDS_Hypothesis* theA2)
5727 if ( !theA1 || !theA2 ||
5728 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5729 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5730 return false; // one of the hypothesis is not algorithm
5731 // check algorithm names (should be equal)
5732 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5736 //-----------------------------------------------------------------------------
5737 //! Check if sub-shape hypotheses are concurrent
5738 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5740 if ( _subMesh == theOther->_subMesh )
5741 return false; // same sub-shape - should not be
5743 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5744 // any of the two submeshes is not on COMPOUND shape )
5745 // -> no concurrency
5746 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5747 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5748 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5749 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5750 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5753 // bool checkSubShape = ( _dim >= theOther->_dim )
5754 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5755 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5756 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5757 if ( !checkSubShape )
5760 // check algorithms to be same
5761 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5762 return true; // different algorithms -> concurrency !
5764 // check hypothesises for concurrence (skip first as algorithm)
5766 // pointers should be same, because it is referened from mesh hypothesis partition
5767 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5768 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5769 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5770 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5772 // the submeshes are concurrent if their algorithms has different parameters
5773 return nbSame != (int)theOther->_hypotheses.size() - 1;
5776 // Return true if algorithm of this SMESH_DimHyp is used if no
5777 // sub-mesh order is imposed by the user
5778 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5780 // NeedDiscreteBoundary() algo has a higher priority
5781 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5782 theOther->GetAlgo()->NeedDiscreteBoundary() )
5783 return !this->GetAlgo()->NeedDiscreteBoundary();
5785 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5788 }; // end of SMESH_DimHyp
5789 //-----------------------------------------------------------------------------
5791 typedef list<const SMESH_DimHyp*> TDimHypList;
5793 //-----------------------------------------------------------------------------
5795 void addDimHypInstance(const int theDim,
5796 const TopoDS_Shape& theShape,
5797 const SMESH_Algo* theAlgo,
5798 const SMESH_subMesh* theSubMesh,
5799 const list <const SMESHDS_Hypothesis*>& theHypList,
5800 TDimHypList* theDimHypListArr )
5802 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5803 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5804 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5805 dimHyp->_hypotheses.push_front(theAlgo);
5806 listOfdimHyp.push_back( dimHyp );
5809 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5810 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5811 theHypList.begin(), theHypList.end() );
5814 //-----------------------------------------------------------------------------
5815 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5816 TDimHypList& theListOfConcurr)
5818 if ( theListOfConcurr.empty() )
5820 theListOfConcurr.push_back( theDimHyp );
5824 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5825 while ( hypIt != theListOfConcurr.end() &&
5826 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5828 theListOfConcurr.insert( hypIt, theDimHyp );
5832 //-----------------------------------------------------------------------------
5833 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5834 const TDimHypList& theListOfDimHyp,
5835 TDimHypList& theListOfConcurrHyp,
5836 set<int>& theSetOfConcurrId )
5838 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5839 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5841 const SMESH_DimHyp* curDimHyp = *rIt;
5842 if ( curDimHyp == theDimHyp )
5843 break; // meet own dimHyp pointer in same dimension
5845 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5846 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5848 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5853 //-----------------------------------------------------------------------------
5854 void unionLists(TListOfInt& theListOfId,
5855 TListOfListOfInt& theListOfListOfId,
5858 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5859 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5861 continue; //skip already treated lists
5862 // check if other list has any same submesh object
5863 TListOfInt& otherListOfId = *it;
5864 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5865 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5868 // union two lists (from source into target)
5869 TListOfInt::iterator it2 = otherListOfId.begin();
5870 for ( ; it2 != otherListOfId.end(); it2++ ) {
5871 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5872 theListOfId.push_back(*it2);
5874 // clear source list
5875 otherListOfId.clear();
5878 //-----------------------------------------------------------------------------
5880 //! free memory allocated for dimension-hypothesis objects
5881 void removeDimHyps( TDimHypList* theArrOfList )
5883 for (int i = 0; i < 4; i++ ) {
5884 TDimHypList& listOfdimHyp = theArrOfList[i];
5885 TDimHypList::const_iterator it = listOfdimHyp.begin();
5886 for ( ; it != listOfdimHyp.end(); it++ )
5891 //-----------------------------------------------------------------------------
5893 * \brief find common submeshes with given submesh
5894 * \param theSubMeshList list of already collected submesh to check
5895 * \param theSubMesh given submesh to intersect with other
5896 * \param theCommonSubMeshes collected common submeshes
5898 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5899 const SMESH_subMesh* theSubMesh,
5900 set<const SMESH_subMesh*>& theCommon )
5904 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5905 for ( ; it != theSubMeshList.end(); it++ )
5906 theSubMesh->FindIntersection( *it, theCommon );
5907 theSubMeshList.push_back( theSubMesh );
5908 //theCommon.insert( theSubMesh );
5911 //-----------------------------------------------------------------------------
5912 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5914 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5915 for ( ; listsIt != smLists.end(); ++listsIt )
5917 const TListOfInt& smIDs = *listsIt;
5918 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5926 //=============================================================================
5928 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5930 //=============================================================================
5932 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5934 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5935 if ( isSubMeshInList( submeshID, anOrder ))
5938 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5939 return isSubMeshInList( submeshID, allConurrent );
5942 //=============================================================================
5944 * \brief Return submesh objects list in meshing order
5946 //=============================================================================
5948 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5950 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5952 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5954 return aResult._retn();
5956 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5957 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5958 anOrder.splice( anOrder.end(), allConurrent );
5961 TListOfListOfInt::iterator listIt = anOrder.begin();
5962 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5963 unionLists( *listIt, anOrder, listIndx + 1 );
5965 // convert submesh ids into interface instances
5966 // and dump command into python
5967 convertMeshOrder( anOrder, aResult, false );
5969 return aResult._retn();
5972 //=============================================================================
5974 * \brief Finds concurrent sub-meshes
5976 //=============================================================================
5978 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5980 TListOfListOfInt anOrder;
5981 ::SMESH_Mesh& mesh = GetImpl();
5983 // collect submeshes and detect concurrent algorithms and hypothesises
5984 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5986 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5987 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5988 ::SMESH_subMesh* sm = (*i_sm).second;
5990 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5992 // list of assigned hypothesises
5993 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5994 // Find out dimensions where the submesh can be concurrent.
5995 // We define the dimensions by algo of each of hypotheses in hypList
5996 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5997 for( ; hypIt != hypList.end(); hypIt++ ) {
5998 SMESH_Algo* anAlgo = 0;
5999 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6000 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6001 // hyp it-self is algo
6002 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6004 // try to find algorithm with help of sub-shapes
6005 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6006 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6007 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6010 continue; // no algorithm assigned to a current submesh
6012 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6013 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6015 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6016 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6017 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6019 } // end iterations on submesh
6021 // iterate on created dimension-hypotheses and check for concurrents
6022 for ( int i = 0; i < 4; i++ ) {
6023 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6024 // check for concurrents in own and other dimensions (step-by-step)
6025 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6026 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6027 const SMESH_DimHyp* dimHyp = *dhIt;
6028 TDimHypList listOfConcurr;
6029 set<int> setOfConcurrIds;
6030 // looking for concurrents and collect into own list
6031 for ( int j = i; j < 4; j++ )
6032 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6033 // check if any concurrents found
6034 if ( listOfConcurr.size() > 0 ) {
6035 // add own submesh to list of concurrent
6036 addInOrderOfPriority( dimHyp, listOfConcurr );
6037 list<int> listOfConcurrIds;
6038 TDimHypList::iterator hypIt = listOfConcurr.begin();
6039 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6040 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6041 anOrder.push_back( listOfConcurrIds );
6046 removeDimHyps(dimHypListArr);
6048 // now, minimize the number of concurrent groups
6049 // Here we assume that lists of submeshes can have same submesh
6050 // in case of multi-dimension algorithms, as result
6051 // list with common submesh has to be united into one list
6053 TListOfListOfInt::iterator listIt = anOrder.begin();
6054 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6055 unionLists( *listIt, anOrder, listIndx + 1 );
6061 //=============================================================================
6063 * \brief Set submesh object order
6064 * \param theSubMeshArray submesh array order
6066 //=============================================================================
6068 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6071 _preMeshInfo->ForgetOrLoad();
6074 ::SMESH_Mesh& mesh = GetImpl();
6076 TPythonDump aPythonDump; // prevent dump of called methods
6077 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6079 TListOfListOfInt subMeshOrder;
6080 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6082 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6083 TListOfInt subMeshIds;
6085 aPythonDump << ", ";
6086 aPythonDump << "[ ";
6087 // Collect subMeshes which should be clear
6088 // do it list-by-list, because modification of submesh order
6089 // take effect between concurrent submeshes only
6090 set<const SMESH_subMesh*> subMeshToClear;
6091 list<const SMESH_subMesh*> subMeshList;
6092 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6094 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6096 aPythonDump << ", ";
6097 aPythonDump << subMesh;
6098 subMeshIds.push_back( subMesh->GetId() );
6099 // detect common parts of submeshes
6100 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6101 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6103 aPythonDump << " ]";
6104 subMeshOrder.push_back( subMeshIds );
6106 // clear collected submeshes
6107 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6108 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6109 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6110 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6112 aPythonDump << " ])";
6114 mesh.SetMeshOrder( subMeshOrder );
6117 SMESH::SMESH_Mesh_var me = _this();
6118 _gen_i->UpdateIcons( me );
6123 //=============================================================================
6125 * \brief Convert submesh ids into submesh interfaces
6127 //=============================================================================
6129 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6130 SMESH::submesh_array_array& theResOrder,
6131 const bool theIsDump)
6133 int nbSet = theIdsOrder.size();
6134 TPythonDump aPythonDump; // prevent dump of called methods
6136 aPythonDump << "[ ";
6137 theResOrder.length(nbSet);
6138 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6140 for( ; it != theIdsOrder.end(); it++ ) {
6141 // translate submesh identificators into submesh objects
6142 // takeing into account real number of concurrent lists
6143 const TListOfInt& aSubOrder = (*it);
6144 if (!aSubOrder.size())
6147 aPythonDump << "[ ";
6148 // convert shape indices into interfaces
6149 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6150 aResSubSet->length(aSubOrder.size());
6151 TListOfInt::const_iterator subIt = aSubOrder.begin();
6153 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6154 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6156 SMESH::SMESH_subMesh_var subMesh =
6157 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6160 aPythonDump << ", ";
6161 aPythonDump << subMesh;
6163 aResSubSet[ j++ ] = subMesh;
6166 aPythonDump << " ]";
6168 theResOrder[ listIndx++ ] = aResSubSet;
6170 // correct number of lists
6171 theResOrder.length( listIndx );
6174 // finilise python dump
6175 aPythonDump << " ]";
6176 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6180 namespace // utils used by SMESH_MeshPartDS
6183 * \brief Class used to access to protected data of SMDS_MeshInfo
6185 struct TMeshInfo : public SMDS_MeshInfo
6187 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6190 * \brief Element holing its ID only
6192 struct TElemID : public SMDS_LinearEdge
6194 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6198 //================================================================================
6200 // Implementation of SMESH_MeshPartDS
6202 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6203 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6205 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6206 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6209 _meshDS = mesh_i->GetImpl().GetMeshDS();
6211 SetPersistentId( _meshDS->GetPersistentId() );
6213 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6215 // <meshPart> is the whole mesh
6216 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6218 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6219 myGroupSet = _meshDS->GetGroups();
6224 SMESH::long_array_var anIDs = meshPart->GetIDs();
6225 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6226 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6228 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6229 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6230 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6235 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6236 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6237 if ( _elements[ e->GetType() ].insert( e ).second )
6240 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6241 while ( nIt->more() )
6243 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6244 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6251 ShapeToMesh( _meshDS->ShapeToMesh() );
6253 _meshDS = 0; // to enforce iteration on _elements and _nodes
6256 // -------------------------------------------------------------------------------------
6257 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6258 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6261 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6262 for ( ; partIt != meshPart.end(); ++partIt )
6263 if ( const SMDS_MeshElement * e = *partIt )
6264 if ( _elements[ e->GetType() ].insert( e ).second )
6267 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6268 while ( nIt->more() )
6270 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6271 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6277 // -------------------------------------------------------------------------------------
6278 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6280 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6282 TElemID elem( IDelem );
6283 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6284 if ( !_elements[ iType ].empty() )
6286 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6287 if ( it != _elements[ iType ].end() )
6292 // -------------------------------------------------------------------------------------
6293 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6295 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6297 typedef SMDS_SetIterator
6298 <const SMDS_MeshElement*,
6299 TIDSortedElemSet::const_iterator,
6300 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6301 SMDS_MeshElement::GeomFilter
6304 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6306 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6307 _elements[type].end(),
6308 SMDS_MeshElement::GeomFilter( geomType )));
6310 // -------------------------------------------------------------------------------------
6311 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6313 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6315 typedef SMDS_SetIterator
6316 <const SMDS_MeshElement*,
6317 TIDSortedElemSet::const_iterator,
6318 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6319 SMDS_MeshElement::EntityFilter
6322 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6324 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6325 _elements[type].end(),
6326 SMDS_MeshElement::EntityFilter( entity )));
6328 // -------------------------------------------------------------------------------------
6329 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6331 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6332 if ( type == SMDSAbs_All && !_meshDS )
6334 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6336 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6337 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6339 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6341 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6342 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6344 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6345 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6347 // -------------------------------------------------------------------------------------
6348 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6349 iterType SMESH_MeshPartDS::methName() const \
6351 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6352 return _meshDS ? _meshDS->methName() : iterType \
6353 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6355 // -------------------------------------------------------------------------------------
6356 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6357 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6358 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6359 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6360 #undef _GET_ITER_DEFINE
6362 // END Implementation of SMESH_MeshPartDS
6364 //================================================================================