1 // Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_LinearEdge.hxx"
33 #include "SMDS_EdgePosition.hxx"
34 #include "SMDS_ElemIterator.hxx"
35 #include "SMDS_FacePosition.hxx"
36 #include "SMDS_IteratorOnIterators.hxx"
37 #include "SMDS_MeshGroup.hxx"
38 #include "SMDS_SetIterator.hxx"
39 #include "SMDS_StdIterator.hxx"
40 #include "SMDS_VolumeTool.hxx"
41 #include "SMESHDS_Command.hxx"
42 #include "SMESHDS_CommandType.hxx"
43 #include "SMESHDS_Group.hxx"
44 #include "SMESHDS_GroupOnGeom.hxx"
45 #include "SMESH_Controls.hxx"
46 #include "SMESH_File.hxx"
47 #include "SMESH_Filter_i.hxx"
48 #include "SMESH_Gen_i.hxx"
49 #include "SMESH_Group.hxx"
50 #include "SMESH_Group_i.hxx"
51 #include "SMESH_Mesh.hxx"
52 #include "SMESH_MeshAlgos.hxx"
53 #include "SMESH_MeshEditor.hxx"
54 #include "SMESH_MeshEditor_i.hxx"
55 #include "SMESH_MeshPartDS.hxx"
56 #include "SMESH_MesherHelper.hxx"
57 #include "SMESH_PreMeshInfo.hxx"
58 #include "SMESH_PythonDump.hxx"
59 #include "SMESH_subMesh_i.hxx"
61 #include <SALOMEDS_Attributes_wrap.hxx>
62 #include <SALOMEDS_wrap.hxx>
63 #include <Utils_ExceptHandlers.hxx>
64 #include <utilities.h>
66 #include <GEOMImpl_Types.hxx>
67 #include <GEOM_wrap.hxx>
70 #include <BRep_Builder.hxx>
71 #include <Standard_ErrorHandler.hxx>
72 #include <TColStd_MapOfInteger.hxx>
74 #include <TopExp_Explorer.hxx>
75 #include <TopTools_DataMapOfShapeShape.hxx>
76 #include <TopTools_MapIteratorOfMapOfShape.hxx>
77 #include <TopTools_MapOfShape.hxx>
78 #include <TopoDS_Compound.hxx>
85 #include <vtkUnstructuredGridWriter.h>
87 // to pass CORBA exception through SMESH_TRY
88 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
90 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
93 static int MYDEBUG = 0;
95 static int MYDEBUG = 0;
99 using SMESH::TPythonDump;
102 int SMESH_Mesh_i::_idGenerator = 0;
104 //=============================================================================
108 //=============================================================================
110 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
112 : SALOME::GenericObj_i( thePOA )
116 _id = _idGenerator++;
119 _previewEditor = NULL;
124 //=============================================================================
128 //=============================================================================
130 SMESH_Mesh_i::~SMESH_Mesh_i()
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cached shapes if no more meshes remain; (the cache is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
236 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 if ( aShapeObj->_is_nil() )
239 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
240 // find GEOM_Object by entry (IPAL52735)
241 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
242 for ( ; data != _geomGroupData.end(); ++data )
243 if ( data->_smeshObject->_is_equivalent( _this() ))
245 SALOMEDS::SObject_wrap so = _gen_i->getStudyServant()->FindObjectID( data->_groupEntry.c_str() );
246 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
247 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
253 catch(SALOME_Exception & S_ex) {
254 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
256 return aShapeObj._retn();
259 //================================================================================
261 * \brief Replaces a shape in the mesh
263 //================================================================================
264 void SMESH_Mesh_i::ReplaceShape(GEOM::GEOM_Object_ptr theNewGeom)
265 throw (SALOME::SALOME_Exception)
267 TopoDS_Shape S = _impl->GetShapeToMesh();
268 GEOM_Client* geomClient = _gen_i->GetShapeReader();
269 TCollection_AsciiString aIOR;
270 if (geomClient->Find(S, aIOR)) {
271 geomClient->RemoveShapeFromBuffer(aIOR);
274 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
275 SMESH::SMESH_Mesh_var me = _this();
276 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
277 CORBA::String_var entry = theNewGeom->GetStudyEntry();
278 if ( !aSO->_is_nil() )
280 SALOMEDS::SObject_wrap aShapeRefSO;
281 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
283 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
284 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
285 builder->Addreference( aShapeRefSO, aShapeSO );
289 // re-assign global hypotheses to the new shape
291 CheckGeomModif( true );
293 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
294 << me <<".GetMesh()), " << entry.in() << ")";
296 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
300 //================================================================================
302 * \brief Return false if the mesh is not yet fully loaded from the study file
304 //================================================================================
306 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
308 Unexpect aCatch(SALOME_SalomeException);
309 return !_preMeshInfo;
312 //================================================================================
314 * \brief Load full mesh data from the study file
316 //================================================================================
318 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
320 Unexpect aCatch(SALOME_SalomeException);
322 _preMeshInfo->FullLoadFromFile();
325 //================================================================================
327 * \brief Remove all nodes and elements
329 //================================================================================
331 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
333 Unexpect aCatch(SALOME_SalomeException);
335 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
339 //CheckGeomGroupModif(); // issue 20145
341 catch(SALOME_Exception & S_ex) {
342 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
345 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
347 SMESH::SMESH_Mesh_var mesh = _this();
348 _gen_i->UpdateIcons( mesh );
351 //================================================================================
353 * \brief Remove all nodes and elements for indicated shape
355 //================================================================================
357 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
358 throw (SALOME::SALOME_Exception)
360 Unexpect aCatch(SALOME_SalomeException);
362 _preMeshInfo->FullLoadFromFile();
365 _impl->ClearSubMesh( ShapeID );
367 catch(SALOME_Exception & S_ex) {
368 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
370 _impl->GetMeshDS()->Modified();
372 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
375 //=============================================================================
377 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
379 //=============================================================================
381 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
383 SMESH::DriverMED_ReadStatus res;
386 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
387 res = SMESH::DRS_OK; break;
388 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
389 res = SMESH::DRS_EMPTY; break;
390 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
391 res = SMESH::DRS_WARN_RENUMBER; break;
392 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
393 res = SMESH::DRS_WARN_SKIP_ELEM; break;
394 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
395 res = SMESH::DRS_WARN_DESCENDING; break;
396 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
398 res = SMESH::DRS_FAIL; break;
403 //=============================================================================
405 * Convert ::SMESH_ComputeError to SMESH::ComputeError
407 //=============================================================================
409 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
411 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
412 errVar->subShapeID = -1;
413 errVar->hasBadMesh = false;
415 if ( !errorPtr || errorPtr->IsOK() )
417 errVar->code = SMESH::COMPERR_OK;
421 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
422 errVar->comment = errorPtr->myComment.c_str();
424 return errVar._retn();
427 //=============================================================================
431 * Imports mesh data from MED file
433 //=============================================================================
435 SMESH::DriverMED_ReadStatus
436 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
437 throw ( SALOME::SALOME_Exception )
439 Unexpect aCatch(SALOME_SalomeException);
442 status = _impl->MEDToMesh( theFileName, theMeshName );
444 catch( SALOME_Exception& S_ex ) {
445 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
448 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
451 CreateGroupServants();
453 int major, minor, release;
454 major = minor = release = 0;
455 MED::GetMEDVersion(theFileName, major, minor, release);
456 _medFileInfo = new SMESH::MedFileInfo();
457 _medFileInfo->fileName = theFileName;
458 _medFileInfo->fileSize = 0;
459 _medFileInfo->major = major;
460 _medFileInfo->minor = minor;
461 _medFileInfo->release = release;
462 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
464 return ConvertDriverMEDReadStatus(status);
467 //================================================================================
469 * \brief Imports mesh data from the CGNS file
471 //================================================================================
473 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
474 const int theMeshIndex,
475 std::string& theMeshName )
476 throw ( SALOME::SALOME_Exception )
478 Unexpect aCatch(SALOME_SalomeException);
481 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
483 catch( SALOME_Exception& S_ex ) {
484 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
487 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
490 CreateGroupServants();
492 _medFileInfo = new SMESH::MedFileInfo();
493 _medFileInfo->fileName = theFileName;
494 _medFileInfo->major = 0;
495 _medFileInfo->minor = 0;
496 _medFileInfo->release = 0;
497 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
499 return ConvertDriverMEDReadStatus(status);
502 //================================================================================
504 * \brief Return string representation of a MED file version comprising nbDigits
506 //================================================================================
508 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
510 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
512 return CORBA::string_dup( ver.c_str() );
515 //================================================================================
517 * Return the list of med versions compatibles for write/append,
518 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
520 //================================================================================
521 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
523 SMESH::long_array_var aResult = new SMESH::long_array();
524 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
525 long nbver = mvok.size();
526 aResult->length( nbver );
527 for ( int i = 0; i < nbver; i++ )
528 aResult[i] = mvok[i];
529 return aResult._retn();
532 //=============================================================================
536 * Imports mesh data from MED file
538 //=============================================================================
540 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
541 throw ( SALOME::SALOME_Exception )
545 // Read mesh with name = <theMeshName> into SMESH_Mesh
546 _impl->UNVToMesh( theFileName );
548 CreateGroupServants();
550 _medFileInfo = new SMESH::MedFileInfo();
551 _medFileInfo->fileName = theFileName;
552 _medFileInfo->major = 0;
553 _medFileInfo->minor = 0;
554 _medFileInfo->release = 0;
555 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
557 SMESH_CATCH( SMESH::throwCorbaException );
562 //=============================================================================
566 * Imports mesh data from STL file
568 //=============================================================================
569 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
570 throw ( SALOME::SALOME_Exception )
574 // Read mesh with name = <theMeshName> into SMESH_Mesh
575 std::string name = _impl->STLToMesh( theFileName );
578 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
579 _gen_i->SetName( meshSO, name.c_str() );
581 _medFileInfo = new SMESH::MedFileInfo();
582 _medFileInfo->fileName = theFileName;
583 _medFileInfo->major = 0;
584 _medFileInfo->minor = 0;
585 _medFileInfo->release = 0;
586 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
588 SMESH_CATCH( SMESH::throwCorbaException );
593 //================================================================================
595 * \brief Function used in SMESH_CATCH by ImportGMFFile()
597 //================================================================================
601 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
603 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
607 //================================================================================
609 * \brief Imports data from a GMF file and returns an error description
611 //================================================================================
613 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
614 bool theMakeRequiredGroups )
615 throw (SALOME::SALOME_Exception)
617 SMESH_ComputeErrorPtr error;
620 #define SMESH_CAUGHT error =
623 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
625 _medFileInfo = new SMESH::MedFileInfo();
626 _medFileInfo->fileName = theFileName;
627 _medFileInfo->major = 0;
628 _medFileInfo->minor = 0;
629 _medFileInfo->release = 0;
630 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
632 SMESH_CATCH( exceptionToComputeError );
636 CreateGroupServants();
638 return ConvertComputeError( error );
641 //=============================================================================
645 //=============================================================================
647 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
649 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
650 (SMESH_Hypothesis::Hypothesis_Status theStatus)
653 RETURNCASE( HYP_OK );
654 RETURNCASE( HYP_MISSING );
655 RETURNCASE( HYP_CONCURRENT );
656 RETURNCASE( HYP_BAD_PARAMETER );
657 RETURNCASE( HYP_HIDDEN_ALGO );
658 RETURNCASE( HYP_HIDING_ALGO );
659 RETURNCASE( HYP_UNKNOWN_FATAL );
660 RETURNCASE( HYP_INCOMPATIBLE );
661 RETURNCASE( HYP_NOTCONFORM );
662 RETURNCASE( HYP_ALREADY_EXIST );
663 RETURNCASE( HYP_BAD_DIM );
664 RETURNCASE( HYP_BAD_SUBSHAPE );
665 RETURNCASE( HYP_BAD_GEOMETRY );
666 RETURNCASE( HYP_NEED_SHAPE );
667 RETURNCASE( HYP_INCOMPAT_HYPS );
670 return SMESH::HYP_UNKNOWN_FATAL;
673 //=============================================================================
677 * calls internal addHypothesis() and then adds a reference to <anHyp> under
678 * the SObject actually having a reference to <aSubShape>.
679 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
681 //=============================================================================
683 SMESH::Hypothesis_Status
684 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
685 SMESH::SMESH_Hypothesis_ptr anHyp,
686 CORBA::String_out anErrorText)
687 throw(SALOME::SALOME_Exception)
689 Unexpect aCatch(SALOME_SalomeException);
691 _preMeshInfo->ForgetOrLoad();
693 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
696 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
697 anErrorText = error.c_str();
699 SMESH::SMESH_Mesh_var mesh( _this() );
700 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
702 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
704 int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
705 if ( newNbMeshEnt != prevNbMeshEnt )
706 _gen_i->UpdateIcons( mesh );
708 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
710 // Update Python script
711 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
712 << aSubShape << ", " << anHyp << " )";
714 return ConvertHypothesisStatus(status);
717 //=============================================================================
721 //=============================================================================
723 SMESH_Hypothesis::Hypothesis_Status
724 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
725 SMESH::SMESH_Hypothesis_ptr anHyp,
726 std::string* anErrorText)
728 if(MYDEBUG) MESSAGE("addHypothesis");
730 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
731 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
733 if (CORBA::is_nil( anHyp ))
734 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
736 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
739 TopoDS_Shape myLocSubShape;
740 //use PseudoShape in case if mesh has no shape
742 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
744 myLocSubShape = _impl->GetShapeToMesh();
746 const int hypId = anHyp->GetId();
748 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
749 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
751 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
753 // assure there is a corresponding submesh
754 if ( !_impl->IsMainShape( myLocSubShape )) {
755 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
756 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
757 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
760 else if ( anErrorText )
762 *anErrorText = error;
765 catch(SALOME_Exception & S_ex)
767 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
772 //=============================================================================
776 //=============================================================================
778 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
779 SMESH::SMESH_Hypothesis_ptr anHyp)
780 throw(SALOME::SALOME_Exception)
782 Unexpect aCatch(SALOME_SalomeException);
784 _preMeshInfo->ForgetOrLoad();
786 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
787 SMESH::SMESH_Mesh_var mesh = _this();
789 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
791 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
792 _gen_i->UpdateIcons( mesh );
794 // Update Python script
795 if(_impl->HasShapeToMesh())
796 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
797 << aSubShape << ", " << anHyp << " )";
799 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
802 return ConvertHypothesisStatus(status);
805 //=============================================================================
809 //=============================================================================
811 SMESH_Hypothesis::Hypothesis_Status
812 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
813 SMESH::SMESH_Hypothesis_ptr anHyp)
815 if(MYDEBUG) MESSAGE("removeHypothesis()");
817 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
818 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
820 if (CORBA::is_nil( anHyp ))
821 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
824 _preMeshInfo->ForgetOrLoad();
826 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
829 TopoDS_Shape myLocSubShape;
830 //use PseudoShape in case if mesh has no shape
831 if( _impl->HasShapeToMesh() )
832 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
834 myLocSubShape = _impl->GetShapeToMesh();
836 const int hypId = anHyp->GetId();
837 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
838 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
840 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
844 catch(SALOME_Exception & S_ex)
846 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
851 //=============================================================================
855 //=============================================================================
857 SMESH::ListOfHypothesis *
858 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
859 throw(SALOME::SALOME_Exception)
861 Unexpect aCatch(SALOME_SalomeException);
862 if (MYDEBUG) MESSAGE("GetHypothesisList");
863 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
864 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
866 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
869 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
870 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
871 myLocSubShape = _impl->GetShapeToMesh();
872 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
873 int i = 0, n = aLocalList.size();
876 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
877 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
878 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
880 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
881 if ( id_hypptr != _mapHypo.end() )
882 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
886 catch(SALOME_Exception & S_ex) {
887 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
890 return aList._retn();
893 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
895 Unexpect aCatch(SALOME_SalomeException);
896 if (MYDEBUG) MESSAGE("GetSubMeshes");
898 SMESH::submesh_array_var aList = new SMESH::submesh_array();
901 TPythonDump aPythonDump;
902 if ( !_mapSubMeshIor.empty() )
906 aList->length( _mapSubMeshIor.size() );
908 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
909 for ( ; it != _mapSubMeshIor.end(); it++ ) {
910 if ( CORBA::is_nil( it->second )) continue;
911 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
913 if (i > 1) aPythonDump << ", ";
914 aPythonDump << it->second;
918 catch(SALOME_Exception & S_ex) {
919 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
922 // Update Python script
923 if ( !_mapSubMeshIor.empty() )
924 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
926 return aList._retn();
929 //=============================================================================
933 //=============================================================================
935 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
936 const char* theName )
937 throw(SALOME::SALOME_Exception)
939 Unexpect aCatch(SALOME_SalomeException);
940 if (CORBA::is_nil(aSubShape))
941 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
943 SMESH::SMESH_subMesh_var subMesh;
944 SMESH::SMESH_Mesh_var aMesh = _this();
946 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
948 //Get or Create the SMESH_subMesh object implementation
950 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
952 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
954 TopoDS_Iterator it( myLocSubShape );
956 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
958 subMesh = getSubMesh( subMeshId );
960 // create a new subMesh object servant if there is none for the shape
961 if ( subMesh->_is_nil() )
962 subMesh = createSubMesh( aSubShape );
963 if ( _gen_i->CanPublishInStudy( subMesh ))
965 SALOMEDS::SObject_wrap aSO =
966 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
967 if ( !aSO->_is_nil()) {
968 // Update Python script
969 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
970 << aSubShape << ", '" << theName << "' )";
974 catch(SALOME_Exception & S_ex) {
975 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
977 return subMesh._retn();
980 //=============================================================================
984 //=============================================================================
986 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
987 throw (SALOME::SALOME_Exception)
991 if ( theSubMesh->_is_nil() )
994 GEOM::GEOM_Object_var aSubShape;
995 // Remove submesh's SObject
996 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
997 if ( !anSO->_is_nil() ) {
998 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
999 SALOMEDS::SObject_wrap anObj, aRef;
1000 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
1001 anObj->ReferencedObject( aRef.inout() ))
1003 CORBA::Object_var obj = aRef->GetObject();
1004 aSubShape = GEOM::GEOM_Object::_narrow( obj );
1006 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
1007 // aSubShape = theSubMesh->GetSubShape();
1009 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
1010 builder->RemoveObjectWithChildren( anSO );
1012 // Update Python script
1013 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1016 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1018 _preMeshInfo->ForgetOrLoad();
1020 SMESH_CATCH( SMESH::throwCorbaException );
1023 //=============================================================================
1027 //=============================================================================
1029 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1030 const char* theName )
1031 throw(SALOME::SALOME_Exception)
1033 Unexpect aCatch(SALOME_SalomeException);
1035 _preMeshInfo->FullLoadFromFile();
1037 SMESH::SMESH_Group_var aNewGroup =
1038 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1040 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1042 SMESH::SMESH_Mesh_var mesh = _this();
1043 SALOMEDS::SObject_wrap aSO =
1044 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1045 if ( !aSO->_is_nil())
1046 // Update Python script
1047 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1048 << theElemType << ", '" << theName << "' )";
1050 return aNewGroup._retn();
1053 //=============================================================================
1057 //=============================================================================
1058 SMESH::SMESH_GroupOnGeom_ptr
1059 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1060 const char* theName,
1061 GEOM::GEOM_Object_ptr theGeomObj)
1062 throw(SALOME::SALOME_Exception)
1064 Unexpect aCatch(SALOME_SalomeException);
1066 _preMeshInfo->FullLoadFromFile();
1068 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1070 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1071 if ( !aShape.IsNull() )
1074 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1076 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1078 SMESH::SMESH_Mesh_var mesh = _this();
1079 SALOMEDS::SObject_wrap aSO =
1080 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1081 if ( !aSO->_is_nil())
1082 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1083 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1087 return aNewGroup._retn();
1090 //================================================================================
1092 * \brief Creates a group whose contents is defined by filter
1093 * \param theElemType - group type
1094 * \param theName - group name
1095 * \param theFilter - the filter
1096 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1098 //================================================================================
1100 SMESH::SMESH_GroupOnFilter_ptr
1101 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1102 const char* theName,
1103 SMESH::Filter_ptr theFilter )
1104 throw (SALOME::SALOME_Exception)
1106 Unexpect aCatch(SALOME_SalomeException);
1108 _preMeshInfo->FullLoadFromFile();
1110 if ( CORBA::is_nil( theFilter ))
1111 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1113 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1115 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1117 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1118 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1121 if ( !aNewGroup->_is_nil() )
1122 aNewGroup->SetFilter( theFilter );
1124 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1126 SMESH::SMESH_Mesh_var mesh = _this();
1127 SALOMEDS::SObject_wrap aSO =
1128 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1130 if ( !aSO->_is_nil())
1131 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1132 << theElemType << ", '" << theName << "', " << theFilter << " )";
1134 return aNewGroup._retn();
1137 //=============================================================================
1141 //=============================================================================
1143 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1144 throw (SALOME::SALOME_Exception)
1146 if ( theGroup->_is_nil() )
1151 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1155 if ( aGroup->GetMeshServant() != this )
1156 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1157 SALOME::BAD_PARAM );
1159 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1160 if ( !aGroupSO->_is_nil() )
1162 // Update Python script
1163 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1165 // Remove group's SObject
1166 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1167 builder->RemoveObjectWithChildren( aGroupSO );
1169 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1171 // Remove the group from SMESH data structures
1172 removeGroup( aGroup->GetLocalID() );
1174 SMESH_CATCH( SMESH::throwCorbaException );
1177 //=============================================================================
1179 * Remove group with its contents
1181 //=============================================================================
1183 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1184 throw (SALOME::SALOME_Exception)
1188 _preMeshInfo->FullLoadFromFile();
1190 if ( theGroup->_is_nil() )
1193 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1194 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1195 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1198 vector<int> nodeIds; // to remove nodes becoming free
1199 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1200 if ( !isNodal && !theGroup->IsEmpty() )
1202 CORBA::Long elemID = theGroup->GetID( 1 );
1203 int nbElemNodes = GetElemNbNodes( elemID );
1204 if ( nbElemNodes > 0 )
1205 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1208 // Retrieve contents
1209 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1210 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1211 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1212 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1213 elems.assign( elemBeg, elemEnd );
1215 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1218 RemoveGroup( theGroup );
1221 for ( size_t i = 0; i < elems.size(); ++i )
1223 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1227 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1228 nodeIds.push_back( nIt->next()->GetID() );
1230 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1234 _impl->GetMeshDS()->RemoveElement( elems[i] );
1238 // Remove free nodes
1239 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1240 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1241 if ( n->NbInverseElements() == 0 )
1242 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1244 // Update Python script (theGroup must be alive for this)
1245 pyDump << SMESH::SMESH_Mesh_var(_this())
1246 << ".RemoveGroupWithContents( " << theGroup << " )";
1248 SMESH_CATCH( SMESH::throwCorbaException );
1251 //================================================================================
1253 * \brief Get the list of groups existing in the mesh
1254 * \retval SMESH::ListOfGroups * - list of groups
1256 //================================================================================
1258 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1260 Unexpect aCatch(SALOME_SalomeException);
1261 if (MYDEBUG) MESSAGE("GetGroups");
1263 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1266 TPythonDump aPythonDump;
1267 if ( !_mapGroups.empty() )
1269 aPythonDump << "[ ";
1271 aList->length( _mapGroups.size() );
1273 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1274 for ( ; it != _mapGroups.end(); it++ ) {
1275 if ( CORBA::is_nil( it->second )) continue;
1276 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1278 if (i > 1) aPythonDump << ", ";
1279 aPythonDump << it->second;
1283 catch(SALOME_Exception & S_ex) {
1284 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1286 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1288 return aList._retn();
1291 //=============================================================================
1293 * Get number of groups existing in the mesh
1295 //=============================================================================
1297 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1299 Unexpect aCatch(SALOME_SalomeException);
1300 return _mapGroups.size();
1303 //=============================================================================
1305 * New group including all mesh elements present in initial groups is created.
1307 //=============================================================================
1309 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1310 SMESH::SMESH_GroupBase_ptr theGroup2,
1311 const char* theName )
1312 throw (SALOME::SALOME_Exception)
1314 SMESH::SMESH_Group_var aResGrp;
1318 _preMeshInfo->FullLoadFromFile();
1320 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1321 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1323 if ( theGroup1->GetType() != theGroup2->GetType() )
1324 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1329 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1330 if ( aResGrp->_is_nil() )
1331 return SMESH::SMESH_Group::_nil();
1333 aResGrp->AddFrom( theGroup1 );
1334 aResGrp->AddFrom( theGroup2 );
1336 // Update Python script
1337 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1338 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1340 SMESH_CATCH( SMESH::throwCorbaException );
1342 return aResGrp._retn();
1345 //=============================================================================
1347 * \brief New group including all mesh elements present in initial groups is created.
1348 * \param theGroups list of groups
1349 * \param theName name of group to be created
1350 * \return pointer to the new group
1352 //=============================================================================
1354 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1355 const char* theName )
1356 throw (SALOME::SALOME_Exception)
1358 SMESH::SMESH_Group_var aResGrp;
1361 _preMeshInfo->FullLoadFromFile();
1364 return SMESH::SMESH_Group::_nil();
1369 SMESH::ElementType aType = SMESH::ALL;
1370 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1372 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1373 if ( CORBA::is_nil( aGrp ) )
1375 if ( aType == SMESH::ALL )
1376 aType = aGrp->GetType();
1377 else if ( aType != aGrp->GetType() )
1378 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1381 if ( aType == SMESH::ALL )
1382 return SMESH::SMESH_Group::_nil();
1387 aResGrp = CreateGroup( aType, theName );
1388 if ( aResGrp->_is_nil() )
1389 return SMESH::SMESH_Group::_nil();
1391 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1392 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1394 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1395 if ( !CORBA::is_nil( aGrp ) )
1397 aResGrp->AddFrom( aGrp );
1398 if ( g > 0 ) pyDump << ", ";
1402 pyDump << " ], '" << theName << "' )";
1404 SMESH_CATCH( SMESH::throwCorbaException );
1406 return aResGrp._retn();
1409 //=============================================================================
1411 * New group is created. All mesh elements that are
1412 * present in both initial groups are added to the new one.
1414 //=============================================================================
1416 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1417 SMESH::SMESH_GroupBase_ptr theGroup2,
1418 const char* theName )
1419 throw (SALOME::SALOME_Exception)
1421 SMESH::SMESH_Group_var aResGrp;
1426 _preMeshInfo->FullLoadFromFile();
1428 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1429 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1431 if ( theGroup1->GetType() != theGroup2->GetType() )
1432 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1436 // Create Intersection
1437 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1438 if ( aResGrp->_is_nil() )
1439 return aResGrp._retn();
1441 SMESHDS_GroupBase* groupDS1 = 0;
1442 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1443 groupDS1 = grp_i->GetGroupDS();
1445 SMESHDS_GroupBase* groupDS2 = 0;
1446 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1447 groupDS2 = grp_i->GetGroupDS();
1449 SMESHDS_Group* resGroupDS = 0;
1450 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1451 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1453 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1455 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1456 while ( elemIt1->more() )
1458 const SMDS_MeshElement* e = elemIt1->next();
1459 if ( groupDS2->Contains( e ))
1460 resGroupDS->SMDSGroup().Add( e );
1463 // Update Python script
1464 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1465 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1467 SMESH_CATCH( SMESH::throwCorbaException );
1469 return aResGrp._retn();
1472 //=============================================================================
1474 \brief Intersect list of groups. New group is created. All mesh elements that
1475 are present in all initial groups simultaneously are added to the new one.
1476 \param theGroups list of groups
1477 \param theName name of group to be created
1478 \return pointer on the group
1480 //=============================================================================
1481 SMESH::SMESH_Group_ptr
1482 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1483 const char* theName )
1484 throw (SALOME::SALOME_Exception)
1486 SMESH::SMESH_Group_var aResGrp;
1491 _preMeshInfo->FullLoadFromFile();
1494 return SMESH::SMESH_Group::_nil();
1496 // check types and get SMESHDS_GroupBase's
1497 SMESH::ElementType aType = SMESH::ALL;
1498 vector< SMESHDS_GroupBase* > groupVec;
1499 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1501 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1502 if ( CORBA::is_nil( aGrp ) )
1504 if ( aType == SMESH::ALL )
1505 aType = aGrp->GetType();
1506 else if ( aType != aGrp->GetType() )
1507 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1510 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1511 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1513 if ( grpDS->IsEmpty() )
1518 groupVec.push_back( grpDS );
1521 if ( aType == SMESH::ALL ) // all groups are nil
1522 return SMESH::SMESH_Group::_nil();
1527 aResGrp = CreateGroup( aType, theName );
1529 SMESHDS_Group* resGroupDS = 0;
1530 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1531 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1532 if ( !resGroupDS || groupVec.empty() )
1533 return aResGrp._retn();
1536 size_t i, nb = groupVec.size();
1537 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1538 while ( elemIt1->more() )
1540 const SMDS_MeshElement* e = elemIt1->next();
1542 for ( i = 1; ( i < nb && inAll ); ++i )
1543 inAll = groupVec[i]->Contains( e );
1546 resGroupDS->SMDSGroup().Add( e );
1549 // Update Python script
1550 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1551 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1553 SMESH_CATCH( SMESH::throwCorbaException );
1555 return aResGrp._retn();
1558 //=============================================================================
1560 * New group is created. All mesh elements that are present in
1561 * a main group but is not present in a tool group are added to the new one
1563 //=============================================================================
1565 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1566 SMESH::SMESH_GroupBase_ptr theGroup2,
1567 const char* theName )
1568 throw (SALOME::SALOME_Exception)
1570 SMESH::SMESH_Group_var aResGrp;
1575 _preMeshInfo->FullLoadFromFile();
1577 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1578 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1580 if ( theGroup1->GetType() != theGroup2->GetType() )
1581 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1585 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1586 if ( aResGrp->_is_nil() )
1587 return aResGrp._retn();
1589 SMESHDS_GroupBase* groupDS1 = 0;
1590 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1591 groupDS1 = grp_i->GetGroupDS();
1593 SMESHDS_GroupBase* groupDS2 = 0;
1594 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1595 groupDS2 = grp_i->GetGroupDS();
1597 SMESHDS_Group* resGroupDS = 0;
1598 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1599 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1601 if ( groupDS1 && groupDS2 && resGroupDS )
1603 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1604 while ( elemIt1->more() )
1606 const SMDS_MeshElement* e = elemIt1->next();
1607 if ( !groupDS2->Contains( e ))
1608 resGroupDS->SMDSGroup().Add( e );
1611 // Update Python script
1612 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1613 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1615 SMESH_CATCH( SMESH::throwCorbaException );
1617 return aResGrp._retn();
1620 //=============================================================================
1622 \brief Cut lists of groups. New group is created. All mesh elements that are
1623 present in main groups but do not present in tool groups are added to the new one
1624 \param theMainGroups list of main groups
1625 \param theToolGroups list of tool groups
1626 \param theName name of group to be created
1627 \return pointer on the group
1629 //=============================================================================
1630 SMESH::SMESH_Group_ptr
1631 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1632 const SMESH::ListOfGroups& theToolGroups,
1633 const char* theName )
1634 throw (SALOME::SALOME_Exception)
1636 SMESH::SMESH_Group_var aResGrp;
1641 _preMeshInfo->FullLoadFromFile();
1644 return SMESH::SMESH_Group::_nil();
1646 // check types and get SMESHDS_GroupBase's
1647 SMESH::ElementType aType = SMESH::ALL;
1648 vector< SMESHDS_GroupBase* > toolGroupVec;
1649 vector< SMDS_ElemIteratorPtr > mainIterVec;
1651 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1653 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1654 if ( CORBA::is_nil( aGrp ) )
1656 if ( aType == SMESH::ALL )
1657 aType = aGrp->GetType();
1658 else if ( aType != aGrp->GetType() )
1659 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1661 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1662 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1663 if ( !grpDS->IsEmpty() )
1664 mainIterVec.push_back( grpDS->GetElements() );
1666 if ( aType == SMESH::ALL ) // all main groups are nil
1667 return SMESH::SMESH_Group::_nil();
1668 if ( mainIterVec.empty() ) // all main groups are empty
1669 return aResGrp._retn();
1671 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1673 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1674 if ( CORBA::is_nil( aGrp ) )
1676 if ( aType != aGrp->GetType() )
1677 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1679 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1680 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1681 toolGroupVec.push_back( grpDS );
1687 aResGrp = CreateGroup( aType, theName );
1689 SMESHDS_Group* resGroupDS = 0;
1690 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1691 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1693 return aResGrp._retn();
1696 size_t i, nb = toolGroupVec.size();
1697 SMDS_ElemIteratorPtr mainElemIt
1698 ( new SMDS_IteratorOnIterators
1699 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1700 while ( mainElemIt->more() )
1702 const SMDS_MeshElement* e = mainElemIt->next();
1704 for ( i = 0; ( i < nb && !isIn ); ++i )
1705 isIn = toolGroupVec[i]->Contains( e );
1708 resGroupDS->SMDSGroup().Add( e );
1711 // Update Python script
1712 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1713 << ".CutListOfGroups( " << theMainGroups << ", "
1714 << theToolGroups << ", '" << theName << "' )";
1716 SMESH_CATCH( SMESH::throwCorbaException );
1718 return aResGrp._retn();
1721 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1723 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1724 bool & toStopChecking )
1726 toStopChecking = ( nbCommon < nbChecked );
1727 return nbCommon == nbNodes;
1729 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1730 bool & toStopChecking )
1732 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1733 return nbCommon == nbCorners;
1735 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1736 bool & toStopChecking )
1738 return nbCommon > 0;
1740 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1741 bool & toStopChecking )
1743 return nbCommon >= (nbNodes+1) / 2;
1747 //=============================================================================
1749 * Create a group of entities basing on nodes of other groups.
1750 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1751 * \param [in] anElemType - a type of elements to include to the new group.
1752 * \param [in] theName - a name of the new group.
1753 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1754 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1755 * new group provided that it is based on nodes of an element of \a aListOfGroups
1756 * \return SMESH_Group - the created group
1758 // IMP 19939, bug 22010, IMP 22635
1759 //=============================================================================
1761 SMESH::SMESH_Group_ptr
1762 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1763 SMESH::ElementType theElemType,
1764 const char* theName,
1765 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1766 CORBA::Boolean theUnderlyingOnly)
1767 throw (SALOME::SALOME_Exception)
1769 SMESH::SMESH_Group_var aResGrp;
1773 _preMeshInfo->FullLoadFromFile();
1775 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1777 if ( !theName || !aMeshDS )
1778 return SMESH::SMESH_Group::_nil();
1780 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1782 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1783 SMESH_Comment nbCoNoStr( "SMESH.");
1784 switch ( theNbCommonNodes ) {
1785 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1786 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1787 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1788 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1789 default: return aResGrp._retn();
1791 int nbChecked, nbCommon, nbNodes, nbCorners;
1797 aResGrp = CreateGroup( theElemType, theName );
1798 if ( aResGrp->_is_nil() )
1799 return SMESH::SMESH_Group::_nil();
1801 SMESHDS_GroupBase* groupBaseDS =
1802 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1803 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1805 vector<bool> isNodeInGroups;
1807 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1809 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1810 if ( CORBA::is_nil( aGrp ) )
1812 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1813 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1816 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1817 if ( !elIt ) continue;
1819 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1821 while ( elIt->more() ) {
1822 const SMDS_MeshElement* el = elIt->next();
1823 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1824 while ( nIt->more() )
1825 resGroupCore.Add( nIt->next() );
1828 // get elements of theElemType based on nodes of every element of group
1829 else if ( theUnderlyingOnly )
1831 while ( elIt->more() )
1833 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1834 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1835 TIDSortedElemSet checkedElems;
1836 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1837 while ( nIt->more() )
1839 const SMDS_MeshNode* n = nIt->next();
1840 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1841 // check nodes of elements of theElemType around el
1842 while ( elOfTypeIt->more() )
1844 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1845 if ( !checkedElems.insert( elOfType ).second ) continue;
1846 nbNodes = elOfType->NbNodes();
1847 nbCorners = elOfType->NbCornerNodes();
1849 bool toStopChecking = false;
1850 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1851 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1852 if ( elNodes.count( nIt2->next() ) &&
1853 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1855 resGroupCore.Add( elOfType );
1862 // get all nodes of elements of groups
1865 while ( elIt->more() )
1867 const SMDS_MeshElement* el = elIt->next(); // an element of group
1868 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1869 while ( nIt->more() )
1871 const SMDS_MeshNode* n = nIt->next();
1872 if ( n->GetID() >= (int) isNodeInGroups.size() )
1873 isNodeInGroups.resize( n->GetID() + 1, false );
1874 isNodeInGroups[ n->GetID() ] = true;
1880 // Get elements of theElemType based on a certain number of nodes of elements of groups
1881 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1883 const SMDS_MeshNode* n;
1884 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1885 const int isNodeInGroupsSize = isNodeInGroups.size();
1886 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1888 if ( !isNodeInGroups[ iN ] ||
1889 !( n = aMeshDS->FindNode( iN )))
1892 // check nodes of elements of theElemType around n
1893 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1894 while ( elOfTypeIt->more() )
1896 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1897 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1902 nbNodes = elOfType->NbNodes();
1903 nbCorners = elOfType->NbCornerNodes();
1905 bool toStopChecking = false;
1906 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1907 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1909 const int nID = nIt->next()->GetID();
1910 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1911 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1913 resGroupCore.Add( elOfType );
1921 // Update Python script
1922 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1923 << ".CreateDimGroup( "
1924 << theGroups << ", " << theElemType << ", '" << theName << "', "
1925 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1927 SMESH_CATCH( SMESH::throwCorbaException );
1929 return aResGrp._retn();
1932 //================================================================================
1934 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1935 * existing 1D elements as group boundaries.
1936 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1937 * adjacent faces is more than \a sharpAngle in degrees.
1938 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1939 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1940 * \return ListOfGroups - the created groups
1942 //================================================================================
1944 SMESH::ListOfGroups*
1945 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1946 CORBA::Boolean theCreateEdges,
1947 CORBA::Boolean theUseExistingEdges )
1948 throw (SALOME::SALOME_Exception)
1950 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1951 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1954 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1960 _preMeshInfo->FullLoadFromFile();
1962 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1964 std::vector< SMESH_MeshAlgos::Edge > edges =
1965 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1967 if ( theCreateEdges )
1969 std::vector<const SMDS_MeshNode *> nodes(2);
1970 for ( size_t i = 0; i < edges.size(); ++i )
1972 nodes[0] = edges[i]._node1;
1973 nodes[1] = edges[i]._node2;
1974 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1976 if ( edges[i]._medium )
1977 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1979 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1983 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1984 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1986 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1988 resultGroups->length( faceGroups.size() );
1989 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
1991 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
1992 _editor->GenerateGroupName("Group").c_str());
1993 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
1995 SMESHDS_GroupBase* groupBaseDS =
1996 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
1997 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1999 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
2000 for ( size_t i = 0; i < faces.size(); ++i )
2001 groupCore.Add( faces[i] );
2004 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
2005 << ".FaceGroupsSeparatedByEdges( "
2006 << TVar( theSharpAngle ) << ", "
2007 << theCreateEdges << ", "
2008 << theUseExistingEdges << " )";
2010 SMESH_CATCH( SMESH::throwCorbaException );
2011 return resultGroups._retn();
2015 //================================================================================
2017 * \brief Remember GEOM group data
2019 //================================================================================
2021 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2022 CORBA::Object_ptr theSmeshObj)
2024 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2027 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2028 if ( groupSO->_is_nil() )
2031 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2032 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2033 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2036 _geomGroupData.push_back( TGeomGroupData() );
2037 TGeomGroupData & groupData = _geomGroupData.back();
2039 CORBA::String_var entry = groupSO->GetID();
2040 groupData._groupEntry = entry.in();
2042 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2043 groupData._indices.insert( ids[i] );
2045 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2046 // shape index in SMESHDS
2047 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2048 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2051 //================================================================================
2053 * Remove GEOM group data relating to removed smesh object
2055 //================================================================================
2057 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2059 list<TGeomGroupData>::iterator
2060 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2061 for ( ; data != dataEnd; ++data ) {
2062 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2063 _geomGroupData.erase( data );
2069 //================================================================================
2071 * \brief Return new group contents if it has been changed and update group data
2073 //================================================================================
2074 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2076 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2078 TopoDS_Shape newShape;
2080 if ( how == IS_BREAK_LINK )
2082 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2083 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2084 if ( !meshSO->_is_nil() &&
2085 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2086 geomRefSO->ReferencedObject( geomSO.inout() ))
2088 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2089 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2090 newShape = _gen_i->GeomObjectToShape( geom );
2091 CORBA::String_var entry = geom->GetStudyEntry();
2092 groupData._groupEntry = entry.in();
2098 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2099 if ( !groupSO->_is_nil() )
2101 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2102 if ( CORBA::is_nil( groupObj )) return newShape;
2103 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2105 // get indices of group items
2106 set<int> curIndices;
2107 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2108 GEOM::GEOM_IGroupOperations_ptr groupOp = geomGen->GetIGroupOperations();
2109 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2110 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2111 curIndices.insert( ids[i] );
2113 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2114 return newShape; // group not changed
2117 groupData._indices = curIndices;
2119 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2120 if ( !geomClient ) return newShape;
2121 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2122 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2123 newShape = _gen_i->GeomObjectToShape( geomGroup );
2126 if ( newShape.IsNull() ) {
2127 // geom group becomes empty - return empty compound
2128 TopoDS_Compound compound;
2129 BRep_Builder().MakeCompound(compound);
2130 newShape = compound;
2137 //-----------------------------------------------------------------------------
2139 * \brief Storage of shape and index used in CheckGeomGroupModif()
2141 struct TIndexedShape
2144 TopoDS_Shape _shape;
2145 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2147 //-----------------------------------------------------------------------------
2149 * \brief Data to re-create a group on geometry
2151 struct TGroupOnGeomData
2154 TopoDS_Shape _shape;
2155 SMDSAbs_ElementType _type;
2157 Quantity_Color _color;
2159 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2161 _oldID = group->GetID();
2162 _type = group->GetType();
2163 _name = group->GetStoreName();
2164 _color = group->GetColor();
2168 //-----------------------------------------------------------------------------
2170 * \brief Check if a filter is still valid after geometry removal
2172 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2174 if ( theFilter->_is_nil() )
2176 SMESH::Filter::Criteria_var criteria;
2177 theFilter->GetCriteria( criteria.out() );
2179 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2181 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2183 switch ( criteria[ iCr ].Type )
2185 case SMESH::FT_BelongToGeom:
2186 case SMESH::FT_BelongToPlane:
2187 case SMESH::FT_BelongToCylinder:
2188 case SMESH::FT_BelongToGenSurface:
2189 case SMESH::FT_LyingOnGeom:
2190 entry = thresholdID;
2192 case SMESH::FT_ConnectedElements:
2195 entry = thresholdID;
2201 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2202 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2203 if ( so->_is_nil() )
2205 CORBA::Object_var obj = so->GetObject();
2206 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2207 if ( gen->GeomObjectToShape( geom ).IsNull() )
2210 } // loop on criteria
2216 //=============================================================================
2218 * \brief Update data if geometry changes
2222 //=============================================================================
2224 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2226 SMESH::SMESH_Mesh_var me = _this();
2227 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2229 TPythonDump dumpNothing; // prevent any dump
2231 //bool removedFromClient = false;
2233 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2235 //removedFromClient = _impl->HasShapeToMesh();
2237 // try to find geometry by study reference
2238 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2239 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2240 if ( !meshSO->_is_nil() &&
2241 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2242 geomRefSO->ReferencedObject( geomSO.inout() ))
2244 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2245 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2248 if ( mainGO->_is_nil() && // geometry removed ==>
2249 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2251 // convert geom dependent groups into standalone ones
2252 CheckGeomGroupModif();
2254 _impl->ShapeToMesh( TopoDS_Shape() );
2256 // remove sub-meshes
2257 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2258 while ( i_sm != _mapSubMeshIor.end() )
2260 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2262 RemoveSubMesh( sm );
2264 // remove all children except groups in the study
2265 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2266 SALOMEDS::SObject_wrap so;
2267 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2268 if ( meshSO->FindSubObject( tag, so.inout() ))
2269 builder->RemoveObjectWithChildren( so );
2271 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2277 if ( !_impl->HasShapeToMesh() ) return;
2280 // Update after group modification
2282 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2283 mainGO->GetTick() == _mainShapeTick )
2285 int nb = NbNodes() + NbElements();
2286 CheckGeomGroupModif();
2287 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2288 _gen_i->UpdateIcons( me );
2292 // Update after shape modification
2294 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2295 if ( !geomClient ) return;
2296 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2297 if ( geomGen->_is_nil() ) return;
2299 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2300 geomClient->RemoveShapeFromBuffer( ior.in() );
2302 // Update data taking into account that if topology doesn't change
2303 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2306 _preMeshInfo->ForgetAllData();
2311 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2312 if ( newShape.IsNull() )
2315 _mainShapeTick = mainGO->GetTick();
2317 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2319 // store data of groups on geometry
2320 std::vector< TGroupOnGeomData > groupsData;
2321 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2322 groupsData.reserve( groups.size() );
2323 TopTools_DataMapOfShapeShape old2newShapeMap;
2324 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2325 for ( ; g != groups.end(); ++g )
2327 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2329 groupsData.push_back( TGroupOnGeomData( group ));
2332 SMESH::SMESH_GroupOnGeom_var gog;
2333 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2334 if ( i_grp != _mapGroups.end() )
2335 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2337 GEOM::GEOM_Object_var geom;
2338 if ( !gog->_is_nil() )
2342 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2343 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2344 if ( !grpSO->_is_nil() &&
2345 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2346 geomRefSO->ReferencedObject( geomSO.inout() ))
2348 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2349 geom = GEOM::GEOM_Object::_narrow( geomObj );
2354 geom = gog->GetShape();
2357 if ( !geom->_is_nil() )
2359 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2360 geomClient->RemoveShapeFromBuffer( ior.in() );
2361 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2362 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2364 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2366 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2370 // store assigned hypotheses
2371 std::vector< pair< int, THypList > > ids2Hyps;
2372 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2373 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2375 const TopoDS_Shape& s = s2hyps.Key();
2376 const THypList& hyps = s2hyps.ChangeValue();
2377 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2380 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2382 // count shapes excluding compounds corresponding to geom groups
2383 int oldNbSubShapes = meshDS->MaxShapeIndex();
2384 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2386 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2387 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2390 std::set<int> subIds;
2391 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2392 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2393 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2396 // check if shape topology changes - save shape type per shape ID
2397 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2398 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2399 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2401 // change shape to mesh
2402 _impl->ShapeToMesh( TopoDS_Shape() );
2403 _impl->ShapeToMesh( newShape );
2405 // check if shape topology changes - check new shape types
2406 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2407 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2409 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2410 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2413 // re-add shapes (compounds) of geom groups
2414 std::map< int, int > old2newIDs; // group IDs
2415 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2416 for ( ; data != _geomGroupData.end(); ++data )
2419 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2420 if ( ii2i != ii2iMap.end() )
2421 oldID = ii2i->second;
2423 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2424 if ( !newShape.IsNull() )
2426 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2428 TopoDS_Compound compound;
2429 BRep_Builder().MakeCompound( compound );
2430 BRep_Builder().Add( compound, newShape );
2431 newShape = compound;
2433 int newID = _impl->GetSubMesh( newShape )->GetId();
2434 if ( oldID && oldID != newID )
2435 old2newIDs.insert( std::make_pair( oldID, newID ));
2439 // re-assign hypotheses
2440 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2442 if ( !sameTopology && ids2Hyps[i].first != 1 )
2443 continue; // assign only global hypos
2444 int sID = ids2Hyps[i].first;
2445 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2446 if ( o2n != old2newIDs.end() )
2448 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2449 const THypList& hyps = ids2Hyps[i].second;
2450 THypList::const_iterator h = hyps.begin();
2451 for ( ; h != hyps.end(); ++h )
2452 _impl->AddHypothesis( s, (*h)->GetID() );
2455 if ( !sameTopology )
2457 // remove invalid study sub-objects
2458 CheckGeomGroupModif();
2462 // restore groups on geometry
2463 for ( size_t i = 0; i < groupsData.size(); ++i )
2465 const TGroupOnGeomData& data = groupsData[i];
2466 if ( data._shape.IsNull() )
2469 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2470 if ( i2g == _mapGroups.end() ) continue;
2472 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2473 if ( !gr_i ) continue;
2475 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2477 _mapGroups.erase( i2g );
2479 g->GetGroupDS()->SetColor( data._color );
2482 std::map< int, int >::iterator o2n = old2newIDs.begin();
2483 for ( ; o2n != old2newIDs.end(); ++o2n )
2485 int newID = o2n->second, oldID = o2n->first;
2486 if ( !_mapSubMesh.count( oldID ))
2490 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2491 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2492 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2494 _mapSubMesh. erase(oldID);
2495 _mapSubMesh_i. erase(oldID);
2496 _mapSubMeshIor.erase(oldID);
2498 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2501 // update _mapSubMesh
2502 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2503 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2504 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2507 _gen_i->UpdateIcons( me );
2511 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2512 if ( !meshSO->_is_nil() )
2513 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2517 //=============================================================================
2519 * \brief Update objects depending on changed geom groups
2521 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2522 * issue 0020210: Update of a smesh group after modification of the associated geom group
2524 //=============================================================================
2526 void SMESH_Mesh_i::CheckGeomGroupModif()
2528 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2529 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2530 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2531 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2532 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2534 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2535 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2536 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2538 int nbValid = 0, nbRemoved = 0;
2539 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2540 for ( ; chItr->More(); chItr->Next() )
2542 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2543 if ( !smSO->_is_nil() &&
2544 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2545 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2547 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2548 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2549 if ( !geom->_non_existent() )
2552 continue; // keep the sub-mesh
2555 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2556 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2557 if ( !sm->_is_nil() && !sm->_non_existent() )
2559 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2560 if ( smGeom->_is_nil() )
2562 RemoveSubMesh( sm );
2569 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2570 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2574 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2575 builder->RemoveObjectWithChildren( rootSO );
2579 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2580 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2581 while ( i_gr != _mapGroups.end())
2583 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2585 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2586 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2587 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2588 bool isValidGeom = false;
2589 if ( !onGeom->_is_nil() )
2591 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2593 else if ( !onFilt->_is_nil() )
2595 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2599 isValidGeom = ( !groupSO->_is_nil() &&
2600 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2604 if ( !IsLoaded() || group->IsEmpty() )
2606 RemoveGroup( group );
2608 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2610 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2612 else // is it possible?
2614 builder->RemoveObjectWithChildren( refSO );
2620 if ( !_impl->HasShapeToMesh() ) return;
2622 CORBA::Long nbEntities = NbNodes() + NbElements();
2624 // Check if group contents changed
2626 typedef map< string, TopoDS_Shape > TEntry2Geom;
2627 TEntry2Geom newGroupContents;
2629 list<TGeomGroupData>::iterator
2630 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2631 for ( ; data != dataEnd; ++data )
2633 pair< TEntry2Geom::iterator, bool > it_new =
2634 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2635 bool processedGroup = !it_new.second;
2636 TopoDS_Shape& newShape = it_new.first->second;
2637 if ( !processedGroup )
2638 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2639 if ( newShape.IsNull() )
2640 continue; // no changes
2643 _preMeshInfo->ForgetOrLoad();
2645 if ( processedGroup ) { // update group indices
2646 list<TGeomGroupData>::iterator data2 = data;
2647 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2648 data->_indices = data2->_indices;
2651 // Update SMESH objects according to new GEOM group contents
2653 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2654 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2656 int oldID = submesh->GetId();
2657 if ( !_mapSubMeshIor.count( oldID ))
2659 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2661 // update hypotheses
2662 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2663 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2664 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2666 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2667 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2669 // care of submeshes
2670 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2671 int newID = newSubmesh->GetId();
2672 if ( newID != oldID ) {
2673 _mapSubMesh [ newID ] = newSubmesh;
2674 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2675 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2676 _mapSubMesh. erase(oldID);
2677 _mapSubMesh_i. erase(oldID);
2678 _mapSubMeshIor.erase(oldID);
2679 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2684 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2685 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2686 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2688 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2690 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2691 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2692 ds->SetShape( newShape );
2697 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2698 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2700 // Remove groups and submeshes basing on removed sub-shapes
2702 TopTools_MapOfShape newShapeMap;
2703 TopoDS_Iterator shapeIt( newShape );
2704 for ( ; shapeIt.More(); shapeIt.Next() )
2705 newShapeMap.Add( shapeIt.Value() );
2707 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2708 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2710 if ( newShapeMap.Contains( shapeIt.Value() ))
2712 TopTools_IndexedMapOfShape oldShapeMap;
2713 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2714 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2716 const TopoDS_Shape& oldShape = oldShapeMap(i);
2717 int oldInd = meshDS->ShapeToIndex( oldShape );
2719 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2720 if ( i_smIor != _mapSubMeshIor.end() ) {
2721 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2724 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2725 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2727 // check if a group bases on oldInd shape
2728 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2729 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2730 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2731 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2733 RemoveGroup( i_grp->second ); // several groups can base on same shape
2734 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2739 // Reassign hypotheses and update groups after setting the new shape to mesh
2741 // collect anassigned hypotheses
2742 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2743 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2744 TShapeHypList assignedHyps;
2745 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2747 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2748 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2749 if ( !hyps.empty() ) {
2750 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2751 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2752 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2755 // collect shapes supporting groups
2756 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2757 TShapeTypeList groupData;
2758 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2759 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2760 for ( ; grIt != groups.end(); ++grIt )
2762 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2764 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2766 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2768 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2769 _impl->ShapeToMesh( newShape );
2771 // reassign hypotheses
2772 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2773 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2775 TIndexedShape& geom = indS_hyps->first;
2776 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2777 int oldID = geom._index;
2778 int newID = meshDS->ShapeToIndex( geom._shape );
2779 if ( oldID == 1 ) { // main shape
2781 geom._shape = newShape;
2785 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2786 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2787 // care of sub-meshes
2788 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2789 if ( newID != oldID ) {
2790 _mapSubMesh [ newID ] = newSubmesh;
2791 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2792 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2793 _mapSubMesh. erase(oldID);
2794 _mapSubMesh_i. erase(oldID);
2795 _mapSubMeshIor.erase(oldID);
2796 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2800 TShapeTypeList::iterator geomType = groupData.begin();
2801 for ( ; geomType != groupData.end(); ++geomType )
2803 const TIndexedShape& geom = geomType->first;
2804 int oldID = geom._index;
2805 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2808 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2809 CORBA::String_var name = groupSO->GetName();
2811 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2812 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2813 /*id=*/-1, geom._shape ))
2814 group_i->changeLocalId( group->GetID() );
2817 break; // everything has been updated
2820 } // loop on group data
2824 CORBA::Long newNbEntities = NbNodes() + NbElements();
2825 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2826 if ( newNbEntities != nbEntities )
2828 // Add all SObjects with icons to soToUpdateIcons
2829 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2831 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2832 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2833 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2835 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2836 i_gr != _mapGroups.end(); ++i_gr ) // groups
2837 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2840 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2841 for ( ; so != soToUpdateIcons.end(); ++so )
2842 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2845 //=============================================================================
2847 * \brief Create standalone group from a group on geometry or filter
2849 //=============================================================================
2851 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2852 throw (SALOME::SALOME_Exception)
2854 SMESH::SMESH_Group_var aGroup;
2859 _preMeshInfo->FullLoadFromFile();
2861 if ( theGroup->_is_nil() )
2862 return aGroup._retn();
2864 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2866 return aGroup._retn();
2868 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2870 const int anId = aGroupToRem->GetLocalID();
2871 if ( !_impl->ConvertToStandalone( anId ) )
2872 return aGroup._retn();
2873 removeGeomGroupData( theGroup );
2875 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2877 // remove old instance of group from own map
2878 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2879 _mapGroups.erase( anId );
2881 SALOMEDS::StudyBuilder_var builder;
2882 SALOMEDS::SObject_wrap aGroupSO;
2883 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2884 if ( !aStudy->_is_nil() ) {
2885 builder = aStudy->NewBuilder();
2886 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2887 if ( !aGroupSO->_is_nil() )
2889 // remove reference to geometry
2890 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2891 for ( ; chItr->More(); chItr->Next() )
2893 // Remove group's child SObject
2894 SALOMEDS::SObject_wrap so = chItr->Value();
2895 builder->RemoveObject( so );
2897 // Update Python script
2898 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2899 << ".ConvertToStandalone( " << aGroupSO << " )";
2901 // change icon of Group on Filter
2904 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2905 // const int isEmpty = ( elemTypes->length() == 0 );
2908 SALOMEDS::GenericAttribute_wrap anAttr =
2909 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2910 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2911 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2917 // remember new group in own map
2918 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2919 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2921 // register CORBA object for persistence
2922 _gen_i->RegisterObject( aGroup );
2924 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2925 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2926 //aGroup->Register();
2927 aGroupToRem->UnRegister();
2929 SMESH_CATCH( SMESH::throwCorbaException );
2931 return aGroup._retn();
2934 //=============================================================================
2938 //=============================================================================
2940 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2942 if(MYDEBUG) MESSAGE( "createSubMesh" );
2943 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2944 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2947 SMESH_subMesh_i * subMeshServant;
2950 subMeshId = mySubMesh->GetId();
2951 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2953 else // "invalid sub-mesh"
2955 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2956 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2957 if ( _mapSubMesh.empty() )
2960 subMeshId = _mapSubMesh.begin()->first - 1;
2961 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2964 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2966 _mapSubMesh [subMeshId] = mySubMesh;
2967 _mapSubMesh_i [subMeshId] = subMeshServant;
2968 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2970 subMeshServant->Register();
2972 // register CORBA object for persistence
2973 int nextId = _gen_i->RegisterObject( subMesh );
2974 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2975 else { nextId = 0; } // avoid "unused variable" warning
2977 // to track changes of GEOM groups
2978 if ( subMeshId > 0 )
2979 addGeomGroupData( theSubShapeObject, subMesh );
2981 return subMesh._retn();
2984 //=======================================================================
2985 //function : getSubMesh
2987 //=======================================================================
2989 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2991 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2992 if ( it == _mapSubMeshIor.end() )
2993 return SMESH::SMESH_subMesh::_nil();
2995 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2998 //=============================================================================
3002 //=============================================================================
3004 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3005 GEOM::GEOM_Object_ptr theSubShapeObject )
3007 bool isHypChanged = false;
3008 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3009 return isHypChanged;
3011 const int subMeshId = theSubMesh->GetId();
3013 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3016 if (( _mapSubMesh.count( subMeshId )) &&
3017 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3019 TopoDS_Shape S = sm->GetSubShape();
3022 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3023 isHypChanged = !hyps.empty();
3024 if ( isHypChanged && _preMeshInfo )
3025 _preMeshInfo->ForgetOrLoad();
3026 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3027 for ( ; hyp != hyps.end(); ++hyp )
3028 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3035 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3036 isHypChanged = ( aHypList->length() > 0 );
3037 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3038 removeHypothesis( theSubShapeObject, aHypList[i] );
3041 catch( const SALOME::SALOME_Exception& ) {
3042 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3044 removeGeomGroupData( theSubShapeObject );
3048 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3049 if ( id_smi != _mapSubMesh_i.end() )
3050 id_smi->second->UnRegister();
3052 // remove a CORBA object
3053 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3054 if ( id_smptr != _mapSubMeshIor.end() )
3055 SMESH::SMESH_subMesh_var( id_smptr->second );
3057 _mapSubMesh.erase(subMeshId);
3058 _mapSubMesh_i.erase(subMeshId);
3059 _mapSubMeshIor.erase(subMeshId);
3061 return isHypChanged;
3064 //=============================================================================
3068 //=============================================================================
3070 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3071 const char* theName,
3073 const TopoDS_Shape& theShape,
3074 const SMESH_PredicatePtr& thePredicate )
3076 std::string newName;
3077 if ( !theName || !theName[0] )
3079 std::set< std::string > presentNames;
3080 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3081 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3083 CORBA::String_var name = i_gr->second->GetName();
3084 presentNames.insert( name.in() );
3087 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3088 } while ( !presentNames.insert( newName ).second );
3089 theName = newName.c_str();
3091 SMESH::SMESH_GroupBase_var aGroup;
3092 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3093 theID, theShape, thePredicate ))
3095 int anId = g->GetID();
3096 SMESH_GroupBase_i* aGroupImpl;
3097 if ( !theShape.IsNull() )
3098 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3099 else if ( thePredicate )
3100 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3102 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3104 aGroup = aGroupImpl->_this();
3105 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3106 aGroupImpl->Register();
3108 // register CORBA object for persistence
3109 int nextId = _gen_i->RegisterObject( aGroup );
3110 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3111 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3113 // to track changes of GEOM groups
3114 if ( !theShape.IsNull() ) {
3115 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3116 addGeomGroupData( geom, aGroup );
3119 return aGroup._retn();
3122 //=============================================================================
3124 * SMESH_Mesh_i::removeGroup
3126 * Should be called by ~SMESH_Group_i()
3128 //=============================================================================
3130 void SMESH_Mesh_i::removeGroup( const int theId )
3132 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3133 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3134 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3135 _mapGroups.erase( theId );
3136 removeGeomGroupData( group );
3137 if ( !_impl->RemoveGroup( theId ))
3139 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3140 RemoveGroup( group );
3142 group->UnRegister();
3146 //=============================================================================
3150 //=============================================================================
3152 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3153 throw(SALOME::SALOME_Exception)
3155 SMESH::log_array_var aLog;
3159 _preMeshInfo->FullLoadFromFile();
3161 list < SMESHDS_Command * >logDS = _impl->GetLog();
3162 aLog = new SMESH::log_array;
3164 int lg = logDS.size();
3167 list < SMESHDS_Command * >::iterator its = logDS.begin();
3168 while(its != logDS.end()){
3169 SMESHDS_Command *com = *its;
3170 int comType = com->GetType();
3172 int lgcom = com->GetNumber();
3174 const list < int >&intList = com->GetIndexes();
3175 int inum = intList.size();
3177 list < int >::const_iterator ii = intList.begin();
3178 const list < double >&coordList = com->GetCoords();
3179 int rnum = coordList.size();
3181 list < double >::const_iterator ir = coordList.begin();
3182 aLog[indexLog].commandType = comType;
3183 aLog[indexLog].number = lgcom;
3184 aLog[indexLog].coords.length(rnum);
3185 aLog[indexLog].indexes.length(inum);
3186 for(int i = 0; i < rnum; i++){
3187 aLog[indexLog].coords[i] = *ir;
3188 //MESSAGE(" "<<i<<" "<<ir.Value());
3191 for(int i = 0; i < inum; i++){
3192 aLog[indexLog].indexes[i] = *ii;
3193 //MESSAGE(" "<<i<<" "<<ii.Value());
3202 SMESH_CATCH( SMESH::throwCorbaException );
3204 return aLog._retn();
3208 //=============================================================================
3212 //=============================================================================
3214 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3218 SMESH_CATCH( SMESH::throwCorbaException );
3221 //=============================================================================
3225 //=============================================================================
3227 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3232 //=============================================================================
3235 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3236 // issue 0020918: groups removal is caused by hyp modification
3237 // issue 0021208: to forget not loaded mesh data at hyp modification
3238 struct TCallUp_i : public SMESH_Mesh::TCallUp
3240 SMESH_Mesh_i* _mesh;
3241 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3242 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3243 virtual void HypothesisModified( int hypID,
3244 bool updIcons) { _mesh->onHypothesisModified( hypID,
3246 virtual void Load () { _mesh->Load(); }
3247 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3251 //================================================================================
3253 * \brief callback from _impl to
3254 * 1) forget not loaded mesh data (issue 0021208)
3255 * 2) mark hypothesis as valid
3257 //================================================================================
3259 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3262 _preMeshInfo->ForgetOrLoad();
3264 if ( theUpdateIcons )
3266 SMESH::SMESH_Mesh_var mesh = _this();
3267 _gen_i->UpdateIcons( mesh );
3270 if ( _nbInvalidHypos != 0 )
3272 // mark a hypothesis as valid after edition
3274 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3275 SALOMEDS::SObject_wrap hypRoot;
3276 if ( !smeshComp->_is_nil() &&
3277 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3279 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3280 for ( ; anIter->More(); anIter->Next() )
3282 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3283 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3284 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3285 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3286 _gen_i->HighLightInvalid( hyp, false );
3288 nbInvalid += _gen_i->IsInvalid( hypSO );
3291 _nbInvalidHypos = nbInvalid;
3295 //=============================================================================
3299 //=============================================================================
3301 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3303 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3306 _impl->SetCallUp( new TCallUp_i(this));
3309 //=============================================================================
3313 //=============================================================================
3315 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3317 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3321 //=============================================================================
3323 * Return mesh editor
3325 //=============================================================================
3327 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3328 throw (SALOME::SALOME_Exception)
3330 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3334 _preMeshInfo->FullLoadFromFile();
3336 // Create MeshEditor
3338 _editor = new SMESH_MeshEditor_i( this, false );
3339 aMeshEdVar = _editor->_this();
3341 // Update Python script
3342 TPythonDump() << _editor << " = "
3343 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3345 SMESH_CATCH( SMESH::throwCorbaException );
3347 return aMeshEdVar._retn();
3350 //=============================================================================
3352 * Return mesh edition previewer
3354 //=============================================================================
3356 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3357 throw (SALOME::SALOME_Exception)
3359 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3363 _preMeshInfo->FullLoadFromFile();
3365 if ( !_previewEditor )
3366 _previewEditor = new SMESH_MeshEditor_i( this, true );
3367 aMeshEdVar = _previewEditor->_this();
3369 SMESH_CATCH( SMESH::throwCorbaException );
3371 return aMeshEdVar._retn();
3374 //================================================================================
3376 * \brief Return true if the mesh has been edited since a last total re-compute
3377 * and those modifications may prevent successful partial re-compute
3379 //================================================================================
3381 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3383 Unexpect aCatch(SALOME_SalomeException);
3384 return _impl->HasModificationsToDiscard();
3387 //================================================================================
3389 * \brief Returns a random unique color
3391 //================================================================================
3393 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3395 const int MAX_ATTEMPTS = 100;
3397 double tolerance = 0.5;
3398 SALOMEDS::Color col;
3402 // generate random color
3403 double red = (double)rand() / RAND_MAX;
3404 double green = (double)rand() / RAND_MAX;
3405 double blue = (double)rand() / RAND_MAX;
3406 // check existence in the list of the existing colors
3407 bool matched = false;
3408 std::list<SALOMEDS::Color>::const_iterator it;
3409 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3410 SALOMEDS::Color color = *it;
3411 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3412 matched = tol < tolerance;
3414 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3415 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3423 //=============================================================================
3425 * Sets auto-color mode. If it is on, groups get unique random colors
3427 //=============================================================================
3429 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3431 Unexpect aCatch(SALOME_SalomeException);
3432 _impl->SetAutoColor(theAutoColor);
3434 TPythonDump pyDump; // not to dump group->SetColor() from below code
3435 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3437 std::list<SALOMEDS::Color> aReservedColors;
3438 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3439 for ( ; it != _mapGroups.end(); it++ ) {
3440 if ( CORBA::is_nil( it->second )) continue;
3441 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3442 it->second->SetColor( aColor );
3443 aReservedColors.push_back( aColor );
3447 //=============================================================================
3449 * Returns true if auto-color mode is on
3451 //=============================================================================
3453 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3455 Unexpect aCatch(SALOME_SalomeException);
3456 return _impl->GetAutoColor();
3459 //=============================================================================
3461 * Checks if there are groups with equal names
3463 //=============================================================================
3465 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3467 return _impl->HasDuplicatedGroupNamesMED();
3470 //================================================================================
3472 * \brief Care of a file before exporting mesh into it
3474 //================================================================================
3476 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3478 SMESH_File aFile( file, false );
3480 if ( aFile.exists() ) {
3481 // existing filesystem node
3482 if ( !aFile.isDirectory() ) {
3483 if ( aFile.openForWriting() ) {
3484 if ( overwrite && ! aFile.remove()) {
3485 msg << "Can't replace " << aFile.getName();
3488 msg << "Can't write into " << aFile.getName();
3491 msg << "Location " << aFile.getName() << " is not a file";
3495 // nonexisting file; check if it can be created
3496 if ( !aFile.openForWriting() ) {
3497 msg << "You cannot create the file "
3499 << ". Check the directory existence and access rights";
3507 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3511 //================================================================================
3513 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3514 * \param file - file name
3515 * \param overwrite - to erase the file or not
3516 * \retval string - mesh name
3518 //================================================================================
3520 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3521 CORBA::Boolean overwrite)
3524 PrepareForWriting(file, overwrite);
3525 string aMeshName = "Mesh";
3526 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3527 if ( !aStudy->_is_nil() ) {
3528 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3529 if ( !aMeshSO->_is_nil() ) {
3530 CORBA::String_var name = aMeshSO->GetName();
3532 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3533 if ( !aStudy->GetProperties()->IsLocked() )
3535 SALOMEDS::GenericAttribute_wrap anAttr;
3536 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3537 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3538 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3539 ASSERT(!aFileName->_is_nil());
3540 aFileName->SetValue(file);
3541 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3542 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3543 ASSERT(!aFileType->_is_nil());
3544 aFileType->SetValue("FICHIERMED");
3548 // Update Python script
3549 // set name of mesh before export
3550 TPythonDump() << _gen_i << ".SetName("
3551 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3553 // check names of groups
3559 //================================================================================
3561 * \brief Export to MED file
3563 //================================================================================
3565 void SMESH_Mesh_i::ExportMED(const char* file,
3566 CORBA::Boolean auto_groups,
3567 CORBA::Long version,
3568 CORBA::Boolean overwrite,
3569 CORBA::Boolean autoDimension)
3570 throw(SALOME::SALOME_Exception)
3572 //MESSAGE("MED minor version: "<< minor);
3575 _preMeshInfo->FullLoadFromFile();
3577 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3578 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3580 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3582 << "auto_groups=" <<auto_groups << ", "
3583 << "minor=" << version << ", "
3584 << "overwrite=" << overwrite << ", "
3585 << "meshPart=None, "
3586 << "autoDimension=" << autoDimension << " )";
3588 SMESH_CATCH( SMESH::throwCorbaException );
3591 //================================================================================
3593 * \brief Export a mesh to a SAUV file
3595 //================================================================================
3597 void SMESH_Mesh_i::ExportSAUV (const char* file,
3598 CORBA::Boolean auto_groups)
3599 throw(SALOME::SALOME_Exception)
3601 Unexpect aCatch(SALOME_SalomeException);
3603 _preMeshInfo->FullLoadFromFile();
3605 string aMeshName = prepareMeshNameAndGroups(file, true);
3606 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3607 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3608 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3612 //================================================================================
3614 * \brief Export a mesh to a DAT file
3616 //================================================================================
3618 void SMESH_Mesh_i::ExportDAT (const char *file)
3619 throw(SALOME::SALOME_Exception)
3621 Unexpect aCatch(SALOME_SalomeException);
3623 _preMeshInfo->FullLoadFromFile();
3625 // Update Python script
3626 // check names of groups
3628 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3631 PrepareForWriting(file);
3632 _impl->ExportDAT(file);
3635 //================================================================================
3637 * \brief Export a mesh to an UNV file
3639 //================================================================================
3641 void SMESH_Mesh_i::ExportUNV (const char *file)
3642 throw(SALOME::SALOME_Exception)
3644 Unexpect aCatch(SALOME_SalomeException);
3646 _preMeshInfo->FullLoadFromFile();
3648 // Update Python script
3649 // check names of groups
3651 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3654 PrepareForWriting(file);
3655 _impl->ExportUNV(file);
3658 //================================================================================
3660 * \brief Export a mesh to an STL file
3662 //================================================================================
3664 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3665 throw(SALOME::SALOME_Exception)
3667 Unexpect aCatch(SALOME_SalomeException);
3669 _preMeshInfo->FullLoadFromFile();
3671 // Update Python script
3672 // check names of groups
3674 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3675 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3677 CORBA::String_var name;
3678 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3679 if ( !so->_is_nil() )
3680 name = so->GetName();
3683 PrepareForWriting( file );
3684 _impl->ExportSTL( file, isascii, name.in() );
3687 //================================================================================
3689 * \brief Export a part of mesh to a med file
3691 //================================================================================
3693 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3695 CORBA::Boolean auto_groups,
3696 CORBA::Long version,
3697 CORBA::Boolean overwrite,
3698 CORBA::Boolean autoDimension,
3699 const GEOM::ListOfFields& fields,
3700 const char* geomAssocFields,
3701 CORBA::Double ZTolerance)
3702 throw (SALOME::SALOME_Exception)
3704 MESSAGE("MED version: "<< version);
3707 _preMeshInfo->FullLoadFromFile();
3710 bool have0dField = false;
3711 if ( fields.length() > 0 )
3713 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3714 if ( shapeToMesh->_is_nil() )
3715 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3717 for ( size_t i = 0; i < fields.length(); ++i )
3719 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3720 THROW_SALOME_CORBA_EXCEPTION
3721 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3722 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3723 if ( fieldShape->_is_nil() )
3724 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3725 if ( !fieldShape->IsSame( shapeToMesh ) )
3726 THROW_SALOME_CORBA_EXCEPTION
3727 ( "Field defined not on shape", SALOME::BAD_PARAM);
3728 if ( fields[i]->GetDimension() == 0 )
3731 if ( geomAssocFields )
3732 for ( int i = 0; geomAssocFields[i]; ++i )
3733 switch ( geomAssocFields[i] ) {
3734 case 'v':case 'e':case 'f':case 's': break;
3735 case 'V':case 'E':case 'F':case 'S': break;
3736 default: THROW_SALOME_CORBA_EXCEPTION
3737 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3741 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3745 string aMeshName = "Mesh";
3746 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3747 if ( CORBA::is_nil( meshPart ) ||
3748 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3750 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3751 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3752 0, autoDimension, /*addODOnVertices=*/have0dField,
3754 meshDS = _impl->GetMeshDS();
3759 _preMeshInfo->FullLoadFromFile();
3761 PrepareForWriting(file, overwrite);
3763 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3764 if ( !SO->_is_nil() ) {
3765 CORBA::String_var name = SO->GetName();
3769 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3770 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3771 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3772 meshDS = tmpDSDeleter._obj = partDS;
3777 if ( _impl->HasShapeToMesh() )
3779 DriverMED_W_Field fieldWriter;
3780 fieldWriter.SetFile( file );
3781 fieldWriter.SetMeshName( aMeshName );
3782 fieldWriter.AddODOnVertices( have0dField );
3784 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3788 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3789 goList->length( fields.length() );
3790 for ( size_t i = 0; i < fields.length(); ++i )
3792 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3795 TPythonDump() << _this() << ".ExportPartToMED( "
3796 << meshPart << ", r'"
3798 << auto_groups << ", "
3800 << overwrite << ", "
3801 << autoDimension << ", "
3803 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3804 << TVar( ZTolerance )
3807 SMESH_CATCH( SMESH::throwCorbaException );
3810 //================================================================================
3812 * Write GEOM fields to MED file
3814 //================================================================================
3816 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3817 SMESHDS_Mesh* meshDS,
3818 const GEOM::ListOfFields& fields,
3819 const char* geomAssocFields)
3821 #define METH "SMESH_Mesh_i::exportMEDFields() "
3823 if (( fields.length() < 1 ) &&
3824 ( !geomAssocFields || !geomAssocFields[0] ))
3827 std::vector< std::vector< double > > dblVals;
3828 std::vector< std::vector< int > > intVals;
3829 std::vector< int > subIdsByDim[ 4 ];
3830 const double noneDblValue = 0.;
3831 const double noneIntValue = 0;
3833 for ( size_t iF = 0; iF < fields.length(); ++iF )
3837 int dim = fields[ iF ]->GetDimension();
3838 SMDSAbs_ElementType elemType;
3839 TopAbs_ShapeEnum shapeType;
3841 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3842 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3843 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3844 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3846 continue; // skip fields on whole shape
3848 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3849 if ( dataType == GEOM::FDT_String )
3851 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3852 if ( stepIDs->length() < 1 )
3854 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3855 if ( comps->length() < 1 )
3857 CORBA::String_var name = fields[ iF ]->GetName();
3859 if ( !fieldWriter.Set( meshDS,
3863 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3866 for ( size_t iC = 0; iC < comps->length(); ++iC )
3867 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3869 dblVals.resize( comps->length() );
3870 intVals.resize( comps->length() );
3872 // find sub-shape IDs
3874 std::vector< int >& subIds = subIdsByDim[ dim ];
3875 if ( subIds.empty() )
3876 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3877 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3878 subIds.push_back( id );
3882 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3886 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3888 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3889 if ( step->_is_nil() )
3892 CORBA::Long stamp = step->GetStamp();
3893 CORBA::Long id = step->GetID();
3894 fieldWriter.SetDtIt( int( stamp ), int( id ));
3896 // fill dblVals or intVals
3897 for ( size_t iC = 0; iC < comps->length(); ++iC )
3898 if ( dataType == GEOM::FDT_Double )
3900 dblVals[ iC ].clear();
3901 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3905 intVals[ iC ].clear();
3906 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3910 case GEOM::FDT_Double:
3912 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3913 if ( dblStep->_is_nil() ) continue;
3914 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3915 if ( vv->length() != subIds.size() * comps->length() )
3916 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3917 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3918 for ( size_t iC = 0; iC < comps->length(); ++iC )
3919 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3924 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3925 if ( intStep->_is_nil() ) continue;
3926 GEOM::ListOfLong_var vv = intStep->GetValues();
3927 if ( vv->length() != subIds.size() * comps->length() )
3928 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3929 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3930 for ( size_t iC = 0; iC < comps->length(); ++iC )
3931 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3934 case GEOM::FDT_Bool:
3936 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3937 if ( boolStep->_is_nil() ) continue;
3938 GEOM::short_array_var vv = boolStep->GetValues();
3939 if ( vv->length() != subIds.size() * comps->length() )
3940 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3941 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3942 for ( size_t iC = 0; iC < comps->length(); ++iC )
3943 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3949 // pass values to fieldWriter
3950 elemIt = fieldWriter.GetOrderedElems();
3951 if ( dataType == GEOM::FDT_Double )
3952 while ( elemIt->more() )
3954 const SMDS_MeshElement* e = elemIt->next();
3955 const int shapeID = e->getshapeId();
3956 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3957 for ( size_t iC = 0; iC < comps->length(); ++iC )
3958 fieldWriter.AddValue( noneDblValue );
3960 for ( size_t iC = 0; iC < comps->length(); ++iC )
3961 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3964 while ( elemIt->more() )
3966 const SMDS_MeshElement* e = elemIt->next();
3967 const int shapeID = e->getshapeId();
3968 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3969 for ( size_t iC = 0; iC < comps->length(); ++iC )
3970 fieldWriter.AddValue( (double) noneIntValue );
3972 for ( size_t iC = 0; iC < comps->length(); ++iC )
3973 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3977 fieldWriter.Perform();
3978 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3979 if ( res && res->IsKO() )
3981 if ( res->myComment.empty() )
3982 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3984 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3990 if ( !geomAssocFields || !geomAssocFields[0] )
3993 // write geomAssocFields
3995 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3996 shapeDim[ TopAbs_COMPOUND ] = 3;
3997 shapeDim[ TopAbs_COMPSOLID ] = 3;
3998 shapeDim[ TopAbs_SOLID ] = 3;
3999 shapeDim[ TopAbs_SHELL ] = 2;
4000 shapeDim[ TopAbs_FACE ] = 2;
4001 shapeDim[ TopAbs_WIRE ] = 1;
4002 shapeDim[ TopAbs_EDGE ] = 1;
4003 shapeDim[ TopAbs_VERTEX ] = 0;
4004 shapeDim[ TopAbs_SHAPE ] = 3;
4006 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4008 std::vector< std::string > compNames;
4009 switch ( geomAssocFields[ iF ]) {
4011 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4012 compNames.push_back( "dim" );
4015 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4018 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4021 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4025 compNames.push_back( "id" );
4026 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4027 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4029 fieldWriter.SetDtIt( -1, -1 );
4031 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4035 if ( compNames.size() == 2 ) // _vertices_
4036 while ( elemIt->more() )
4038 const SMDS_MeshElement* e = elemIt->next();
4039 const int shapeID = e->getshapeId();
4042 fieldWriter.AddValue( (double) -1 );
4043 fieldWriter.AddValue( (double) -1 );
4047 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4048 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4049 fieldWriter.AddValue( (double) shapeID );
4053 while ( elemIt->more() )
4055 const SMDS_MeshElement* e = elemIt->next();
4056 const int shapeID = e->getshapeId();
4058 fieldWriter.AddValue( (double) -1 );
4060 fieldWriter.AddValue( (double) shapeID );
4064 fieldWriter.Perform();
4065 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4066 if ( res && res->IsKO() )
4068 if ( res->myComment.empty() )
4069 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4071 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4074 } // loop on geomAssocFields
4079 //================================================================================
4081 * \brief Export a part of mesh to a DAT file
4083 //================================================================================
4085 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4087 throw (SALOME::SALOME_Exception)
4089 Unexpect aCatch(SALOME_SalomeException);
4091 _preMeshInfo->FullLoadFromFile();
4093 PrepareForWriting(file);
4095 SMESH_MeshPartDS partDS( meshPart );
4096 _impl->ExportDAT(file,&partDS);
4098 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4099 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4101 //================================================================================
4103 * \brief Export a part of mesh to an UNV file
4105 //================================================================================
4107 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4109 throw (SALOME::SALOME_Exception)
4111 Unexpect aCatch(SALOME_SalomeException);
4113 _preMeshInfo->FullLoadFromFile();
4115 PrepareForWriting(file);
4117 SMESH_MeshPartDS partDS( meshPart );
4118 _impl->ExportUNV(file, &partDS);
4120 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4121 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4123 //================================================================================
4125 * \brief Export a part of mesh to an STL file
4127 //================================================================================
4129 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4131 ::CORBA::Boolean isascii)
4132 throw (SALOME::SALOME_Exception)
4134 Unexpect aCatch(SALOME_SalomeException);
4136 _preMeshInfo->FullLoadFromFile();
4138 PrepareForWriting(file);
4140 CORBA::String_var name;
4141 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4142 if ( !so->_is_nil() )
4143 name = so->GetName();
4145 SMESH_MeshPartDS partDS( meshPart );
4146 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4148 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4149 << meshPart<< ", r'" << file << "', " << isascii << ")";
4152 //================================================================================
4154 * \brief Export a part of mesh to an STL file
4156 //================================================================================
4158 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4160 CORBA::Boolean overwrite,
4161 CORBA::Boolean groupElemsByType)
4162 throw (SALOME::SALOME_Exception)
4165 Unexpect aCatch(SALOME_SalomeException);
4167 _preMeshInfo->FullLoadFromFile();
4169 PrepareForWriting(file,overwrite);
4171 std::string meshName("");
4172 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4173 if ( !so->_is_nil() )
4175 CORBA::String_var name = so->GetName();
4176 meshName = name.in();
4180 SMESH_MeshPartDS partDS( meshPart );
4181 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4183 SMESH_CATCH( SMESH::throwCorbaException );
4185 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4186 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4188 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4192 //================================================================================
4194 * \brief Export a part of mesh to a GMF file
4196 //================================================================================
4198 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4200 bool withRequiredGroups)
4201 throw (SALOME::SALOME_Exception)
4203 Unexpect aCatch(SALOME_SalomeException);
4205 _preMeshInfo->FullLoadFromFile();
4207 PrepareForWriting(file,/*overwrite=*/true);
4209 SMESH_MeshPartDS partDS( meshPart );
4210 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4212 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4213 << meshPart<< ", r'"
4215 << withRequiredGroups << ")";
4218 //=============================================================================
4220 * Return computation progress [0.,1]
4222 //=============================================================================
4224 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4228 return _impl->GetComputeProgress();
4230 SMESH_CATCH( SMESH::doNothing );
4234 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4236 Unexpect aCatch(SALOME_SalomeException);
4238 return _preMeshInfo->NbNodes();
4240 return _impl->NbNodes();
4243 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4245 Unexpect aCatch(SALOME_SalomeException);
4247 return _preMeshInfo->NbElements();
4249 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4252 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4254 Unexpect aCatch(SALOME_SalomeException);
4256 return _preMeshInfo->Nb0DElements();
4258 return _impl->Nb0DElements();
4261 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4263 Unexpect aCatch(SALOME_SalomeException);
4265 return _preMeshInfo->NbBalls();
4267 return _impl->NbBalls();
4270 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4272 Unexpect aCatch(SALOME_SalomeException);
4274 return _preMeshInfo->NbEdges();
4276 return _impl->NbEdges();
4279 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4280 throw(SALOME::SALOME_Exception)
4282 Unexpect aCatch(SALOME_SalomeException);
4284 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4286 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4289 //=============================================================================
4291 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4293 Unexpect aCatch(SALOME_SalomeException);
4295 return _preMeshInfo->NbFaces();
4297 return _impl->NbFaces();
4300 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4302 Unexpect aCatch(SALOME_SalomeException);
4304 return _preMeshInfo->NbTriangles();
4306 return _impl->NbTriangles();
4309 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4311 Unexpect aCatch(SALOME_SalomeException);
4313 return _preMeshInfo->NbBiQuadTriangles();
4315 return _impl->NbBiQuadTriangles();
4318 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4320 Unexpect aCatch(SALOME_SalomeException);
4322 return _preMeshInfo->NbQuadrangles();
4324 return _impl->NbQuadrangles();
4327 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4329 Unexpect aCatch(SALOME_SalomeException);
4331 return _preMeshInfo->NbBiQuadQuadrangles();
4333 return _impl->NbBiQuadQuadrangles();
4336 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4338 Unexpect aCatch(SALOME_SalomeException);
4340 return _preMeshInfo->NbPolygons();
4342 return _impl->NbPolygons();
4345 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4347 Unexpect aCatch(SALOME_SalomeException);
4349 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4351 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4354 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4355 throw(SALOME::SALOME_Exception)
4357 Unexpect aCatch(SALOME_SalomeException);
4359 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4361 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4364 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4365 throw(SALOME::SALOME_Exception)
4367 Unexpect aCatch(SALOME_SalomeException);
4369 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4371 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4374 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4375 throw(SALOME::SALOME_Exception)
4377 Unexpect aCatch(SALOME_SalomeException);
4379 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4381 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4384 //=============================================================================
4386 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4388 Unexpect aCatch(SALOME_SalomeException);
4390 return _preMeshInfo->NbVolumes();
4392 return _impl->NbVolumes();
4395 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4397 Unexpect aCatch(SALOME_SalomeException);
4399 return _preMeshInfo->NbTetras();
4401 return _impl->NbTetras();
4404 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4406 Unexpect aCatch(SALOME_SalomeException);
4408 return _preMeshInfo->NbHexas();
4410 return _impl->NbHexas();
4413 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4415 Unexpect aCatch(SALOME_SalomeException);
4417 return _preMeshInfo->NbTriQuadHexas();
4419 return _impl->NbTriQuadraticHexas();
4422 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4424 Unexpect aCatch(SALOME_SalomeException);
4426 return _preMeshInfo->NbPyramids();
4428 return _impl->NbPyramids();
4431 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4433 Unexpect aCatch(SALOME_SalomeException);
4435 return _preMeshInfo->NbPrisms();
4437 return _impl->NbPrisms();
4440 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4442 Unexpect aCatch(SALOME_SalomeException);
4444 return _preMeshInfo->NbHexPrisms();
4446 return _impl->NbHexagonalPrisms();
4449 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4451 Unexpect aCatch(SALOME_SalomeException);
4453 return _preMeshInfo->NbPolyhedrons();
4455 return _impl->NbPolyhedrons();
4458 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4459 throw(SALOME::SALOME_Exception)
4461 Unexpect aCatch(SALOME_SalomeException);
4463 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4465 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4468 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4469 throw(SALOME::SALOME_Exception)
4471 Unexpect aCatch(SALOME_SalomeException);
4473 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4475 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4478 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4479 throw(SALOME::SALOME_Exception)
4481 Unexpect aCatch(SALOME_SalomeException);
4483 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4485 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4488 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4489 throw(SALOME::SALOME_Exception)
4491 Unexpect aCatch(SALOME_SalomeException);
4493 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4495 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4498 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4499 throw(SALOME::SALOME_Exception)
4501 Unexpect aCatch(SALOME_SalomeException);
4503 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4505 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4508 //=============================================================================
4510 * Returns nb of published sub-meshes
4512 //=============================================================================
4514 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4516 Unexpect aCatch(SALOME_SalomeException);
4517 return _mapSubMesh_i.size();
4520 //=============================================================================
4522 * Dumps mesh into a string
4524 //=============================================================================
4526 char* SMESH_Mesh_i::Dump()
4530 return CORBA::string_dup( os.str().c_str() );
4533 //=============================================================================
4535 * Method of SMESH_IDSource interface
4537 //=============================================================================
4539 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4541 return GetElementsId();
4544 //=============================================================================
4546 * Returns ids of all elements
4548 //=============================================================================
4550 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4551 throw (SALOME::SALOME_Exception)
4553 Unexpect aCatch(SALOME_SalomeException);
4555 _preMeshInfo->FullLoadFromFile();
4557 SMESH::long_array_var aResult = new SMESH::long_array();
4558 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4560 if ( aSMESHDS_Mesh == NULL )
4561 return aResult._retn();
4563 long nbElements = NbElements();
4564 aResult->length( nbElements );
4565 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4566 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4567 aResult[i] = anIt->next()->GetID();
4569 return aResult._retn();
4573 //=============================================================================
4575 * Returns ids of all elements of given type
4577 //=============================================================================
4579 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4580 throw (SALOME::SALOME_Exception)
4582 Unexpect aCatch(SALOME_SalomeException);
4584 _preMeshInfo->FullLoadFromFile();
4586 SMESH::long_array_var aResult = new SMESH::long_array();
4587 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4589 if ( aSMESHDS_Mesh == NULL )
4590 return aResult._retn();
4592 long nbElements = NbElements();
4594 // No sense in returning ids of elements along with ids of nodes:
4595 // when theElemType == SMESH::ALL, return node ids only if
4596 // there are no elements
4597 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4598 return GetNodesId();
4600 aResult->length( nbElements );
4604 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4605 while ( i < nbElements && anIt->more() )
4606 aResult[i++] = anIt->next()->GetID();
4608 aResult->length( i );
4610 return aResult._retn();
4613 //=============================================================================
4615 * Returns ids of all nodes
4617 //=============================================================================
4619 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4620 throw (SALOME::SALOME_Exception)
4622 Unexpect aCatch(SALOME_SalomeException);
4624 _preMeshInfo->FullLoadFromFile();
4626 SMESH::long_array_var aResult = new SMESH::long_array();
4627 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4629 if ( aMeshDS == NULL )
4630 return aResult._retn();
4632 long nbNodes = NbNodes();
4633 aResult->length( nbNodes );
4634 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4635 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4636 aResult[i] = anIt->next()->GetID();
4638 return aResult._retn();
4641 //=============================================================================
4645 //=============================================================================
4647 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4648 throw (SALOME::SALOME_Exception)
4650 SMESH::ElementType type = SMESH::ALL;
4654 _preMeshInfo->FullLoadFromFile();
4656 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4658 SMESH_CATCH( SMESH::throwCorbaException );
4663 //=============================================================================
4667 //=============================================================================
4669 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4670 throw (SALOME::SALOME_Exception)
4673 _preMeshInfo->FullLoadFromFile();
4675 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4677 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4679 return ( SMESH::EntityType ) e->GetEntityType();
4682 //=============================================================================
4686 //=============================================================================
4688 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4689 throw (SALOME::SALOME_Exception)
4692 _preMeshInfo->FullLoadFromFile();
4694 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4696 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4698 return ( SMESH::GeometryType ) e->GetGeomType();
4701 //=============================================================================
4703 * Returns ID of elements for given submesh
4705 //=============================================================================
4706 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4707 throw (SALOME::SALOME_Exception)
4709 SMESH::long_array_var aResult = new SMESH::long_array();
4713 _preMeshInfo->FullLoadFromFile();
4715 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4716 if(!SM) return aResult._retn();
4718 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4719 if(!SDSM) return aResult._retn();
4721 aResult->length(SDSM->NbElements());
4723 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4725 while ( eIt->more() ) {
4726 aResult[i++] = eIt->next()->GetID();
4729 SMESH_CATCH( SMESH::throwCorbaException );
4731 return aResult._retn();
4734 //=============================================================================
4736 * Returns ID of nodes for given submesh
4737 * If param all==true - returns all nodes, else -
4738 * returns only nodes on shapes.
4740 //=============================================================================
4742 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4744 throw (SALOME::SALOME_Exception)
4746 SMESH::long_array_var aResult = new SMESH::long_array();
4750 _preMeshInfo->FullLoadFromFile();
4752 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4753 if(!SM) return aResult._retn();
4755 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4756 if(!SDSM) return aResult._retn();
4759 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4760 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4761 while ( nIt->more() ) {
4762 const SMDS_MeshNode* elem = nIt->next();
4763 theElems.insert( elem->GetID() );
4766 else { // all nodes of submesh elements
4767 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4768 while ( eIt->more() ) {
4769 const SMDS_MeshElement* anElem = eIt->next();
4770 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4771 while ( nIt->more() ) {
4772 const SMDS_MeshElement* elem = nIt->next();
4773 theElems.insert( elem->GetID() );
4778 aResult->length(theElems.size());
4779 set<int>::iterator itElem;
4781 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4782 aResult[i++] = *itElem;
4784 SMESH_CATCH( SMESH::throwCorbaException );
4786 return aResult._retn();
4789 //=============================================================================
4791 * Returns type of elements for given submesh
4793 //=============================================================================
4795 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4796 throw (SALOME::SALOME_Exception)
4798 SMESH::ElementType type = SMESH::ALL;
4802 _preMeshInfo->FullLoadFromFile();
4804 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4805 if(!SM) return SMESH::ALL;
4807 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4808 if(!SDSM) return SMESH::ALL;
4810 if(SDSM->NbElements()==0)
4811 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4813 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4814 const SMDS_MeshElement* anElem = eIt->next();
4816 type = ( SMESH::ElementType ) anElem->GetType();
4818 SMESH_CATCH( SMESH::throwCorbaException );
4824 //=============================================================================
4826 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4828 //=============================================================================
4830 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4833 _preMeshInfo->FullLoadFromFile();
4835 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4836 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4841 //=============================================================================
4843 * Get XYZ coordinates of node as list of double
4844 * If there is not node for given ID - returns empty list
4846 //=============================================================================
4848 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4851 _preMeshInfo->FullLoadFromFile();
4853 SMESH::double_array_var aResult = new SMESH::double_array();
4854 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4855 if ( aMeshDS == NULL )
4856 return aResult._retn();
4859 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4861 return aResult._retn();
4865 aResult[0] = aNode->X();
4866 aResult[1] = aNode->Y();
4867 aResult[2] = aNode->Z();
4868 return aResult._retn();
4872 //=============================================================================
4874 * For given node returns list of IDs of inverse elements
4875 * If there is not node for given ID - returns empty list
4877 //=============================================================================
4879 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4880 SMESH::ElementType elemType)
4883 _preMeshInfo->FullLoadFromFile();
4885 SMESH::long_array_var aResult = new SMESH::long_array();
4886 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4887 if ( aMeshDS == NULL )
4888 return aResult._retn();
4891 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4893 return aResult._retn();
4895 // find inverse elements
4896 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4897 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4898 aResult->length( aNode->NbInverseElements( type ));
4899 for( int i = 0; eIt->more(); ++i )
4901 const SMDS_MeshElement* elem = eIt->next();
4902 aResult[ i ] = elem->GetID();
4904 return aResult._retn();
4907 //=============================================================================
4909 * \brief Return position of a node on shape
4911 //=============================================================================
4913 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4916 _preMeshInfo->FullLoadFromFile();
4918 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4919 aNodePosition->shapeID = 0;
4920 aNodePosition->shapeType = GEOM::SHAPE;
4922 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4923 if ( !mesh ) return aNodePosition;
4925 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4927 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4929 aNodePosition->shapeID = aNode->getshapeId();
4930 switch ( pos->GetTypeOfPosition() ) {
4932 aNodePosition->shapeType = GEOM::EDGE;
4933 aNodePosition->params.length(1);
4934 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4936 case SMDS_TOP_FACE: {
4937 SMDS_FacePositionPtr fPos = pos;
4938 aNodePosition->shapeType = GEOM::FACE;
4939 aNodePosition->params.length(2);
4940 aNodePosition->params[0] = fPos->GetUParameter();
4941 aNodePosition->params[1] = fPos->GetVParameter();
4944 case SMDS_TOP_VERTEX:
4945 aNodePosition->shapeType = GEOM::VERTEX;
4947 case SMDS_TOP_3DSPACE:
4948 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4949 aNodePosition->shapeType = GEOM::SOLID;
4950 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4951 aNodePosition->shapeType = GEOM::SHELL;
4957 return aNodePosition;
4960 //=============================================================================
4962 * \brief Return position of an element on shape
4964 //=============================================================================
4966 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4969 _preMeshInfo->FullLoadFromFile();
4971 SMESH::ElementPosition anElementPosition;
4972 anElementPosition.shapeID = 0;
4973 anElementPosition.shapeType = GEOM::SHAPE;
4975 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4976 if ( !mesh ) return anElementPosition;
4978 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4980 anElementPosition.shapeID = anElem->getshapeId();
4981 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4982 if ( !aSp.IsNull() ) {
4983 switch ( aSp.ShapeType() ) {
4985 anElementPosition.shapeType = GEOM::EDGE;
4988 anElementPosition.shapeType = GEOM::FACE;
4991 anElementPosition.shapeType = GEOM::VERTEX;
4994 anElementPosition.shapeType = GEOM::SOLID;
4997 anElementPosition.shapeType = GEOM::SHELL;
5003 return anElementPosition;
5006 //=============================================================================
5008 * If given element is node returns IDs of shape from position
5009 * If there is not node for given ID - returns -1
5011 //=============================================================================
5013 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5016 _preMeshInfo->FullLoadFromFile();
5018 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5019 if ( aMeshDS == NULL )
5023 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5025 return aNode->getshapeId();
5032 //=============================================================================
5034 * For given element returns ID of result shape after
5035 * ::FindShape() from SMESH_MeshEditor
5036 * If there is not element for given ID - returns -1
5038 //=============================================================================
5040 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5043 _preMeshInfo->FullLoadFromFile();
5045 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5046 if ( aMeshDS == NULL )
5049 // try to find element
5050 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5054 ::SMESH_MeshEditor aMeshEditor(_impl);
5055 int index = aMeshEditor.FindShape( elem );
5063 //=============================================================================
5065 * Returns number of nodes for given element
5066 * If there is not element for given ID - returns -1
5068 //=============================================================================
5070 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5073 _preMeshInfo->FullLoadFromFile();
5075 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5076 if ( aMeshDS == NULL ) return -1;
5077 // try to find element
5078 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5079 if(!elem) return -1;
5080 return elem->NbNodes();
5084 //=============================================================================
5086 * Returns ID of node by given index for given element
5087 * If there is not element for given ID - returns -1
5088 * If there is not node for given index - returns -2
5090 //=============================================================================
5092 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5095 _preMeshInfo->FullLoadFromFile();
5097 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5098 if ( aMeshDS == NULL ) return -1;
5099 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5100 if(!elem) return -1;
5101 if( index>=elem->NbNodes() || index<0 ) return -1;
5102 return elem->GetNode(index)->GetID();
5105 //=============================================================================
5107 * Returns IDs of nodes of given element
5109 //=============================================================================
5111 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5114 _preMeshInfo->FullLoadFromFile();
5116 SMESH::long_array_var aResult = new SMESH::long_array();
5117 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5119 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5121 aResult->length( elem->NbNodes() );
5122 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5123 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5124 aResult[ i ] = n->GetID();
5127 return aResult._retn();
5130 //=============================================================================
5132 * Returns true if given node is medium node
5133 * in given quadratic element
5135 //=============================================================================
5137 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5140 _preMeshInfo->FullLoadFromFile();
5142 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5143 if ( aMeshDS == NULL ) return false;
5145 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5146 if(!aNode) return false;
5147 // try to find element
5148 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5149 if(!elem) return false;
5151 return elem->IsMediumNode(aNode);
5155 //=============================================================================
5157 * Returns true if given node is medium node
5158 * in one of quadratic elements
5160 //=============================================================================
5162 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5163 SMESH::ElementType theElemType)
5166 _preMeshInfo->FullLoadFromFile();
5168 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5169 if ( aMeshDS == NULL ) return false;
5172 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5173 if(!aNode) return false;
5175 SMESH_MesherHelper aHelper( *(_impl) );
5177 SMDSAbs_ElementType aType;
5178 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5179 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5180 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5181 else aType = SMDSAbs_All;
5183 return aHelper.IsMedium(aNode,aType);
5187 //=============================================================================
5189 * Returns number of edges for given element
5191 //=============================================================================
5193 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5196 _preMeshInfo->FullLoadFromFile();
5198 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5199 if ( aMeshDS == NULL ) return -1;
5200 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5201 if(!elem) return -1;
5202 return elem->NbEdges();
5206 //=============================================================================
5208 * Returns number of faces for given element
5210 //=============================================================================
5212 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5215 _preMeshInfo->FullLoadFromFile();
5217 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5218 if ( aMeshDS == NULL ) return -1;
5219 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5220 if(!elem) return -1;
5221 return elem->NbFaces();
5224 //=======================================================================
5225 //function : GetElemFaceNodes
5226 //purpose : Returns nodes of given face (counted from zero) for given element.
5227 //=======================================================================
5229 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5230 CORBA::Short faceIndex)
5233 _preMeshInfo->FullLoadFromFile();
5235 SMESH::long_array_var aResult = new SMESH::long_array();
5236 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5238 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5240 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5241 if ( faceIndex < vtool.NbFaces() )
5243 aResult->length( vtool.NbFaceNodes( faceIndex ));
5244 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5245 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5246 aResult[ i ] = nn[ i ]->GetID();
5250 return aResult._retn();
5253 //=======================================================================
5254 //function : GetFaceNormal
5255 //purpose : Returns three components of normal of given mesh face.
5256 //=======================================================================
5258 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5259 CORBA::Boolean normalized)
5262 _preMeshInfo->FullLoadFromFile();
5264 SMESH::double_array_var aResult = new SMESH::double_array();
5266 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5269 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5271 aResult->length( 3 );
5272 aResult[ 0 ] = normal.X();
5273 aResult[ 1 ] = normal.Y();
5274 aResult[ 2 ] = normal.Z();
5277 return aResult._retn();
5280 //=======================================================================
5281 //function : FindElementByNodes
5282 //purpose : Returns an element based on all given nodes.
5283 //=======================================================================
5285 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5288 _preMeshInfo->FullLoadFromFile();
5290 CORBA::Long elemID(0);
5291 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5293 vector< const SMDS_MeshNode * > nn( nodes.length() );
5294 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5295 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5298 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5299 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5300 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5301 _impl->NbVolumes( ORDER_QUADRATIC )))
5302 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5304 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5309 //================================================================================
5311 * \brief Return elements including all given nodes.
5313 //================================================================================
5315 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5316 SMESH::ElementType elemType)
5319 _preMeshInfo->FullLoadFromFile();
5321 SMESH::long_array_var result = new SMESH::long_array();
5323 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5325 vector< const SMDS_MeshNode * > nn( nodes.length() );
5326 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5327 nn[i] = mesh->FindNode( nodes[i] );
5329 std::vector<const SMDS_MeshElement *> elems;
5330 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5331 result->length( elems.size() );
5332 for ( size_t i = 0; i < elems.size(); ++i )
5333 result[i] = elems[i]->GetID();
5335 return result._retn();
5338 //=============================================================================
5340 * Returns true if given element is polygon
5342 //=============================================================================
5344 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5347 _preMeshInfo->FullLoadFromFile();
5349 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5350 if ( aMeshDS == NULL ) return false;
5351 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5352 if(!elem) return false;
5353 return elem->IsPoly();
5357 //=============================================================================
5359 * Returns true if given element is quadratic
5361 //=============================================================================
5363 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5366 _preMeshInfo->FullLoadFromFile();
5368 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5369 if ( aMeshDS == NULL ) return false;
5370 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5371 if(!elem) return false;
5372 return elem->IsQuadratic();
5375 //=============================================================================
5377 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5379 //=============================================================================
5381 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5384 _preMeshInfo->FullLoadFromFile();
5386 if ( const SMDS_BallElement* ball =
5387 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5388 return ball->GetDiameter();
5393 //=============================================================================
5395 * Returns bary center for given element
5397 //=============================================================================
5399 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5402 _preMeshInfo->FullLoadFromFile();
5404 SMESH::double_array_var aResult = new SMESH::double_array();
5405 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5406 if ( aMeshDS == NULL )
5407 return aResult._retn();
5409 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5411 return aResult._retn();
5413 if(elem->GetType()==SMDSAbs_Volume) {
5414 SMDS_VolumeTool aTool;
5415 if(aTool.Set(elem)) {
5417 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5422 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5424 double x=0., y=0., z=0.;
5425 for(; anIt->more(); ) {
5427 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5441 return aResult._retn();
5444 //================================================================================
5446 * \brief Create a group of elements preventing computation of a sub-shape
5448 //================================================================================
5450 SMESH::ListOfGroups*
5451 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5452 const char* theGroupName )
5453 throw ( SALOME::SALOME_Exception )
5455 Unexpect aCatch(SALOME_SalomeException);
5457 if ( !theGroupName || strlen( theGroupName) == 0 )
5458 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5460 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5461 ::SMESH_MeshEditor::ElemFeatures elemType;
5463 // submesh by subshape id
5464 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5465 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5468 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5469 if ( error && error->HasBadElems() )
5471 // sort bad elements by type
5472 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5473 const list<const SMDS_MeshElement*>& badElems =
5474 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5475 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5476 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5477 for ( ; elemIt != elemEnd; ++elemIt )
5479 const SMDS_MeshElement* elem = *elemIt;
5480 if ( !elem ) continue;
5482 if ( elem->GetID() < 1 )
5484 // elem is a temporary element, make a real element
5485 vector< const SMDS_MeshNode* > nodes;
5486 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5487 while ( nIt->more() && elem )
5489 nodes.push_back( nIt->next() );
5490 if ( nodes.back()->GetID() < 1 )
5491 elem = 0; // a temporary element on temporary nodes
5495 ::SMESH_MeshEditor editor( _impl );
5496 elem = editor.AddElement( nodes, elemType.Init( elem ));
5500 elemsByType[ elem->GetType() ].push_back( elem );
5503 // how many groups to create?
5505 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5506 nbTypes += int( !elemsByType[ i ].empty() );
5507 groups->length( nbTypes );
5510 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5512 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5513 if ( elems.empty() ) continue;
5515 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5516 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5518 SMESH::SMESH_Mesh_var mesh = _this();
5519 SALOMEDS::SObject_wrap aSO =
5520 _gen_i->PublishGroup( mesh, groups[ iG ],
5521 GEOM::GEOM_Object::_nil(), theGroupName);
5523 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5524 if ( !grp_i ) continue;
5526 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5527 for ( size_t iE = 0; iE < elems.size(); ++iE )
5528 grpDS->SMDSGroup().Add( elems[ iE ]);
5533 return groups._retn();
5536 //=============================================================================
5538 * Create and publish group servants if any groups were imported or created anyhow
5540 //=============================================================================
5542 void SMESH_Mesh_i::CreateGroupServants()
5544 SMESH::SMESH_Mesh_var aMesh = _this();
5547 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5548 while ( groupIt->more() )
5550 ::SMESH_Group* group = groupIt->next();
5551 int anId = group->GetID();
5553 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5554 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5556 addedIDs.insert( anId );
5558 SMESH_GroupBase_i* aGroupImpl;
5560 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5561 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5563 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5564 shape = groupOnGeom->GetShape();
5567 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5570 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5571 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5572 aGroupImpl->Register();
5574 // register CORBA object for persistence
5575 int nextId = _gen_i->RegisterObject( groupVar );
5576 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5577 else { nextId = 0; } // avoid "unused variable" warning in release mode
5579 // publishing the groups in the study
5580 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5581 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5583 if ( !addedIDs.empty() )
5586 set<int>::iterator id = addedIDs.begin();
5587 for ( ; id != addedIDs.end(); ++id )
5589 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5590 int i = std::distance( _mapGroups.begin(), it );
5591 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5596 //=============================================================================
5598 * \brief Return true if all sub-meshes are computed OK - to update an icon
5600 //=============================================================================
5602 bool SMESH_Mesh_i::IsComputedOK()
5604 return _impl->IsComputedOK();
5607 //=============================================================================
5609 * \brief Return groups cantained in _mapGroups by their IDs
5611 //=============================================================================
5613 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5615 int nbGroups = groupIDs.size();
5616 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5617 aList->length( nbGroups );
5619 list<int>::const_iterator ids = groupIDs.begin();
5620 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5622 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5623 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5624 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5626 aList->length( nbGroups );
5627 return aList._retn();
5630 //=============================================================================
5632 * \brief Return information about imported file
5634 //=============================================================================
5636 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5638 SMESH::MedFileInfo_var res( _medFileInfo );
5639 if ( !res.operator->() ) {
5640 res = new SMESH::MedFileInfo;
5642 res->fileSize = res->major = res->minor = res->release = -1;
5647 //=======================================================================
5648 //function : FileInfoToString
5649 //purpose : Persistence of file info
5650 //=======================================================================
5652 std::string SMESH_Mesh_i::FileInfoToString()
5655 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5657 s = SMESH_Comment( _medFileInfo->fileSize )
5658 << " " << _medFileInfo->major
5659 << " " << _medFileInfo->minor
5660 << " " << _medFileInfo->release
5661 << " " << _medFileInfo->fileName;
5666 //=======================================================================
5667 //function : FileInfoFromString
5668 //purpose : Persistence of file info
5669 //=======================================================================
5671 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5673 std::string size, major, minor, release, fileName;
5674 std::istringstream is(info);
5675 is >> size >> major >> minor >> release;
5676 fileName = info.data() + ( size.size() + 1 +
5679 release.size()+ 1 );
5681 _medFileInfo = new SMESH::MedFileInfo();
5682 _medFileInfo->fileName = fileName.c_str();
5683 _medFileInfo->fileSize = atoi( size.c_str() );
5684 _medFileInfo->major = atoi( major.c_str() );
5685 _medFileInfo->minor = atoi( minor.c_str() );
5686 _medFileInfo->release = atoi( release.c_str() );
5689 //=============================================================================
5691 * \brief Pass names of mesh groups from study to mesh DS
5693 //=============================================================================
5695 void SMESH_Mesh_i::checkGroupNames()
5697 int nbGrp = NbGroups();
5701 SMESH::ListOfGroups* grpList = 0;
5702 // avoid dump of "GetGroups"
5704 // store python dump into a local variable inside local scope
5705 SMESH::TPythonDump pDump; // do not delete this line of code
5706 grpList = GetGroups();
5709 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5710 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5713 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5714 if ( aGrpSO->_is_nil() )
5716 // correct name of the mesh group if necessary
5717 const char* guiName = aGrpSO->GetName();
5718 if ( strcmp(guiName, aGrp->GetName()) )
5719 aGrp->SetName( guiName );
5723 //=============================================================================
5725 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5727 //=============================================================================
5728 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5730 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5734 //=============================================================================
5736 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5738 //=============================================================================
5740 char* SMESH_Mesh_i::GetParameters()
5742 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5745 //=============================================================================
5747 * \brief Returns list of notebook variables used for last Mesh operation
5749 //=============================================================================
5750 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5752 SMESH::string_array_var aResult = new SMESH::string_array();
5753 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5755 CORBA::String_var aParameters = GetParameters();
5756 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5757 if ( aSections->length() > 0 ) {
5758 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5759 aResult->length( aVars.length() );
5760 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5761 aResult[i] = CORBA::string_dup( aVars[i] );
5764 return aResult._retn();
5767 //=======================================================================
5768 //function : GetTypes
5769 //purpose : Returns types of elements it contains
5770 //=======================================================================
5772 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5775 return _preMeshInfo->GetTypes();
5777 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5781 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5782 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5783 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5784 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5785 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5786 if (_impl->NbNodes() &&
5787 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5788 types->length( nbTypes );
5790 return types._retn();
5793 //=======================================================================
5794 //function : GetMesh
5795 //purpose : Returns self
5796 //=======================================================================
5798 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5800 return SMESH::SMESH_Mesh::_duplicate( _this() );
5803 //=======================================================================
5804 //function : IsMeshInfoCorrect
5805 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5806 // * happen if mesh data is not yet fully loaded from the file of study.
5807 //=======================================================================
5809 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5811 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5814 //=============================================================================
5816 * \brief Returns number of mesh elements per each \a EntityType
5818 //=============================================================================
5820 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5823 return _preMeshInfo->GetMeshInfo();
5825 SMESH::long_array_var aRes = new SMESH::long_array();
5826 aRes->length(SMESH::Entity_Last);
5827 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5829 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5831 return aRes._retn();
5832 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5833 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5834 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5835 return aRes._retn();
5838 //=============================================================================
5840 * \brief Returns number of mesh elements per each \a ElementType
5842 //=============================================================================
5844 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5846 SMESH::long_array_var aRes = new SMESH::long_array();
5847 aRes->length(SMESH::NB_ELEMENT_TYPES);
5848 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5851 const SMDS_MeshInfo* meshInfo = 0;
5853 meshInfo = _preMeshInfo;
5854 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5855 meshInfo = & meshDS->GetMeshInfo();
5858 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5859 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5861 return aRes._retn();
5864 //=============================================================================
5866 * Collect statistic of mesh elements given by iterator
5868 //=============================================================================
5870 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5871 SMESH::long_array& theInfo)
5873 if (!theItr) return;
5874 while (theItr->more())
5875 theInfo[ theItr->next()->GetEntityType() ]++;
5877 //=============================================================================
5879 * Returns mesh unstructed grid information.
5881 //=============================================================================
5883 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5885 SALOMEDS::TMPFile_var SeqFile;
5886 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5887 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5889 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5890 aWriter->WriteToOutputStringOn();
5891 aWriter->SetInputData(aGrid);
5892 aWriter->SetFileTypeToBinary();
5894 char* str = aWriter->GetOutputString();
5895 int size = aWriter->GetOutputStringLength();
5897 //Allocate octet buffer of required size
5898 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5899 //Copy ostrstream content to the octet buffer
5900 memcpy(OctetBuf, str, size);
5901 //Create and return TMPFile
5902 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5906 return SeqFile._retn();
5909 //=============================================================================
5910 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5911 * SMESH::ElementType type) */
5913 using namespace SMESH::Controls;
5914 //-----------------------------------------------------------------------------
5915 struct PredicateIterator : public SMDS_ElemIterator
5917 SMDS_ElemIteratorPtr _elemIter;
5918 PredicatePtr _predicate;
5919 const SMDS_MeshElement* _elem;
5920 SMDSAbs_ElementType _type;
5922 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5923 PredicatePtr predicate,
5924 SMDSAbs_ElementType type):
5925 _elemIter(iterator), _predicate(predicate), _type(type)
5933 virtual const SMDS_MeshElement* next()
5935 const SMDS_MeshElement* res = _elem;
5937 while ( _elemIter->more() && !_elem )
5939 if ((_elem = _elemIter->next()) &&
5940 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5941 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5948 //-----------------------------------------------------------------------------
5949 struct IDSourceIterator : public SMDS_ElemIterator
5951 const CORBA::Long* _idPtr;
5952 const CORBA::Long* _idEndPtr;
5953 SMESH::long_array_var _idArray;
5954 const SMDS_Mesh* _mesh;
5955 const SMDSAbs_ElementType _type;
5956 const SMDS_MeshElement* _elem;
5958 IDSourceIterator( const SMDS_Mesh* mesh,
5959 const CORBA::Long* ids,
5961 SMDSAbs_ElementType type):
5962 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5964 if ( _idPtr && nbIds && _mesh )
5967 IDSourceIterator( const SMDS_Mesh* mesh,
5968 SMESH::long_array* idArray,
5969 SMDSAbs_ElementType type):
5970 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5972 if ( idArray && _mesh )
5974 _idPtr = &_idArray[0];
5975 _idEndPtr = _idPtr + _idArray->length();
5983 virtual const SMDS_MeshElement* next()
5985 const SMDS_MeshElement* res = _elem;
5987 while ( _idPtr < _idEndPtr && !_elem )
5989 if ( _type == SMDSAbs_Node )
5991 _elem = _mesh->FindNode( *_idPtr++ );
5993 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5994 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6002 //-----------------------------------------------------------------------------
6004 struct NodeOfElemIterator : public SMDS_ElemIterator
6006 TColStd_MapOfInteger _checkedNodeIDs;
6007 SMDS_ElemIteratorPtr _elemIter;
6008 SMDS_ElemIteratorPtr _nodeIter;
6009 const SMDS_MeshElement* _node;
6011 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6013 if ( _elemIter && _elemIter->more() )
6015 _nodeIter = _elemIter->next()->nodesIterator();
6023 virtual const SMDS_MeshElement* next()
6025 const SMDS_MeshElement* res = _node;
6027 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6029 if ( _nodeIter->more() )
6031 _node = _nodeIter->next();
6032 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6037 _nodeIter = _elemIter->next()->nodesIterator();
6045 //=============================================================================
6047 * Return iterator on elements of given type in given object
6049 //=============================================================================
6051 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6052 SMESH::ElementType theType)
6054 SMDS_ElemIteratorPtr elemIt;
6055 bool typeOK = ( theType == SMESH::ALL );
6056 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6058 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6059 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6060 if ( !mesh_i ) return elemIt;
6061 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6063 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6065 elemIt = meshDS->elementsIterator( elemType );
6068 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6070 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6073 elemIt = sm->GetElements();
6074 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6076 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6077 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6081 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6083 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6084 if ( groupDS && ( elemType == groupDS->GetType() ||
6085 elemType == SMDSAbs_Node ||
6086 elemType == SMDSAbs_All ))
6088 elemIt = groupDS->GetElements();
6089 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6092 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6094 if ( filter_i->GetElementType() == theType ||
6095 filter_i->GetElementType() == SMESH::ALL ||
6096 elemType == SMDSAbs_Node ||
6097 elemType == SMDSAbs_All)
6099 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6100 if ( pred_i && pred_i->GetPredicate() )
6102 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6103 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6104 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6105 elemIt = SMDS_ElemIteratorPtr
6106 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6107 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6113 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6114 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6115 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6117 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6118 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6121 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6122 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6126 SMESH::long_array_var ids = theObject->GetIDs();
6127 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6129 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6132 if ( elemIt && elemIt->more() && !typeOK )
6134 if ( elemType == SMDSAbs_Node )
6136 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6140 elemIt = SMDS_ElemIteratorPtr();
6146 //=============================================================================
6147 namespace // Finding concurrent hypotheses
6148 //=============================================================================
6152 * \brief mapping of mesh dimension into shape type
6154 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6156 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6158 case 0: aType = TopAbs_VERTEX; break;
6159 case 1: aType = TopAbs_EDGE; break;
6160 case 2: aType = TopAbs_FACE; break;
6162 default:aType = TopAbs_SOLID; break;
6167 //-----------------------------------------------------------------------------
6169 * \brief Internal structure used to find concurrent submeshes
6171 * It represents a pair < submesh, concurrent dimension >, where
6172 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6173 * with another submesh. In other words, it is dimension of a hypothesis assigned
6180 int _dim; //!< a dimension the algo can build (concurrent dimension)
6181 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6182 TopTools_MapOfShape _shapeMap;
6183 SMESH_subMesh* _subMesh;
6184 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6186 //-----------------------------------------------------------------------------
6187 // Return the algorithm
6188 const SMESH_Algo* GetAlgo() const
6189 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6191 //-----------------------------------------------------------------------------
6193 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6195 const TopoDS_Shape& theShape)
6197 _subMesh = (SMESH_subMesh*)theSubMesh;
6198 SetShape( theDim, theShape );
6201 //-----------------------------------------------------------------------------
6203 void SetShape(const int theDim,
6204 const TopoDS_Shape& theShape)
6207 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6208 if (_dim >= _ownDim)
6209 _shapeMap.Add( theShape );
6211 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6212 for( ; anExp.More(); anExp.Next() )
6213 _shapeMap.Add( anExp.Current() );
6217 //-----------------------------------------------------------------------------
6218 //! Check sharing of sub-shapes
6219 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6220 const TopTools_MapOfShape& theToFind,
6221 const TopAbs_ShapeEnum theType)
6223 bool isShared = false;
6224 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6225 for (; !isShared && anItr.More(); anItr.Next() )
6227 const TopoDS_Shape aSubSh = anItr.Key();
6228 // check for case when concurrent dimensions are same
6229 isShared = theToFind.Contains( aSubSh );
6230 // check for sub-shape with concurrent dimension
6231 TopExp_Explorer anExp( aSubSh, theType );
6232 for ( ; !isShared && anExp.More(); anExp.Next() )
6233 isShared = theToFind.Contains( anExp.Current() );
6238 //-----------------------------------------------------------------------------
6239 //! check algorithms
6240 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6241 const SMESHDS_Hypothesis* theA2)
6243 if ( !theA1 || !theA2 ||
6244 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6245 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6246 return false; // one of the hypothesis is not algorithm
6247 // check algorithm names (should be equal)
6248 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6252 //-----------------------------------------------------------------------------
6253 //! Check if sub-shape hypotheses are concurrent
6254 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6256 if ( _subMesh == theOther->_subMesh )
6257 return false; // same sub-shape - should not be
6259 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6260 // any of the two submeshes is not on COMPOUND shape )
6261 // -> no concurrency
6262 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6263 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6264 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6265 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6266 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6269 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6270 if ( !checkSubShape )
6273 // check algorithms to be same
6274 const SMESH_Algo* a1 = this->GetAlgo();
6275 const SMESH_Algo* a2 = theOther->GetAlgo();
6276 bool isSame = checkAlgo( a1, a2 );
6280 return false; // pb?
6281 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6284 // check hypothesises for concurrence (skip first as algorithm)
6286 // pointers should be same, because it is referened from mesh hypothesis partition
6287 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6288 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6289 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6290 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6292 // the submeshes are concurrent if their algorithms has different parameters
6293 return nbSame != theOther->_hypotheses.size() - 1;
6296 // Return true if algorithm of this SMESH_DimHyp is used if no
6297 // sub-mesh order is imposed by the user
6298 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6300 // NeedDiscreteBoundary() algo has a higher priority
6301 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6302 theOther->GetAlgo()->NeedDiscreteBoundary() )
6303 return !this->GetAlgo()->NeedDiscreteBoundary();
6305 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6308 }; // end of SMESH_DimHyp
6309 //-----------------------------------------------------------------------------
6311 typedef list<const SMESH_DimHyp*> TDimHypList;
6313 //-----------------------------------------------------------------------------
6315 void addDimHypInstance(const int theDim,
6316 const TopoDS_Shape& theShape,
6317 const SMESH_Algo* theAlgo,
6318 const SMESH_subMesh* theSubMesh,
6319 const list <const SMESHDS_Hypothesis*>& theHypList,
6320 TDimHypList* theDimHypListArr )
6322 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6323 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6324 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6325 dimHyp->_hypotheses.push_front(theAlgo);
6326 listOfdimHyp.push_back( dimHyp );
6329 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6330 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6331 theHypList.begin(), theHypList.end() );
6334 //-----------------------------------------------------------------------------
6335 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6336 TDimHypList& theListOfConcurr)
6338 if ( theListOfConcurr.empty() )
6340 theListOfConcurr.push_back( theDimHyp );
6344 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6345 while ( hypIt != theListOfConcurr.end() &&
6346 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6348 theListOfConcurr.insert( hypIt, theDimHyp );
6352 //-----------------------------------------------------------------------------
6353 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6354 const TDimHypList& theListOfDimHyp,
6355 TDimHypList& theListOfConcurrHyp,
6356 set<int>& theSetOfConcurrId )
6358 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6359 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6361 const SMESH_DimHyp* curDimHyp = *rIt;
6362 if ( curDimHyp == theDimHyp )
6363 break; // meet own dimHyp pointer in same dimension
6365 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6366 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6368 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6373 //-----------------------------------------------------------------------------
6374 void unionLists(TListOfInt& theListOfId,
6375 TListOfListOfInt& theListOfListOfId,
6378 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6379 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6381 continue; //skip already treated lists
6382 // check if other list has any same submesh object
6383 TListOfInt& otherListOfId = *it;
6384 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6385 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6388 // union two lists (from source into target)
6389 TListOfInt::iterator it2 = otherListOfId.begin();
6390 for ( ; it2 != otherListOfId.end(); it2++ ) {
6391 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6392 theListOfId.push_back(*it2);
6394 // clear source list
6395 otherListOfId.clear();
6398 //-----------------------------------------------------------------------------
6400 //! free memory allocated for dimension-hypothesis objects
6401 void removeDimHyps( TDimHypList* theArrOfList )
6403 for (int i = 0; i < 4; i++ ) {
6404 TDimHypList& listOfdimHyp = theArrOfList[i];
6405 TDimHypList::const_iterator it = listOfdimHyp.begin();
6406 for ( ; it != listOfdimHyp.end(); it++ )
6411 //-----------------------------------------------------------------------------
6413 * \brief find common submeshes with given submesh
6414 * \param theSubMeshList list of already collected submesh to check
6415 * \param theSubMesh given submesh to intersect with other
6416 * \param theCommonSubMeshes collected common submeshes
6418 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6419 const SMESH_subMesh* theSubMesh,
6420 set<const SMESH_subMesh*>& theCommon )
6424 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6425 for ( ; it != theSubMeshList.end(); it++ )
6426 theSubMesh->FindIntersection( *it, theCommon );
6427 theSubMeshList.push_back( theSubMesh );
6428 //theCommon.insert( theSubMesh );
6431 //-----------------------------------------------------------------------------
6432 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6434 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6435 for ( ; listsIt != smLists.end(); ++listsIt )
6437 const TListOfInt& smIDs = *listsIt;
6438 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6446 //=============================================================================
6448 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6450 //=============================================================================
6452 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6454 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6455 if ( isSubMeshInList( submeshID, anOrder ))
6458 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6459 return isSubMeshInList( submeshID, allConurrent );
6462 //=============================================================================
6464 * \brief Return submesh objects list in meshing order
6466 //=============================================================================
6468 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6470 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6472 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6474 return aResult._retn();
6476 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6477 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6478 anOrder.splice( anOrder.end(), allConurrent );
6481 TListOfListOfInt::iterator listIt = anOrder.begin();
6482 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6483 unionLists( *listIt, anOrder, listIndx + 1 );
6485 // convert submesh ids into interface instances
6486 // and dump command into python
6487 convertMeshOrder( anOrder, aResult, false );
6489 return aResult._retn();
6492 //=============================================================================
6494 * \brief Finds concurrent sub-meshes
6496 //=============================================================================
6498 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6500 TListOfListOfInt anOrder;
6501 ::SMESH_Mesh& mesh = GetImpl();
6503 // collect submeshes and detect concurrent algorithms and hypothesises
6504 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6506 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6507 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6508 ::SMESH_subMesh* sm = (*i_sm).second;
6510 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6512 // list of assigned hypothesises
6513 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6514 // Find out dimensions where the submesh can be concurrent.
6515 // We define the dimensions by algo of each of hypotheses in hypList
6516 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6517 for( ; hypIt != hypList.end(); hypIt++ ) {
6518 SMESH_Algo* anAlgo = 0;
6519 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6520 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6521 // hyp it-self is algo
6522 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6524 // try to find algorithm with help of sub-shapes
6525 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6526 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6527 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6530 continue; // no algorithm assigned to a current submesh
6532 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6533 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6535 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6536 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6537 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6539 } // end iterations on submesh
6541 // iterate on created dimension-hypotheses and check for concurrents
6542 for ( int i = 0; i < 4; i++ ) {
6543 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6544 // check for concurrents in own and other dimensions (step-by-step)
6545 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6546 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6547 const SMESH_DimHyp* dimHyp = *dhIt;
6548 TDimHypList listOfConcurr;
6549 set<int> setOfConcurrIds;
6550 // looking for concurrents and collect into own list
6551 for ( int j = i; j < 4; j++ )
6552 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6553 // check if any concurrents found
6554 if ( listOfConcurr.size() > 0 ) {
6555 // add own submesh to list of concurrent
6556 addInOrderOfPriority( dimHyp, listOfConcurr );
6557 list<int> listOfConcurrIds;
6558 TDimHypList::iterator hypIt = listOfConcurr.begin();
6559 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6560 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6561 anOrder.push_back( listOfConcurrIds );
6566 removeDimHyps(dimHypListArr);
6568 // now, minimize the number of concurrent groups
6569 // Here we assume that lists of submeshes can have same submesh
6570 // in case of multi-dimension algorithms, as result
6571 // list with common submesh has to be united into one list
6573 TListOfListOfInt::iterator listIt = anOrder.begin();
6574 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6575 unionLists( *listIt, anOrder, listIndx + 1 );
6581 //=============================================================================
6583 * \brief Set submesh object order
6584 * \param theSubMeshArray submesh array order
6586 //=============================================================================
6588 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6591 _preMeshInfo->ForgetOrLoad();
6594 ::SMESH_Mesh& mesh = GetImpl();
6596 TPythonDump aPythonDump; // prevent dump of called methods
6597 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6599 TListOfListOfInt subMeshOrder;
6600 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6602 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6603 TListOfInt subMeshIds;
6605 aPythonDump << ", ";
6606 aPythonDump << "[ ";
6607 // Collect subMeshes which should be clear
6608 // do it list-by-list, because modification of submesh order
6609 // take effect between concurrent submeshes only
6610 set<const SMESH_subMesh*> subMeshToClear;
6611 list<const SMESH_subMesh*> subMeshList;
6612 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6614 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6616 aPythonDump << ", ";
6617 aPythonDump << subMesh;
6618 subMeshIds.push_back( subMesh->GetId() );
6619 // detect common parts of submeshes
6620 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6621 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6623 aPythonDump << " ]";
6624 subMeshOrder.push_back( subMeshIds );
6626 // clear collected sub-meshes
6627 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6628 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6629 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6631 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6632 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6633 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6636 aPythonDump << " ])";
6638 mesh.SetMeshOrder( subMeshOrder );
6641 SMESH::SMESH_Mesh_var me = _this();
6642 _gen_i->UpdateIcons( me );
6647 //=============================================================================
6649 * \brief Convert submesh ids into submesh interfaces
6651 //=============================================================================
6653 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6654 SMESH::submesh_array_array& theResOrder,
6655 const bool theIsDump)
6657 int nbSet = theIdsOrder.size();
6658 TPythonDump aPythonDump; // prevent dump of called methods
6660 aPythonDump << "[ ";
6661 theResOrder.length(nbSet);
6662 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6664 for( ; it != theIdsOrder.end(); it++ ) {
6665 // translate submesh identificators into submesh objects
6666 // takeing into account real number of concurrent lists
6667 const TListOfInt& aSubOrder = (*it);
6668 if (!aSubOrder.size())
6671 aPythonDump << "[ ";
6672 // convert shape indices into interfaces
6673 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6674 aResSubSet->length(aSubOrder.size());
6675 TListOfInt::const_iterator subIt = aSubOrder.begin();
6677 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6678 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6680 SMESH::SMESH_subMesh_var subMesh =
6681 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6684 aPythonDump << ", ";
6685 aPythonDump << subMesh;
6687 aResSubSet[ j++ ] = subMesh;
6690 aPythonDump << " ]";
6692 theResOrder[ listIndx++ ] = aResSubSet;
6694 // correct number of lists
6695 theResOrder.length( listIndx );
6698 // finilise python dump
6699 aPythonDump << " ]";
6700 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6704 namespace // utils used by SMESH_MeshPartDS
6707 * \brief Class used to access to protected data of SMDS_MeshInfo
6709 struct TMeshInfo : public SMDS_MeshInfo
6711 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6714 * \brief Element holing its ID only
6716 struct TElemID : public SMDS_LinearEdge
6718 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6722 //================================================================================
6724 // Implementation of SMESH_MeshPartDS
6726 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6727 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6729 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6730 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6733 _meshDS = mesh_i->GetImpl().GetMeshDS();
6735 SetPersistentId( _meshDS->GetPersistentId() );
6737 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6739 // <meshPart> is the whole mesh
6740 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6742 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6743 myGroupSet = _meshDS->GetGroups();
6748 SMESH::long_array_var anIDs = meshPart->GetIDs();
6749 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6750 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6752 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6753 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6754 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6759 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6760 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6761 if ( _elements[ e->GetType() ].insert( e ).second )
6764 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6765 while ( nIt->more() )
6767 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6768 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6775 ShapeToMesh( _meshDS->ShapeToMesh() );
6777 _meshDS = 0; // to enforce iteration on _elements and _nodes
6780 // -------------------------------------------------------------------------------------
6781 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6782 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6785 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6786 for ( ; partIt != meshPart.end(); ++partIt )
6787 if ( const SMDS_MeshElement * e = *partIt )
6788 if ( _elements[ e->GetType() ].insert( e ).second )
6791 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6792 while ( nIt->more() )
6794 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6795 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6801 // -------------------------------------------------------------------------------------
6802 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6804 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6806 TElemID elem( IDelem );
6807 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6808 if ( !_elements[ iType ].empty() )
6810 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6811 if ( it != _elements[ iType ].end() )
6816 // -------------------------------------------------------------------------------------
6817 bool SMESH_MeshPartDS::HasNumerationHoles()
6819 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6821 return ( MinNodeID() != 1 ||
6822 MaxNodeID() != NbNodes() ||
6823 MinElementID() != 1 ||
6824 MaxElementID() != NbElements() );
6826 // -------------------------------------------------------------------------------------
6827 int SMESH_MeshPartDS::MaxNodeID() const
6829 if ( _meshDS ) return _meshDS->MaxNodeID();
6830 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6832 // -------------------------------------------------------------------------------------
6833 int SMESH_MeshPartDS::MinNodeID() const
6835 if ( _meshDS ) return _meshDS->MinNodeID();
6836 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6838 // -------------------------------------------------------------------------------------
6839 int SMESH_MeshPartDS::MaxElementID() const
6841 if ( _meshDS ) return _meshDS->MaxElementID();
6843 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6844 if ( !_elements[ iType ].empty() )
6845 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6848 // -------------------------------------------------------------------------------------
6849 int SMESH_MeshPartDS::MinElementID() const
6851 if ( _meshDS ) return _meshDS->MinElementID();
6853 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6854 if ( !_elements[ iType ].empty() )
6855 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6858 // -------------------------------------------------------------------------------------
6859 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6861 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6863 typedef SMDS_SetIterator
6864 <const SMDS_MeshElement*,
6865 TIDSortedElemSet::const_iterator,
6866 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6867 SMDS_MeshElement::GeomFilter
6870 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6872 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6873 _elements[type].end(),
6874 SMDS_MeshElement::GeomFilter( geomType )));
6876 // -------------------------------------------------------------------------------------
6877 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6879 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6881 typedef SMDS_SetIterator
6882 <const SMDS_MeshElement*,
6883 TIDSortedElemSet::const_iterator,
6884 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6885 SMDS_MeshElement::EntityFilter
6888 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6890 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6891 _elements[type].end(),
6892 SMDS_MeshElement::EntityFilter( entity )));
6894 // -------------------------------------------------------------------------------------
6895 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6897 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6898 if ( type == SMDSAbs_All && !_meshDS )
6900 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6902 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6903 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6905 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6907 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6908 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6910 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6911 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6913 // -------------------------------------------------------------------------------------
6914 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6915 iterType SMESH_MeshPartDS::methName() const \
6917 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6918 return _meshDS ? _meshDS->methName() : iterType \
6919 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6921 // -------------------------------------------------------------------------------------
6922 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6923 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6924 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6925 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6926 #undef _GET_ITER_DEFINE
6928 // END Implementation of SMESH_MeshPartDS
6930 //================================================================================