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_wrap 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_wrap 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;
2298 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2299 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2301 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2302 geomClient->RemoveShapeFromBuffer( ior.in() );
2304 // Update data taking into account that if topology doesn't change
2305 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2308 _preMeshInfo->ForgetAllData();
2311 if ( isBreakLink || !isShaper )
2313 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2314 if ( newShape.IsNull() )
2317 _mainShapeTick = mainGO->GetTick();
2319 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2321 // store data of groups on geometry
2322 std::vector< TGroupOnGeomData > groupsData;
2323 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2324 groupsData.reserve( groups.size() );
2325 TopTools_DataMapOfShapeShape old2newShapeMap;
2326 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2327 for ( ; g != groups.end(); ++g )
2329 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2331 groupsData.push_back( TGroupOnGeomData( group ));
2334 SMESH::SMESH_GroupOnGeom_var gog;
2335 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2336 if ( i_grp != _mapGroups.end() )
2337 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2339 GEOM::GEOM_Object_var geom;
2340 if ( !gog->_is_nil() )
2344 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2345 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2346 if ( !grpSO->_is_nil() &&
2347 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2348 geomRefSO->ReferencedObject( geomSO.inout() ))
2350 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2351 geom = GEOM::GEOM_Object::_narrow( geomObj );
2356 geom = gog->GetShape();
2359 if ( !geom->_is_nil() )
2361 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2362 geomClient->RemoveShapeFromBuffer( ior.in() );
2363 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2364 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2366 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2368 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2372 // store assigned hypotheses
2373 std::vector< pair< int, THypList > > ids2Hyps;
2374 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2375 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2377 const TopoDS_Shape& s = s2hyps.Key();
2378 const THypList& hyps = s2hyps.ChangeValue();
2379 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2382 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2384 // count shapes excluding compounds corresponding to geom groups
2385 int oldNbSubShapes = meshDS->MaxShapeIndex();
2386 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2388 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2389 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2392 std::set<int> subIds;
2393 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2394 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2395 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2398 // check if shape topology changes - save shape type per shape ID
2399 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2400 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2401 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2403 // change shape to mesh
2404 _impl->ShapeToMesh( TopoDS_Shape() );
2405 _impl->ShapeToMesh( newShape );
2407 // check if shape topology changes - check new shape types
2408 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2409 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2411 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2412 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2415 // re-add shapes (compounds) of geom groups
2416 std::map< int, int > old2newIDs; // group IDs
2417 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2418 for ( ; data != _geomGroupData.end(); ++data )
2421 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2422 if ( ii2i != ii2iMap.end() )
2423 oldID = ii2i->second;
2425 TopoDS_Shape newShape = newGroupShape( *data, isBreakLink ? IS_BREAK_LINK : MAIN_TRANSFORMED );
2426 if ( !newShape.IsNull() )
2428 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2430 TopoDS_Compound compound;
2431 BRep_Builder().MakeCompound( compound );
2432 BRep_Builder().Add( compound, newShape );
2433 newShape = compound;
2435 int newID = _impl->GetSubMesh( newShape )->GetId();
2436 if ( oldID && oldID != newID )
2437 old2newIDs.insert( std::make_pair( oldID, newID ));
2441 // re-assign hypotheses
2442 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2444 if ( !sameTopology && ids2Hyps[i].first != 1 )
2445 continue; // assign only global hypos
2446 int sID = ids2Hyps[i].first;
2447 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2448 if ( o2n != old2newIDs.end() )
2450 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2451 const THypList& hyps = ids2Hyps[i].second;
2452 THypList::const_iterator h = hyps.begin();
2453 for ( ; h != hyps.end(); ++h )
2454 _impl->AddHypothesis( s, (*h)->GetID() );
2457 if ( !sameTopology )
2459 // remove invalid study sub-objects
2460 CheckGeomGroupModif();
2464 // restore groups on geometry
2465 for ( size_t i = 0; i < groupsData.size(); ++i )
2467 const TGroupOnGeomData& data = groupsData[i];
2468 if ( data._shape.IsNull() )
2471 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2472 if ( i2g == _mapGroups.end() ) continue;
2474 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2475 if ( !gr_i ) continue;
2477 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2479 _mapGroups.erase( i2g );
2481 g->GetGroupDS()->SetColor( data._color );
2484 std::map< int, int >::iterator o2n = old2newIDs.begin();
2485 for ( ; o2n != old2newIDs.end(); ++o2n )
2487 int newID = o2n->second, oldID = o2n->first;
2488 if ( !_mapSubMesh.count( oldID ))
2492 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2493 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2494 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2496 _mapSubMesh. erase(oldID);
2497 _mapSubMesh_i. erase(oldID);
2498 _mapSubMeshIor.erase(oldID);
2500 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2503 // update _mapSubMesh
2504 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2505 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2506 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2509 _gen_i->UpdateIcons( me );
2511 if ( !isBreakLink && isShaper )
2513 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2514 if ( !meshSO->_is_nil() )
2515 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2519 //=============================================================================
2521 * \brief Update objects depending on changed geom groups
2523 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2524 * issue 0020210: Update of a smesh group after modification of the associated geom group
2526 //=============================================================================
2528 void SMESH_Mesh_i::CheckGeomGroupModif()
2530 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2531 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2532 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2533 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2534 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2536 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2537 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2538 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2540 int nbValid = 0, nbRemoved = 0;
2541 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2542 for ( ; chItr->More(); chItr->Next() )
2544 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2545 if ( !smSO->_is_nil() &&
2546 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2547 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2549 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2550 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2551 if ( !geom->_non_existent() )
2554 continue; // keep the sub-mesh
2557 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2558 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2559 if ( !sm->_is_nil() && !sm->_non_existent() )
2561 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2562 if ( smGeom->_is_nil() )
2564 RemoveSubMesh( sm );
2571 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2572 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2576 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2577 builder->RemoveObjectWithChildren( rootSO );
2581 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2582 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2583 while ( i_gr != _mapGroups.end())
2585 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2587 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2588 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2589 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2590 bool isValidGeom = false;
2591 if ( !onGeom->_is_nil() )
2593 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2595 else if ( !onFilt->_is_nil() )
2597 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2601 isValidGeom = ( !groupSO->_is_nil() &&
2602 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2606 if ( !IsLoaded() || group->IsEmpty() )
2608 RemoveGroup( group );
2610 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2612 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2614 else // is it possible?
2616 builder->RemoveObjectWithChildren( refSO );
2622 if ( !_impl->HasShapeToMesh() ) return;
2624 CORBA::Long nbEntities = NbNodes() + NbElements();
2626 // Check if group contents changed
2628 typedef map< string, TopoDS_Shape > TEntry2Geom;
2629 TEntry2Geom newGroupContents;
2631 list<TGeomGroupData>::iterator
2632 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2633 for ( ; data != dataEnd; ++data )
2635 pair< TEntry2Geom::iterator, bool > it_new =
2636 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2637 bool processedGroup = !it_new.second;
2638 TopoDS_Shape& newShape = it_new.first->second;
2639 if ( !processedGroup )
2640 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2641 if ( newShape.IsNull() )
2642 continue; // no changes
2645 _preMeshInfo->ForgetOrLoad();
2647 if ( processedGroup ) { // update group indices
2648 list<TGeomGroupData>::iterator data2 = data;
2649 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2650 data->_indices = data2->_indices;
2653 // Update SMESH objects according to new GEOM group contents
2655 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2656 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2658 int oldID = submesh->GetId();
2659 if ( !_mapSubMeshIor.count( oldID ))
2661 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2663 // update hypotheses
2664 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2665 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2666 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2668 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2669 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2671 // care of submeshes
2672 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2673 int newID = newSubmesh->GetId();
2674 if ( newID != oldID ) {
2675 _mapSubMesh [ newID ] = newSubmesh;
2676 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2677 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2678 _mapSubMesh. erase(oldID);
2679 _mapSubMesh_i. erase(oldID);
2680 _mapSubMeshIor.erase(oldID);
2681 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2686 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2687 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2688 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2690 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2692 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2693 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2694 ds->SetShape( newShape );
2699 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2700 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2702 // Remove groups and submeshes basing on removed sub-shapes
2704 TopTools_MapOfShape newShapeMap;
2705 TopoDS_Iterator shapeIt( newShape );
2706 for ( ; shapeIt.More(); shapeIt.Next() )
2707 newShapeMap.Add( shapeIt.Value() );
2709 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2710 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2712 if ( newShapeMap.Contains( shapeIt.Value() ))
2714 TopTools_IndexedMapOfShape oldShapeMap;
2715 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2716 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2718 const TopoDS_Shape& oldShape = oldShapeMap(i);
2719 int oldInd = meshDS->ShapeToIndex( oldShape );
2721 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2722 if ( i_smIor != _mapSubMeshIor.end() ) {
2723 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2726 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2727 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2729 // check if a group bases on oldInd shape
2730 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2731 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2732 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2733 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2735 RemoveGroup( i_grp->second ); // several groups can base on same shape
2736 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2741 // Reassign hypotheses and update groups after setting the new shape to mesh
2743 // collect anassigned hypotheses
2744 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2745 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2746 TShapeHypList assignedHyps;
2747 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2749 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2750 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2751 if ( !hyps.empty() ) {
2752 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2753 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2754 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2757 // collect shapes supporting groups
2758 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2759 TShapeTypeList groupData;
2760 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2761 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2762 for ( ; grIt != groups.end(); ++grIt )
2764 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2766 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2768 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2770 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2771 _impl->ShapeToMesh( newShape );
2773 // reassign hypotheses
2774 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2775 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2777 TIndexedShape& geom = indS_hyps->first;
2778 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2779 int oldID = geom._index;
2780 int newID = meshDS->ShapeToIndex( geom._shape );
2781 if ( oldID == 1 ) { // main shape
2783 geom._shape = newShape;
2787 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2788 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2789 // care of sub-meshes
2790 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2791 if ( newID != oldID ) {
2792 _mapSubMesh [ newID ] = newSubmesh;
2793 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2794 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2795 _mapSubMesh. erase(oldID);
2796 _mapSubMesh_i. erase(oldID);
2797 _mapSubMeshIor.erase(oldID);
2798 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2802 TShapeTypeList::iterator geomType = groupData.begin();
2803 for ( ; geomType != groupData.end(); ++geomType )
2805 const TIndexedShape& geom = geomType->first;
2806 int oldID = geom._index;
2807 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2810 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2811 CORBA::String_var name = groupSO->GetName();
2813 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2814 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2815 /*id=*/-1, geom._shape ))
2816 group_i->changeLocalId( group->GetID() );
2819 break; // everything has been updated
2822 } // loop on group data
2826 CORBA::Long newNbEntities = NbNodes() + NbElements();
2827 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2828 if ( newNbEntities != nbEntities )
2830 // Add all SObjects with icons to soToUpdateIcons
2831 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2833 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2834 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2835 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2837 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2838 i_gr != _mapGroups.end(); ++i_gr ) // groups
2839 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2842 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2843 for ( ; so != soToUpdateIcons.end(); ++so )
2844 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2847 //=============================================================================
2849 * \brief Create standalone group from a group on geometry or filter
2851 //=============================================================================
2853 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2854 throw (SALOME::SALOME_Exception)
2856 SMESH::SMESH_Group_var aGroup;
2861 _preMeshInfo->FullLoadFromFile();
2863 if ( theGroup->_is_nil() )
2864 return aGroup._retn();
2866 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2868 return aGroup._retn();
2870 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2872 const int anId = aGroupToRem->GetLocalID();
2873 if ( !_impl->ConvertToStandalone( anId ) )
2874 return aGroup._retn();
2875 removeGeomGroupData( theGroup );
2877 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2879 // remove old instance of group from own map
2880 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2881 _mapGroups.erase( anId );
2883 SALOMEDS::StudyBuilder_var builder;
2884 SALOMEDS::SObject_wrap aGroupSO;
2885 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2886 if ( !aStudy->_is_nil() ) {
2887 builder = aStudy->NewBuilder();
2888 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2889 if ( !aGroupSO->_is_nil() )
2891 // remove reference to geometry
2892 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2893 for ( ; chItr->More(); chItr->Next() )
2895 // Remove group's child SObject
2896 SALOMEDS::SObject_wrap so = chItr->Value();
2897 builder->RemoveObject( so );
2899 // Update Python script
2900 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2901 << ".ConvertToStandalone( " << aGroupSO << " )";
2903 // change icon of Group on Filter
2906 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2907 // const int isEmpty = ( elemTypes->length() == 0 );
2910 SALOMEDS::GenericAttribute_wrap anAttr =
2911 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2912 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2913 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2919 // remember new group in own map
2920 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2921 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2923 // register CORBA object for persistence
2924 _gen_i->RegisterObject( aGroup );
2926 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2927 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2928 //aGroup->Register();
2929 aGroupToRem->UnRegister();
2931 SMESH_CATCH( SMESH::throwCorbaException );
2933 return aGroup._retn();
2936 //=============================================================================
2940 //=============================================================================
2942 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2944 if(MYDEBUG) MESSAGE( "createSubMesh" );
2945 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2946 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2949 SMESH_subMesh_i * subMeshServant;
2952 subMeshId = mySubMesh->GetId();
2953 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2955 else // "invalid sub-mesh"
2957 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2958 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2959 if ( _mapSubMesh.empty() )
2962 subMeshId = _mapSubMesh.begin()->first - 1;
2963 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2966 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2968 _mapSubMesh [subMeshId] = mySubMesh;
2969 _mapSubMesh_i [subMeshId] = subMeshServant;
2970 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2972 subMeshServant->Register();
2974 // register CORBA object for persistence
2975 int nextId = _gen_i->RegisterObject( subMesh );
2976 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2977 else { nextId = 0; } // avoid "unused variable" warning
2979 // to track changes of GEOM groups
2980 if ( subMeshId > 0 )
2981 addGeomGroupData( theSubShapeObject, subMesh );
2983 return subMesh._retn();
2986 //=======================================================================
2987 //function : getSubMesh
2989 //=======================================================================
2991 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2993 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2994 if ( it == _mapSubMeshIor.end() )
2995 return SMESH::SMESH_subMesh::_nil();
2997 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3000 //=============================================================================
3004 //=============================================================================
3006 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3007 GEOM::GEOM_Object_ptr theSubShapeObject )
3009 bool isHypChanged = false;
3010 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3011 return isHypChanged;
3013 const int subMeshId = theSubMesh->GetId();
3015 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3018 if (( _mapSubMesh.count( subMeshId )) &&
3019 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3021 TopoDS_Shape S = sm->GetSubShape();
3024 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3025 isHypChanged = !hyps.empty();
3026 if ( isHypChanged && _preMeshInfo )
3027 _preMeshInfo->ForgetOrLoad();
3028 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3029 for ( ; hyp != hyps.end(); ++hyp )
3030 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3037 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3038 isHypChanged = ( aHypList->length() > 0 );
3039 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3040 removeHypothesis( theSubShapeObject, aHypList[i] );
3043 catch( const SALOME::SALOME_Exception& ) {
3044 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3046 removeGeomGroupData( theSubShapeObject );
3050 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3051 if ( id_smi != _mapSubMesh_i.end() )
3052 id_smi->second->UnRegister();
3054 // remove a CORBA object
3055 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3056 if ( id_smptr != _mapSubMeshIor.end() )
3057 SMESH::SMESH_subMesh_var( id_smptr->second );
3059 _mapSubMesh.erase(subMeshId);
3060 _mapSubMesh_i.erase(subMeshId);
3061 _mapSubMeshIor.erase(subMeshId);
3063 return isHypChanged;
3066 //=============================================================================
3070 //=============================================================================
3072 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3073 const char* theName,
3075 const TopoDS_Shape& theShape,
3076 const SMESH_PredicatePtr& thePredicate )
3078 std::string newName;
3079 if ( !theName || !theName[0] )
3081 std::set< std::string > presentNames;
3082 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3083 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3085 CORBA::String_var name = i_gr->second->GetName();
3086 presentNames.insert( name.in() );
3089 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3090 } while ( !presentNames.insert( newName ).second );
3091 theName = newName.c_str();
3093 SMESH::SMESH_GroupBase_var aGroup;
3094 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3095 theID, theShape, thePredicate ))
3097 int anId = g->GetID();
3098 SMESH_GroupBase_i* aGroupImpl;
3099 if ( !theShape.IsNull() )
3100 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3101 else if ( thePredicate )
3102 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3104 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3106 aGroup = aGroupImpl->_this();
3107 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3108 aGroupImpl->Register();
3110 // register CORBA object for persistence
3111 int nextId = _gen_i->RegisterObject( aGroup );
3112 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3113 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3115 // to track changes of GEOM groups
3116 if ( !theShape.IsNull() ) {
3117 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3118 addGeomGroupData( geom, aGroup );
3121 return aGroup._retn();
3124 //=============================================================================
3126 * SMESH_Mesh_i::removeGroup
3128 * Should be called by ~SMESH_Group_i()
3130 //=============================================================================
3132 void SMESH_Mesh_i::removeGroup( const int theId )
3134 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3135 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3136 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3137 _mapGroups.erase( theId );
3138 removeGeomGroupData( group );
3139 if ( !_impl->RemoveGroup( theId ))
3141 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3142 RemoveGroup( group );
3144 group->UnRegister();
3148 //=============================================================================
3152 //=============================================================================
3154 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3155 throw(SALOME::SALOME_Exception)
3157 SMESH::log_array_var aLog;
3161 _preMeshInfo->FullLoadFromFile();
3163 list < SMESHDS_Command * >logDS = _impl->GetLog();
3164 aLog = new SMESH::log_array;
3166 int lg = logDS.size();
3169 list < SMESHDS_Command * >::iterator its = logDS.begin();
3170 while(its != logDS.end()){
3171 SMESHDS_Command *com = *its;
3172 int comType = com->GetType();
3174 int lgcom = com->GetNumber();
3176 const list < int >&intList = com->GetIndexes();
3177 int inum = intList.size();
3179 list < int >::const_iterator ii = intList.begin();
3180 const list < double >&coordList = com->GetCoords();
3181 int rnum = coordList.size();
3183 list < double >::const_iterator ir = coordList.begin();
3184 aLog[indexLog].commandType = comType;
3185 aLog[indexLog].number = lgcom;
3186 aLog[indexLog].coords.length(rnum);
3187 aLog[indexLog].indexes.length(inum);
3188 for(int i = 0; i < rnum; i++){
3189 aLog[indexLog].coords[i] = *ir;
3190 //MESSAGE(" "<<i<<" "<<ir.Value());
3193 for(int i = 0; i < inum; i++){
3194 aLog[indexLog].indexes[i] = *ii;
3195 //MESSAGE(" "<<i<<" "<<ii.Value());
3204 SMESH_CATCH( SMESH::throwCorbaException );
3206 return aLog._retn();
3210 //=============================================================================
3214 //=============================================================================
3216 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3220 SMESH_CATCH( SMESH::throwCorbaException );
3223 //=============================================================================
3227 //=============================================================================
3229 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3234 //=============================================================================
3237 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3238 // issue 0020918: groups removal is caused by hyp modification
3239 // issue 0021208: to forget not loaded mesh data at hyp modification
3240 struct TCallUp_i : public SMESH_Mesh::TCallUp
3242 SMESH_Mesh_i* _mesh;
3243 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3244 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3245 virtual void HypothesisModified( int hypID,
3246 bool updIcons) { _mesh->onHypothesisModified( hypID,
3248 virtual void Load () { _mesh->Load(); }
3249 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3253 //================================================================================
3255 * \brief callback from _impl to
3256 * 1) forget not loaded mesh data (issue 0021208)
3257 * 2) mark hypothesis as valid
3259 //================================================================================
3261 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3264 _preMeshInfo->ForgetOrLoad();
3266 if ( theUpdateIcons )
3268 SMESH::SMESH_Mesh_var mesh = _this();
3269 _gen_i->UpdateIcons( mesh );
3272 if ( _nbInvalidHypos != 0 )
3274 // mark a hypothesis as valid after edition
3276 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3277 SALOMEDS::SObject_wrap hypRoot;
3278 if ( !smeshComp->_is_nil() &&
3279 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3281 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3282 for ( ; anIter->More(); anIter->Next() )
3284 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3285 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3286 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3287 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3288 _gen_i->HighLightInvalid( hyp, false );
3290 nbInvalid += _gen_i->IsInvalid( hypSO );
3293 _nbInvalidHypos = nbInvalid;
3297 //=============================================================================
3301 //=============================================================================
3303 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3305 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3308 _impl->SetCallUp( new TCallUp_i(this));
3311 //=============================================================================
3315 //=============================================================================
3317 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3319 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3323 //=============================================================================
3325 * Return mesh editor
3327 //=============================================================================
3329 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3330 throw (SALOME::SALOME_Exception)
3332 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3336 _preMeshInfo->FullLoadFromFile();
3338 // Create MeshEditor
3340 _editor = new SMESH_MeshEditor_i( this, false );
3341 aMeshEdVar = _editor->_this();
3343 // Update Python script
3344 TPythonDump() << _editor << " = "
3345 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3347 SMESH_CATCH( SMESH::throwCorbaException );
3349 return aMeshEdVar._retn();
3352 //=============================================================================
3354 * Return mesh edition previewer
3356 //=============================================================================
3358 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3359 throw (SALOME::SALOME_Exception)
3361 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3365 _preMeshInfo->FullLoadFromFile();
3367 if ( !_previewEditor )
3368 _previewEditor = new SMESH_MeshEditor_i( this, true );
3369 aMeshEdVar = _previewEditor->_this();
3371 SMESH_CATCH( SMESH::throwCorbaException );
3373 return aMeshEdVar._retn();
3376 //================================================================================
3378 * \brief Return true if the mesh has been edited since a last total re-compute
3379 * and those modifications may prevent successful partial re-compute
3381 //================================================================================
3383 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3385 Unexpect aCatch(SALOME_SalomeException);
3386 return _impl->HasModificationsToDiscard();
3389 //================================================================================
3391 * \brief Returns a random unique color
3393 //================================================================================
3395 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3397 const int MAX_ATTEMPTS = 100;
3399 double tolerance = 0.5;
3400 SALOMEDS::Color col;
3404 // generate random color
3405 double red = (double)rand() / RAND_MAX;
3406 double green = (double)rand() / RAND_MAX;
3407 double blue = (double)rand() / RAND_MAX;
3408 // check existence in the list of the existing colors
3409 bool matched = false;
3410 std::list<SALOMEDS::Color>::const_iterator it;
3411 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3412 SALOMEDS::Color color = *it;
3413 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3414 matched = tol < tolerance;
3416 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3417 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3425 //=============================================================================
3427 * Sets auto-color mode. If it is on, groups get unique random colors
3429 //=============================================================================
3431 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3433 Unexpect aCatch(SALOME_SalomeException);
3434 _impl->SetAutoColor(theAutoColor);
3436 TPythonDump pyDump; // not to dump group->SetColor() from below code
3437 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3439 std::list<SALOMEDS::Color> aReservedColors;
3440 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3441 for ( ; it != _mapGroups.end(); it++ ) {
3442 if ( CORBA::is_nil( it->second )) continue;
3443 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3444 it->second->SetColor( aColor );
3445 aReservedColors.push_back( aColor );
3449 //=============================================================================
3451 * Returns true if auto-color mode is on
3453 //=============================================================================
3455 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3457 Unexpect aCatch(SALOME_SalomeException);
3458 return _impl->GetAutoColor();
3461 //=============================================================================
3463 * Checks if there are groups with equal names
3465 //=============================================================================
3467 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3469 return _impl->HasDuplicatedGroupNamesMED();
3472 //================================================================================
3474 * \brief Care of a file before exporting mesh into it
3476 //================================================================================
3478 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3480 SMESH_File aFile( file, false );
3482 if ( aFile.exists() ) {
3483 // existing filesystem node
3484 if ( !aFile.isDirectory() ) {
3485 if ( aFile.openForWriting() ) {
3486 if ( overwrite && ! aFile.remove()) {
3487 msg << "Can't replace " << aFile.getName();
3490 msg << "Can't write into " << aFile.getName();
3493 msg << "Location " << aFile.getName() << " is not a file";
3497 // nonexisting file; check if it can be created
3498 if ( !aFile.openForWriting() ) {
3499 msg << "You cannot create the file "
3501 << ". Check the directory existence and access rights";
3509 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3513 //================================================================================
3515 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3516 * \param file - file name
3517 * \param overwrite - to erase the file or not
3518 * \retval string - mesh name
3520 //================================================================================
3522 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3523 CORBA::Boolean overwrite)
3526 PrepareForWriting(file, overwrite);
3527 string aMeshName = "Mesh";
3528 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3529 if ( !aStudy->_is_nil() ) {
3530 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3531 if ( !aMeshSO->_is_nil() ) {
3532 CORBA::String_var name = aMeshSO->GetName();
3534 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3535 if ( !aStudy->GetProperties()->IsLocked() )
3537 SALOMEDS::GenericAttribute_wrap anAttr;
3538 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3539 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3540 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3541 ASSERT(!aFileName->_is_nil());
3542 aFileName->SetValue(file);
3543 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3544 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3545 ASSERT(!aFileType->_is_nil());
3546 aFileType->SetValue("FICHIERMED");
3550 // Update Python script
3551 // set name of mesh before export
3552 TPythonDump() << _gen_i << ".SetName("
3553 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3555 // check names of groups
3561 //================================================================================
3563 * \brief Export to MED file
3565 //================================================================================
3567 void SMESH_Mesh_i::ExportMED(const char* file,
3568 CORBA::Boolean auto_groups,
3569 CORBA::Long version,
3570 CORBA::Boolean overwrite,
3571 CORBA::Boolean autoDimension)
3572 throw(SALOME::SALOME_Exception)
3574 //MESSAGE("MED minor version: "<< minor);
3577 _preMeshInfo->FullLoadFromFile();
3579 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3580 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3582 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3584 << "auto_groups=" <<auto_groups << ", "
3585 << "minor=" << version << ", "
3586 << "overwrite=" << overwrite << ", "
3587 << "meshPart=None, "
3588 << "autoDimension=" << autoDimension << " )";
3590 SMESH_CATCH( SMESH::throwCorbaException );
3593 //================================================================================
3595 * \brief Export a mesh to a SAUV file
3597 //================================================================================
3599 void SMESH_Mesh_i::ExportSAUV (const char* file,
3600 CORBA::Boolean auto_groups)
3601 throw(SALOME::SALOME_Exception)
3603 Unexpect aCatch(SALOME_SalomeException);
3605 _preMeshInfo->FullLoadFromFile();
3607 string aMeshName = prepareMeshNameAndGroups(file, true);
3608 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3609 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3610 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3614 //================================================================================
3616 * \brief Export a mesh to a DAT file
3618 //================================================================================
3620 void SMESH_Mesh_i::ExportDAT (const char *file)
3621 throw(SALOME::SALOME_Exception)
3623 Unexpect aCatch(SALOME_SalomeException);
3625 _preMeshInfo->FullLoadFromFile();
3627 // Update Python script
3628 // check names of groups
3630 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3633 PrepareForWriting(file);
3634 _impl->ExportDAT(file);
3637 //================================================================================
3639 * \brief Export a mesh to an UNV file
3641 //================================================================================
3643 void SMESH_Mesh_i::ExportUNV (const char *file)
3644 throw(SALOME::SALOME_Exception)
3646 Unexpect aCatch(SALOME_SalomeException);
3648 _preMeshInfo->FullLoadFromFile();
3650 // Update Python script
3651 // check names of groups
3653 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3656 PrepareForWriting(file);
3657 _impl->ExportUNV(file);
3660 //================================================================================
3662 * \brief Export a mesh to an STL file
3664 //================================================================================
3666 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3667 throw(SALOME::SALOME_Exception)
3669 Unexpect aCatch(SALOME_SalomeException);
3671 _preMeshInfo->FullLoadFromFile();
3673 // Update Python script
3674 // check names of groups
3676 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3677 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3679 CORBA::String_var name;
3680 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3681 if ( !so->_is_nil() )
3682 name = so->GetName();
3685 PrepareForWriting( file );
3686 _impl->ExportSTL( file, isascii, name.in() );
3689 //================================================================================
3691 * \brief Export a part of mesh to a med file
3693 //================================================================================
3695 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3697 CORBA::Boolean auto_groups,
3698 CORBA::Long version,
3699 CORBA::Boolean overwrite,
3700 CORBA::Boolean autoDimension,
3701 const GEOM::ListOfFields& fields,
3702 const char* geomAssocFields,
3703 CORBA::Double ZTolerance)
3704 throw (SALOME::SALOME_Exception)
3706 MESSAGE("MED version: "<< version);
3709 _preMeshInfo->FullLoadFromFile();
3712 bool have0dField = false;
3713 if ( fields.length() > 0 )
3715 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3716 if ( shapeToMesh->_is_nil() )
3717 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3719 for ( size_t i = 0; i < fields.length(); ++i )
3721 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3722 THROW_SALOME_CORBA_EXCEPTION
3723 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3724 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3725 if ( fieldShape->_is_nil() )
3726 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3727 if ( !fieldShape->IsSame( shapeToMesh ) )
3728 THROW_SALOME_CORBA_EXCEPTION
3729 ( "Field defined not on shape", SALOME::BAD_PARAM);
3730 if ( fields[i]->GetDimension() == 0 )
3733 if ( geomAssocFields )
3734 for ( int i = 0; geomAssocFields[i]; ++i )
3735 switch ( geomAssocFields[i] ) {
3736 case 'v':case 'e':case 'f':case 's': break;
3737 case 'V':case 'E':case 'F':case 'S': break;
3738 default: THROW_SALOME_CORBA_EXCEPTION
3739 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3743 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3747 string aMeshName = "Mesh";
3748 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3749 if ( CORBA::is_nil( meshPart ) ||
3750 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3752 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3753 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3754 0, autoDimension, /*addODOnVertices=*/have0dField,
3756 meshDS = _impl->GetMeshDS();
3761 _preMeshInfo->FullLoadFromFile();
3763 PrepareForWriting(file, overwrite);
3765 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3766 if ( !SO->_is_nil() ) {
3767 CORBA::String_var name = SO->GetName();
3771 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3772 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3773 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3774 meshDS = tmpDSDeleter._obj = partDS;
3779 if ( _impl->HasShapeToMesh() )
3781 DriverMED_W_Field fieldWriter;
3782 fieldWriter.SetFile( file );
3783 fieldWriter.SetMeshName( aMeshName );
3784 fieldWriter.AddODOnVertices( have0dField );
3786 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3790 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3791 goList->length( fields.length() );
3792 for ( size_t i = 0; i < fields.length(); ++i )
3794 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3797 TPythonDump() << _this() << ".ExportPartToMED( "
3798 << meshPart << ", r'"
3800 << auto_groups << ", "
3802 << overwrite << ", "
3803 << autoDimension << ", "
3805 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3806 << TVar( ZTolerance )
3809 SMESH_CATCH( SMESH::throwCorbaException );
3812 //================================================================================
3814 * Write GEOM fields to MED file
3816 //================================================================================
3818 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3819 SMESHDS_Mesh* meshDS,
3820 const GEOM::ListOfFields& fields,
3821 const char* geomAssocFields)
3823 #define METH "SMESH_Mesh_i::exportMEDFields() "
3825 if (( fields.length() < 1 ) &&
3826 ( !geomAssocFields || !geomAssocFields[0] ))
3829 std::vector< std::vector< double > > dblVals;
3830 std::vector< std::vector< int > > intVals;
3831 std::vector< int > subIdsByDim[ 4 ];
3832 const double noneDblValue = 0.;
3833 const double noneIntValue = 0;
3835 for ( size_t iF = 0; iF < fields.length(); ++iF )
3839 int dim = fields[ iF ]->GetDimension();
3840 SMDSAbs_ElementType elemType;
3841 TopAbs_ShapeEnum shapeType;
3843 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3844 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3845 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3846 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3848 continue; // skip fields on whole shape
3850 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3851 if ( dataType == GEOM::FDT_String )
3853 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3854 if ( stepIDs->length() < 1 )
3856 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3857 if ( comps->length() < 1 )
3859 CORBA::String_var name = fields[ iF ]->GetName();
3861 if ( !fieldWriter.Set( meshDS,
3865 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3868 for ( size_t iC = 0; iC < comps->length(); ++iC )
3869 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3871 dblVals.resize( comps->length() );
3872 intVals.resize( comps->length() );
3874 // find sub-shape IDs
3876 std::vector< int >& subIds = subIdsByDim[ dim ];
3877 if ( subIds.empty() )
3878 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3879 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3880 subIds.push_back( id );
3884 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3888 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3890 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3891 if ( step->_is_nil() )
3894 CORBA::Long stamp = step->GetStamp();
3895 CORBA::Long id = step->GetID();
3896 fieldWriter.SetDtIt( int( stamp ), int( id ));
3898 // fill dblVals or intVals
3899 for ( size_t iC = 0; iC < comps->length(); ++iC )
3900 if ( dataType == GEOM::FDT_Double )
3902 dblVals[ iC ].clear();
3903 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3907 intVals[ iC ].clear();
3908 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3912 case GEOM::FDT_Double:
3914 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3915 if ( dblStep->_is_nil() ) continue;
3916 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3917 if ( vv->length() != subIds.size() * comps->length() )
3918 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3919 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3920 for ( size_t iC = 0; iC < comps->length(); ++iC )
3921 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3926 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3927 if ( intStep->_is_nil() ) continue;
3928 GEOM::ListOfLong_var vv = intStep->GetValues();
3929 if ( vv->length() != subIds.size() * comps->length() )
3930 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3931 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3932 for ( size_t iC = 0; iC < comps->length(); ++iC )
3933 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3936 case GEOM::FDT_Bool:
3938 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3939 if ( boolStep->_is_nil() ) continue;
3940 GEOM::short_array_var vv = boolStep->GetValues();
3941 if ( vv->length() != subIds.size() * comps->length() )
3942 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3943 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3944 for ( size_t iC = 0; iC < comps->length(); ++iC )
3945 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3951 // pass values to fieldWriter
3952 elemIt = fieldWriter.GetOrderedElems();
3953 if ( dataType == GEOM::FDT_Double )
3954 while ( elemIt->more() )
3956 const SMDS_MeshElement* e = elemIt->next();
3957 const int shapeID = e->getshapeId();
3958 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3959 for ( size_t iC = 0; iC < comps->length(); ++iC )
3960 fieldWriter.AddValue( noneDblValue );
3962 for ( size_t iC = 0; iC < comps->length(); ++iC )
3963 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3966 while ( elemIt->more() )
3968 const SMDS_MeshElement* e = elemIt->next();
3969 const int shapeID = e->getshapeId();
3970 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3971 for ( size_t iC = 0; iC < comps->length(); ++iC )
3972 fieldWriter.AddValue( (double) noneIntValue );
3974 for ( size_t iC = 0; iC < comps->length(); ++iC )
3975 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3979 fieldWriter.Perform();
3980 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3981 if ( res && res->IsKO() )
3983 if ( res->myComment.empty() )
3984 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3986 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3992 if ( !geomAssocFields || !geomAssocFields[0] )
3995 // write geomAssocFields
3997 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3998 shapeDim[ TopAbs_COMPOUND ] = 3;
3999 shapeDim[ TopAbs_COMPSOLID ] = 3;
4000 shapeDim[ TopAbs_SOLID ] = 3;
4001 shapeDim[ TopAbs_SHELL ] = 2;
4002 shapeDim[ TopAbs_FACE ] = 2;
4003 shapeDim[ TopAbs_WIRE ] = 1;
4004 shapeDim[ TopAbs_EDGE ] = 1;
4005 shapeDim[ TopAbs_VERTEX ] = 0;
4006 shapeDim[ TopAbs_SHAPE ] = 3;
4008 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4010 std::vector< std::string > compNames;
4011 switch ( geomAssocFields[ iF ]) {
4013 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4014 compNames.push_back( "dim" );
4017 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4020 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4023 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4027 compNames.push_back( "id" );
4028 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4029 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4031 fieldWriter.SetDtIt( -1, -1 );
4033 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4037 if ( compNames.size() == 2 ) // _vertices_
4038 while ( elemIt->more() )
4040 const SMDS_MeshElement* e = elemIt->next();
4041 const int shapeID = e->getshapeId();
4044 fieldWriter.AddValue( (double) -1 );
4045 fieldWriter.AddValue( (double) -1 );
4049 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4050 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4051 fieldWriter.AddValue( (double) shapeID );
4055 while ( elemIt->more() )
4057 const SMDS_MeshElement* e = elemIt->next();
4058 const int shapeID = e->getshapeId();
4060 fieldWriter.AddValue( (double) -1 );
4062 fieldWriter.AddValue( (double) shapeID );
4066 fieldWriter.Perform();
4067 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4068 if ( res && res->IsKO() )
4070 if ( res->myComment.empty() )
4071 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4073 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4076 } // loop on geomAssocFields
4081 //================================================================================
4083 * \brief Export a part of mesh to a DAT file
4085 //================================================================================
4087 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4089 throw (SALOME::SALOME_Exception)
4091 Unexpect aCatch(SALOME_SalomeException);
4093 _preMeshInfo->FullLoadFromFile();
4095 PrepareForWriting(file);
4097 SMESH_MeshPartDS partDS( meshPart );
4098 _impl->ExportDAT(file,&partDS);
4100 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4101 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4103 //================================================================================
4105 * \brief Export a part of mesh to an UNV file
4107 //================================================================================
4109 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4111 throw (SALOME::SALOME_Exception)
4113 Unexpect aCatch(SALOME_SalomeException);
4115 _preMeshInfo->FullLoadFromFile();
4117 PrepareForWriting(file);
4119 SMESH_MeshPartDS partDS( meshPart );
4120 _impl->ExportUNV(file, &partDS);
4122 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4123 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4125 //================================================================================
4127 * \brief Export a part of mesh to an STL file
4129 //================================================================================
4131 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4133 ::CORBA::Boolean isascii)
4134 throw (SALOME::SALOME_Exception)
4136 Unexpect aCatch(SALOME_SalomeException);
4138 _preMeshInfo->FullLoadFromFile();
4140 PrepareForWriting(file);
4142 CORBA::String_var name;
4143 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4144 if ( !so->_is_nil() )
4145 name = so->GetName();
4147 SMESH_MeshPartDS partDS( meshPart );
4148 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4150 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4151 << meshPart<< ", r'" << file << "', " << isascii << ")";
4154 //================================================================================
4156 * \brief Export a part of mesh to an STL file
4158 //================================================================================
4160 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4162 CORBA::Boolean overwrite,
4163 CORBA::Boolean groupElemsByType)
4164 throw (SALOME::SALOME_Exception)
4167 Unexpect aCatch(SALOME_SalomeException);
4169 _preMeshInfo->FullLoadFromFile();
4171 PrepareForWriting(file,overwrite);
4173 std::string meshName("");
4174 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4175 if ( !so->_is_nil() )
4177 CORBA::String_var name = so->GetName();
4178 meshName = name.in();
4182 SMESH_MeshPartDS partDS( meshPart );
4183 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4185 SMESH_CATCH( SMESH::throwCorbaException );
4187 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4188 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4190 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4194 //================================================================================
4196 * \brief Export a part of mesh to a GMF file
4198 //================================================================================
4200 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4202 bool withRequiredGroups)
4203 throw (SALOME::SALOME_Exception)
4205 Unexpect aCatch(SALOME_SalomeException);
4207 _preMeshInfo->FullLoadFromFile();
4209 PrepareForWriting(file,/*overwrite=*/true);
4211 SMESH_MeshPartDS partDS( meshPart );
4212 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4214 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4215 << meshPart<< ", r'"
4217 << withRequiredGroups << ")";
4220 //=============================================================================
4222 * Return computation progress [0.,1]
4224 //=============================================================================
4226 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4230 return _impl->GetComputeProgress();
4232 SMESH_CATCH( SMESH::doNothing );
4236 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4238 Unexpect aCatch(SALOME_SalomeException);
4240 return _preMeshInfo->NbNodes();
4242 return _impl->NbNodes();
4245 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4247 Unexpect aCatch(SALOME_SalomeException);
4249 return _preMeshInfo->NbElements();
4251 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4254 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4256 Unexpect aCatch(SALOME_SalomeException);
4258 return _preMeshInfo->Nb0DElements();
4260 return _impl->Nb0DElements();
4263 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4265 Unexpect aCatch(SALOME_SalomeException);
4267 return _preMeshInfo->NbBalls();
4269 return _impl->NbBalls();
4272 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4274 Unexpect aCatch(SALOME_SalomeException);
4276 return _preMeshInfo->NbEdges();
4278 return _impl->NbEdges();
4281 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4282 throw(SALOME::SALOME_Exception)
4284 Unexpect aCatch(SALOME_SalomeException);
4286 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4288 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4291 //=============================================================================
4293 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4295 Unexpect aCatch(SALOME_SalomeException);
4297 return _preMeshInfo->NbFaces();
4299 return _impl->NbFaces();
4302 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4304 Unexpect aCatch(SALOME_SalomeException);
4306 return _preMeshInfo->NbTriangles();
4308 return _impl->NbTriangles();
4311 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4313 Unexpect aCatch(SALOME_SalomeException);
4315 return _preMeshInfo->NbBiQuadTriangles();
4317 return _impl->NbBiQuadTriangles();
4320 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4322 Unexpect aCatch(SALOME_SalomeException);
4324 return _preMeshInfo->NbQuadrangles();
4326 return _impl->NbQuadrangles();
4329 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4331 Unexpect aCatch(SALOME_SalomeException);
4333 return _preMeshInfo->NbBiQuadQuadrangles();
4335 return _impl->NbBiQuadQuadrangles();
4338 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4340 Unexpect aCatch(SALOME_SalomeException);
4342 return _preMeshInfo->NbPolygons();
4344 return _impl->NbPolygons();
4347 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4349 Unexpect aCatch(SALOME_SalomeException);
4351 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4353 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4356 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4357 throw(SALOME::SALOME_Exception)
4359 Unexpect aCatch(SALOME_SalomeException);
4361 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4363 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4366 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4367 throw(SALOME::SALOME_Exception)
4369 Unexpect aCatch(SALOME_SalomeException);
4371 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4373 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4376 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4377 throw(SALOME::SALOME_Exception)
4379 Unexpect aCatch(SALOME_SalomeException);
4381 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4383 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4386 //=============================================================================
4388 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4390 Unexpect aCatch(SALOME_SalomeException);
4392 return _preMeshInfo->NbVolumes();
4394 return _impl->NbVolumes();
4397 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4399 Unexpect aCatch(SALOME_SalomeException);
4401 return _preMeshInfo->NbTetras();
4403 return _impl->NbTetras();
4406 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4408 Unexpect aCatch(SALOME_SalomeException);
4410 return _preMeshInfo->NbHexas();
4412 return _impl->NbHexas();
4415 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4417 Unexpect aCatch(SALOME_SalomeException);
4419 return _preMeshInfo->NbTriQuadHexas();
4421 return _impl->NbTriQuadraticHexas();
4424 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4426 Unexpect aCatch(SALOME_SalomeException);
4428 return _preMeshInfo->NbPyramids();
4430 return _impl->NbPyramids();
4433 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4435 Unexpect aCatch(SALOME_SalomeException);
4437 return _preMeshInfo->NbPrisms();
4439 return _impl->NbPrisms();
4442 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4444 Unexpect aCatch(SALOME_SalomeException);
4446 return _preMeshInfo->NbHexPrisms();
4448 return _impl->NbHexagonalPrisms();
4451 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4453 Unexpect aCatch(SALOME_SalomeException);
4455 return _preMeshInfo->NbPolyhedrons();
4457 return _impl->NbPolyhedrons();
4460 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4461 throw(SALOME::SALOME_Exception)
4463 Unexpect aCatch(SALOME_SalomeException);
4465 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4467 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4470 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4471 throw(SALOME::SALOME_Exception)
4473 Unexpect aCatch(SALOME_SalomeException);
4475 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4477 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4480 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4481 throw(SALOME::SALOME_Exception)
4483 Unexpect aCatch(SALOME_SalomeException);
4485 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4487 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4490 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4491 throw(SALOME::SALOME_Exception)
4493 Unexpect aCatch(SALOME_SalomeException);
4495 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4497 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4500 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4501 throw(SALOME::SALOME_Exception)
4503 Unexpect aCatch(SALOME_SalomeException);
4505 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4507 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4510 //=============================================================================
4512 * Returns nb of published sub-meshes
4514 //=============================================================================
4516 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4518 Unexpect aCatch(SALOME_SalomeException);
4519 return _mapSubMesh_i.size();
4522 //=============================================================================
4524 * Dumps mesh into a string
4526 //=============================================================================
4528 char* SMESH_Mesh_i::Dump()
4532 return CORBA::string_dup( os.str().c_str() );
4535 //=============================================================================
4537 * Method of SMESH_IDSource interface
4539 //=============================================================================
4541 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4543 return GetElementsId();
4546 //=============================================================================
4548 * Returns ids of all elements
4550 //=============================================================================
4552 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4553 throw (SALOME::SALOME_Exception)
4555 Unexpect aCatch(SALOME_SalomeException);
4557 _preMeshInfo->FullLoadFromFile();
4559 SMESH::long_array_var aResult = new SMESH::long_array();
4560 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4562 if ( aSMESHDS_Mesh == NULL )
4563 return aResult._retn();
4565 long nbElements = NbElements();
4566 aResult->length( nbElements );
4567 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4568 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4569 aResult[i] = anIt->next()->GetID();
4571 return aResult._retn();
4575 //=============================================================================
4577 * Returns ids of all elements of given type
4579 //=============================================================================
4581 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4582 throw (SALOME::SALOME_Exception)
4584 Unexpect aCatch(SALOME_SalomeException);
4586 _preMeshInfo->FullLoadFromFile();
4588 SMESH::long_array_var aResult = new SMESH::long_array();
4589 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4591 if ( aSMESHDS_Mesh == NULL )
4592 return aResult._retn();
4594 long nbElements = NbElements();
4596 // No sense in returning ids of elements along with ids of nodes:
4597 // when theElemType == SMESH::ALL, return node ids only if
4598 // there are no elements
4599 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4600 return GetNodesId();
4602 aResult->length( nbElements );
4606 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4607 while ( i < nbElements && anIt->more() )
4608 aResult[i++] = anIt->next()->GetID();
4610 aResult->length( i );
4612 return aResult._retn();
4615 //=============================================================================
4617 * Returns ids of all nodes
4619 //=============================================================================
4621 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4622 throw (SALOME::SALOME_Exception)
4624 Unexpect aCatch(SALOME_SalomeException);
4626 _preMeshInfo->FullLoadFromFile();
4628 SMESH::long_array_var aResult = new SMESH::long_array();
4629 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4631 if ( aMeshDS == NULL )
4632 return aResult._retn();
4634 long nbNodes = NbNodes();
4635 aResult->length( nbNodes );
4636 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4637 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4638 aResult[i] = anIt->next()->GetID();
4640 return aResult._retn();
4643 //=============================================================================
4647 //=============================================================================
4649 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4650 throw (SALOME::SALOME_Exception)
4652 SMESH::ElementType type = SMESH::ALL;
4656 _preMeshInfo->FullLoadFromFile();
4658 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4660 SMESH_CATCH( SMESH::throwCorbaException );
4665 //=============================================================================
4669 //=============================================================================
4671 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4672 throw (SALOME::SALOME_Exception)
4675 _preMeshInfo->FullLoadFromFile();
4677 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4679 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4681 return ( SMESH::EntityType ) e->GetEntityType();
4684 //=============================================================================
4688 //=============================================================================
4690 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4691 throw (SALOME::SALOME_Exception)
4694 _preMeshInfo->FullLoadFromFile();
4696 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4698 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4700 return ( SMESH::GeometryType ) e->GetGeomType();
4703 //=============================================================================
4705 * Returns ID of elements for given submesh
4707 //=============================================================================
4708 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4709 throw (SALOME::SALOME_Exception)
4711 SMESH::long_array_var aResult = new SMESH::long_array();
4715 _preMeshInfo->FullLoadFromFile();
4717 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4718 if(!SM) return aResult._retn();
4720 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4721 if(!SDSM) return aResult._retn();
4723 aResult->length(SDSM->NbElements());
4725 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4727 while ( eIt->more() ) {
4728 aResult[i++] = eIt->next()->GetID();
4731 SMESH_CATCH( SMESH::throwCorbaException );
4733 return aResult._retn();
4736 //=============================================================================
4738 * Returns ID of nodes for given submesh
4739 * If param all==true - returns all nodes, else -
4740 * returns only nodes on shapes.
4742 //=============================================================================
4744 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4746 throw (SALOME::SALOME_Exception)
4748 SMESH::long_array_var aResult = new SMESH::long_array();
4752 _preMeshInfo->FullLoadFromFile();
4754 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4755 if(!SM) return aResult._retn();
4757 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4758 if(!SDSM) return aResult._retn();
4761 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4762 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4763 while ( nIt->more() ) {
4764 const SMDS_MeshNode* elem = nIt->next();
4765 theElems.insert( elem->GetID() );
4768 else { // all nodes of submesh elements
4769 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4770 while ( eIt->more() ) {
4771 const SMDS_MeshElement* anElem = eIt->next();
4772 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4773 while ( nIt->more() ) {
4774 const SMDS_MeshElement* elem = nIt->next();
4775 theElems.insert( elem->GetID() );
4780 aResult->length(theElems.size());
4781 set<int>::iterator itElem;
4783 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4784 aResult[i++] = *itElem;
4786 SMESH_CATCH( SMESH::throwCorbaException );
4788 return aResult._retn();
4791 //=============================================================================
4793 * Returns type of elements for given submesh
4795 //=============================================================================
4797 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4798 throw (SALOME::SALOME_Exception)
4800 SMESH::ElementType type = SMESH::ALL;
4804 _preMeshInfo->FullLoadFromFile();
4806 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4807 if(!SM) return SMESH::ALL;
4809 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4810 if(!SDSM) return SMESH::ALL;
4812 if(SDSM->NbElements()==0)
4813 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4815 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4816 const SMDS_MeshElement* anElem = eIt->next();
4818 type = ( SMESH::ElementType ) anElem->GetType();
4820 SMESH_CATCH( SMESH::throwCorbaException );
4826 //=============================================================================
4828 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4830 //=============================================================================
4832 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4835 _preMeshInfo->FullLoadFromFile();
4837 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4838 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4843 //=============================================================================
4845 * Get XYZ coordinates of node as list of double
4846 * If there is not node for given ID - returns empty list
4848 //=============================================================================
4850 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4853 _preMeshInfo->FullLoadFromFile();
4855 SMESH::double_array_var aResult = new SMESH::double_array();
4856 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4857 if ( aMeshDS == NULL )
4858 return aResult._retn();
4861 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4863 return aResult._retn();
4867 aResult[0] = aNode->X();
4868 aResult[1] = aNode->Y();
4869 aResult[2] = aNode->Z();
4870 return aResult._retn();
4874 //=============================================================================
4876 * For given node returns list of IDs of inverse elements
4877 * If there is not node for given ID - returns empty list
4879 //=============================================================================
4881 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4882 SMESH::ElementType elemType)
4885 _preMeshInfo->FullLoadFromFile();
4887 SMESH::long_array_var aResult = new SMESH::long_array();
4888 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4889 if ( aMeshDS == NULL )
4890 return aResult._retn();
4893 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4895 return aResult._retn();
4897 // find inverse elements
4898 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4899 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4900 aResult->length( aNode->NbInverseElements( type ));
4901 for( int i = 0; eIt->more(); ++i )
4903 const SMDS_MeshElement* elem = eIt->next();
4904 aResult[ i ] = elem->GetID();
4906 return aResult._retn();
4909 //=============================================================================
4911 * \brief Return position of a node on shape
4913 //=============================================================================
4915 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4918 _preMeshInfo->FullLoadFromFile();
4920 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4921 aNodePosition->shapeID = 0;
4922 aNodePosition->shapeType = GEOM::SHAPE;
4924 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4925 if ( !mesh ) return aNodePosition;
4927 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4929 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4931 aNodePosition->shapeID = aNode->getshapeId();
4932 switch ( pos->GetTypeOfPosition() ) {
4934 aNodePosition->shapeType = GEOM::EDGE;
4935 aNodePosition->params.length(1);
4936 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4938 case SMDS_TOP_FACE: {
4939 SMDS_FacePositionPtr fPos = pos;
4940 aNodePosition->shapeType = GEOM::FACE;
4941 aNodePosition->params.length(2);
4942 aNodePosition->params[0] = fPos->GetUParameter();
4943 aNodePosition->params[1] = fPos->GetVParameter();
4946 case SMDS_TOP_VERTEX:
4947 aNodePosition->shapeType = GEOM::VERTEX;
4949 case SMDS_TOP_3DSPACE:
4950 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4951 aNodePosition->shapeType = GEOM::SOLID;
4952 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4953 aNodePosition->shapeType = GEOM::SHELL;
4959 return aNodePosition;
4962 //=============================================================================
4964 * \brief Return position of an element on shape
4966 //=============================================================================
4968 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4971 _preMeshInfo->FullLoadFromFile();
4973 SMESH::ElementPosition anElementPosition;
4974 anElementPosition.shapeID = 0;
4975 anElementPosition.shapeType = GEOM::SHAPE;
4977 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4978 if ( !mesh ) return anElementPosition;
4980 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4982 anElementPosition.shapeID = anElem->getshapeId();
4983 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4984 if ( !aSp.IsNull() ) {
4985 switch ( aSp.ShapeType() ) {
4987 anElementPosition.shapeType = GEOM::EDGE;
4990 anElementPosition.shapeType = GEOM::FACE;
4993 anElementPosition.shapeType = GEOM::VERTEX;
4996 anElementPosition.shapeType = GEOM::SOLID;
4999 anElementPosition.shapeType = GEOM::SHELL;
5005 return anElementPosition;
5008 //=============================================================================
5010 * If given element is node returns IDs of shape from position
5011 * If there is not node for given ID - returns -1
5013 //=============================================================================
5015 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5018 _preMeshInfo->FullLoadFromFile();
5020 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5021 if ( aMeshDS == NULL )
5025 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5027 return aNode->getshapeId();
5034 //=============================================================================
5036 * For given element returns ID of result shape after
5037 * ::FindShape() from SMESH_MeshEditor
5038 * If there is not element for given ID - returns -1
5040 //=============================================================================
5042 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5045 _preMeshInfo->FullLoadFromFile();
5047 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5048 if ( aMeshDS == NULL )
5051 // try to find element
5052 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5056 ::SMESH_MeshEditor aMeshEditor(_impl);
5057 int index = aMeshEditor.FindShape( elem );
5065 //=============================================================================
5067 * Returns number of nodes for given element
5068 * If there is not element for given ID - returns -1
5070 //=============================================================================
5072 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5075 _preMeshInfo->FullLoadFromFile();
5077 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5078 if ( aMeshDS == NULL ) return -1;
5079 // try to find element
5080 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5081 if(!elem) return -1;
5082 return elem->NbNodes();
5086 //=============================================================================
5088 * Returns ID of node by given index for given element
5089 * If there is not element for given ID - returns -1
5090 * If there is not node for given index - returns -2
5092 //=============================================================================
5094 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5097 _preMeshInfo->FullLoadFromFile();
5099 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5100 if ( aMeshDS == NULL ) return -1;
5101 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5102 if(!elem) return -1;
5103 if( index>=elem->NbNodes() || index<0 ) return -1;
5104 return elem->GetNode(index)->GetID();
5107 //=============================================================================
5109 * Returns IDs of nodes of given element
5111 //=============================================================================
5113 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5116 _preMeshInfo->FullLoadFromFile();
5118 SMESH::long_array_var aResult = new SMESH::long_array();
5119 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5121 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5123 aResult->length( elem->NbNodes() );
5124 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5125 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5126 aResult[ i ] = n->GetID();
5129 return aResult._retn();
5132 //=============================================================================
5134 * Returns true if given node is medium node
5135 * in given quadratic element
5137 //=============================================================================
5139 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5142 _preMeshInfo->FullLoadFromFile();
5144 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5145 if ( aMeshDS == NULL ) return false;
5147 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5148 if(!aNode) return false;
5149 // try to find element
5150 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5151 if(!elem) return false;
5153 return elem->IsMediumNode(aNode);
5157 //=============================================================================
5159 * Returns true if given node is medium node
5160 * in one of quadratic elements
5162 //=============================================================================
5164 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5165 SMESH::ElementType theElemType)
5168 _preMeshInfo->FullLoadFromFile();
5170 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5171 if ( aMeshDS == NULL ) return false;
5174 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5175 if(!aNode) return false;
5177 SMESH_MesherHelper aHelper( *(_impl) );
5179 SMDSAbs_ElementType aType;
5180 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5181 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5182 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5183 else aType = SMDSAbs_All;
5185 return aHelper.IsMedium(aNode,aType);
5189 //=============================================================================
5191 * Returns number of edges for given element
5193 //=============================================================================
5195 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5198 _preMeshInfo->FullLoadFromFile();
5200 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5201 if ( aMeshDS == NULL ) return -1;
5202 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5203 if(!elem) return -1;
5204 return elem->NbEdges();
5208 //=============================================================================
5210 * Returns number of faces for given element
5212 //=============================================================================
5214 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5217 _preMeshInfo->FullLoadFromFile();
5219 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5220 if ( aMeshDS == NULL ) return -1;
5221 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5222 if(!elem) return -1;
5223 return elem->NbFaces();
5226 //=======================================================================
5227 //function : GetElemFaceNodes
5228 //purpose : Returns nodes of given face (counted from zero) for given element.
5229 //=======================================================================
5231 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5232 CORBA::Short faceIndex)
5235 _preMeshInfo->FullLoadFromFile();
5237 SMESH::long_array_var aResult = new SMESH::long_array();
5238 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5240 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5242 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5243 if ( faceIndex < vtool.NbFaces() )
5245 aResult->length( vtool.NbFaceNodes( faceIndex ));
5246 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5247 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5248 aResult[ i ] = nn[ i ]->GetID();
5252 return aResult._retn();
5255 //=======================================================================
5256 //function : GetFaceNormal
5257 //purpose : Returns three components of normal of given mesh face.
5258 //=======================================================================
5260 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5261 CORBA::Boolean normalized)
5264 _preMeshInfo->FullLoadFromFile();
5266 SMESH::double_array_var aResult = new SMESH::double_array();
5268 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5271 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5273 aResult->length( 3 );
5274 aResult[ 0 ] = normal.X();
5275 aResult[ 1 ] = normal.Y();
5276 aResult[ 2 ] = normal.Z();
5279 return aResult._retn();
5282 //=======================================================================
5283 //function : FindElementByNodes
5284 //purpose : Returns an element based on all given nodes.
5285 //=======================================================================
5287 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5290 _preMeshInfo->FullLoadFromFile();
5292 CORBA::Long elemID(0);
5293 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5295 vector< const SMDS_MeshNode * > nn( nodes.length() );
5296 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5297 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5300 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5301 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5302 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5303 _impl->NbVolumes( ORDER_QUADRATIC )))
5304 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5306 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5311 //================================================================================
5313 * \brief Return elements including all given nodes.
5315 //================================================================================
5317 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5318 SMESH::ElementType elemType)
5321 _preMeshInfo->FullLoadFromFile();
5323 SMESH::long_array_var result = new SMESH::long_array();
5325 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5327 vector< const SMDS_MeshNode * > nn( nodes.length() );
5328 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5329 nn[i] = mesh->FindNode( nodes[i] );
5331 std::vector<const SMDS_MeshElement *> elems;
5332 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5333 result->length( elems.size() );
5334 for ( size_t i = 0; i < elems.size(); ++i )
5335 result[i] = elems[i]->GetID();
5337 return result._retn();
5340 //=============================================================================
5342 * Returns true if given element is polygon
5344 //=============================================================================
5346 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5349 _preMeshInfo->FullLoadFromFile();
5351 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5352 if ( aMeshDS == NULL ) return false;
5353 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5354 if(!elem) return false;
5355 return elem->IsPoly();
5359 //=============================================================================
5361 * Returns true if given element is quadratic
5363 //=============================================================================
5365 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5368 _preMeshInfo->FullLoadFromFile();
5370 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5371 if ( aMeshDS == NULL ) return false;
5372 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5373 if(!elem) return false;
5374 return elem->IsQuadratic();
5377 //=============================================================================
5379 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5381 //=============================================================================
5383 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5386 _preMeshInfo->FullLoadFromFile();
5388 if ( const SMDS_BallElement* ball =
5389 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5390 return ball->GetDiameter();
5395 //=============================================================================
5397 * Returns bary center for given element
5399 //=============================================================================
5401 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5404 _preMeshInfo->FullLoadFromFile();
5406 SMESH::double_array_var aResult = new SMESH::double_array();
5407 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5408 if ( aMeshDS == NULL )
5409 return aResult._retn();
5411 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5413 return aResult._retn();
5415 if(elem->GetType()==SMDSAbs_Volume) {
5416 SMDS_VolumeTool aTool;
5417 if(aTool.Set(elem)) {
5419 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5424 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5426 double x=0., y=0., z=0.;
5427 for(; anIt->more(); ) {
5429 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5443 return aResult._retn();
5446 //================================================================================
5448 * \brief Create a group of elements preventing computation of a sub-shape
5450 //================================================================================
5452 SMESH::ListOfGroups*
5453 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5454 const char* theGroupName )
5455 throw ( SALOME::SALOME_Exception )
5457 Unexpect aCatch(SALOME_SalomeException);
5459 if ( !theGroupName || strlen( theGroupName) == 0 )
5460 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5462 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5463 ::SMESH_MeshEditor::ElemFeatures elemType;
5465 // submesh by subshape id
5466 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5467 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5470 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5471 if ( error && error->HasBadElems() )
5473 // sort bad elements by type
5474 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5475 const list<const SMDS_MeshElement*>& badElems =
5476 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5477 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5478 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5479 for ( ; elemIt != elemEnd; ++elemIt )
5481 const SMDS_MeshElement* elem = *elemIt;
5482 if ( !elem ) continue;
5484 if ( elem->GetID() < 1 )
5486 // elem is a temporary element, make a real element
5487 vector< const SMDS_MeshNode* > nodes;
5488 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5489 while ( nIt->more() && elem )
5491 nodes.push_back( nIt->next() );
5492 if ( nodes.back()->GetID() < 1 )
5493 elem = 0; // a temporary element on temporary nodes
5497 ::SMESH_MeshEditor editor( _impl );
5498 elem = editor.AddElement( nodes, elemType.Init( elem ));
5502 elemsByType[ elem->GetType() ].push_back( elem );
5505 // how many groups to create?
5507 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5508 nbTypes += int( !elemsByType[ i ].empty() );
5509 groups->length( nbTypes );
5512 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5514 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5515 if ( elems.empty() ) continue;
5517 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5518 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5520 SMESH::SMESH_Mesh_var mesh = _this();
5521 SALOMEDS::SObject_wrap aSO =
5522 _gen_i->PublishGroup( mesh, groups[ iG ],
5523 GEOM::GEOM_Object::_nil(), theGroupName);
5525 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5526 if ( !grp_i ) continue;
5528 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5529 for ( size_t iE = 0; iE < elems.size(); ++iE )
5530 grpDS->SMDSGroup().Add( elems[ iE ]);
5535 return groups._retn();
5538 //=============================================================================
5540 * Create and publish group servants if any groups were imported or created anyhow
5542 //=============================================================================
5544 void SMESH_Mesh_i::CreateGroupServants()
5546 SMESH::SMESH_Mesh_var aMesh = _this();
5549 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5550 while ( groupIt->more() )
5552 ::SMESH_Group* group = groupIt->next();
5553 int anId = group->GetID();
5555 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5556 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5558 addedIDs.insert( anId );
5560 SMESH_GroupBase_i* aGroupImpl;
5562 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5563 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5565 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5566 shape = groupOnGeom->GetShape();
5569 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5572 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5573 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5574 aGroupImpl->Register();
5576 // register CORBA object for persistence
5577 int nextId = _gen_i->RegisterObject( groupVar );
5578 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5579 else { nextId = 0; } // avoid "unused variable" warning in release mode
5581 // publishing the groups in the study
5582 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5583 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5585 if ( !addedIDs.empty() )
5588 set<int>::iterator id = addedIDs.begin();
5589 for ( ; id != addedIDs.end(); ++id )
5591 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5592 int i = std::distance( _mapGroups.begin(), it );
5593 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5598 //=============================================================================
5600 * \brief Return true if all sub-meshes are computed OK - to update an icon
5602 //=============================================================================
5604 bool SMESH_Mesh_i::IsComputedOK()
5606 return _impl->IsComputedOK();
5609 //=============================================================================
5611 * \brief Return groups cantained in _mapGroups by their IDs
5613 //=============================================================================
5615 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5617 int nbGroups = groupIDs.size();
5618 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5619 aList->length( nbGroups );
5621 list<int>::const_iterator ids = groupIDs.begin();
5622 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5624 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5625 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5626 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5628 aList->length( nbGroups );
5629 return aList._retn();
5632 //=============================================================================
5634 * \brief Return information about imported file
5636 //=============================================================================
5638 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5640 SMESH::MedFileInfo_var res( _medFileInfo );
5641 if ( !res.operator->() ) {
5642 res = new SMESH::MedFileInfo;
5644 res->fileSize = res->major = res->minor = res->release = -1;
5649 //=======================================================================
5650 //function : FileInfoToString
5651 //purpose : Persistence of file info
5652 //=======================================================================
5654 std::string SMESH_Mesh_i::FileInfoToString()
5657 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5659 s = SMESH_Comment( _medFileInfo->fileSize )
5660 << " " << _medFileInfo->major
5661 << " " << _medFileInfo->minor
5662 << " " << _medFileInfo->release
5663 << " " << _medFileInfo->fileName;
5668 //=======================================================================
5669 //function : FileInfoFromString
5670 //purpose : Persistence of file info
5671 //=======================================================================
5673 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5675 std::string size, major, minor, release, fileName;
5676 std::istringstream is(info);
5677 is >> size >> major >> minor >> release;
5678 fileName = info.data() + ( size.size() + 1 +
5681 release.size()+ 1 );
5683 _medFileInfo = new SMESH::MedFileInfo();
5684 _medFileInfo->fileName = fileName.c_str();
5685 _medFileInfo->fileSize = atoi( size.c_str() );
5686 _medFileInfo->major = atoi( major.c_str() );
5687 _medFileInfo->minor = atoi( minor.c_str() );
5688 _medFileInfo->release = atoi( release.c_str() );
5691 //=============================================================================
5693 * \brief Pass names of mesh groups from study to mesh DS
5695 //=============================================================================
5697 void SMESH_Mesh_i::checkGroupNames()
5699 int nbGrp = NbGroups();
5703 SMESH::ListOfGroups* grpList = 0;
5704 // avoid dump of "GetGroups"
5706 // store python dump into a local variable inside local scope
5707 SMESH::TPythonDump pDump; // do not delete this line of code
5708 grpList = GetGroups();
5711 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5712 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5715 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5716 if ( aGrpSO->_is_nil() )
5718 // correct name of the mesh group if necessary
5719 const char* guiName = aGrpSO->GetName();
5720 if ( strcmp(guiName, aGrp->GetName()) )
5721 aGrp->SetName( guiName );
5725 //=============================================================================
5727 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5729 //=============================================================================
5730 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5732 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5736 //=============================================================================
5738 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5740 //=============================================================================
5742 char* SMESH_Mesh_i::GetParameters()
5744 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5747 //=============================================================================
5749 * \brief Returns list of notebook variables used for last Mesh operation
5751 //=============================================================================
5752 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5754 SMESH::string_array_var aResult = new SMESH::string_array();
5755 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5757 CORBA::String_var aParameters = GetParameters();
5758 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5759 if ( aSections->length() > 0 ) {
5760 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5761 aResult->length( aVars.length() );
5762 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5763 aResult[i] = CORBA::string_dup( aVars[i] );
5766 return aResult._retn();
5769 //=======================================================================
5770 //function : GetTypes
5771 //purpose : Returns types of elements it contains
5772 //=======================================================================
5774 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5777 return _preMeshInfo->GetTypes();
5779 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5783 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5784 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5785 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5786 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5787 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5788 if (_impl->NbNodes() &&
5789 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5790 types->length( nbTypes );
5792 return types._retn();
5795 //=======================================================================
5796 //function : GetMesh
5797 //purpose : Returns self
5798 //=======================================================================
5800 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5802 return SMESH::SMESH_Mesh::_duplicate( _this() );
5805 //=======================================================================
5806 //function : IsMeshInfoCorrect
5807 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5808 // * happen if mesh data is not yet fully loaded from the file of study.
5809 //=======================================================================
5811 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5813 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5816 //=============================================================================
5818 * \brief Returns number of mesh elements per each \a EntityType
5820 //=============================================================================
5822 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5825 return _preMeshInfo->GetMeshInfo();
5827 SMESH::long_array_var aRes = new SMESH::long_array();
5828 aRes->length(SMESH::Entity_Last);
5829 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5831 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5833 return aRes._retn();
5834 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5835 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5836 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5837 return aRes._retn();
5840 //=============================================================================
5842 * \brief Returns number of mesh elements per each \a ElementType
5844 //=============================================================================
5846 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5848 SMESH::long_array_var aRes = new SMESH::long_array();
5849 aRes->length(SMESH::NB_ELEMENT_TYPES);
5850 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5853 const SMDS_MeshInfo* meshInfo = 0;
5855 meshInfo = _preMeshInfo;
5856 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5857 meshInfo = & meshDS->GetMeshInfo();
5860 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5861 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5863 return aRes._retn();
5866 //=============================================================================
5868 * Collect statistic of mesh elements given by iterator
5870 //=============================================================================
5872 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5873 SMESH::long_array& theInfo)
5875 if (!theItr) return;
5876 while (theItr->more())
5877 theInfo[ theItr->next()->GetEntityType() ]++;
5879 //=============================================================================
5881 * Returns mesh unstructed grid information.
5883 //=============================================================================
5885 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5887 SALOMEDS::TMPFile_var SeqFile;
5888 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5889 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5891 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5892 aWriter->WriteToOutputStringOn();
5893 aWriter->SetInputData(aGrid);
5894 aWriter->SetFileTypeToBinary();
5896 char* str = aWriter->GetOutputString();
5897 int size = aWriter->GetOutputStringLength();
5899 //Allocate octet buffer of required size
5900 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5901 //Copy ostrstream content to the octet buffer
5902 memcpy(OctetBuf, str, size);
5903 //Create and return TMPFile
5904 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5908 return SeqFile._retn();
5911 //=============================================================================
5912 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5913 * SMESH::ElementType type) */
5915 using namespace SMESH::Controls;
5916 //-----------------------------------------------------------------------------
5917 struct PredicateIterator : public SMDS_ElemIterator
5919 SMDS_ElemIteratorPtr _elemIter;
5920 PredicatePtr _predicate;
5921 const SMDS_MeshElement* _elem;
5922 SMDSAbs_ElementType _type;
5924 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5925 PredicatePtr predicate,
5926 SMDSAbs_ElementType type):
5927 _elemIter(iterator), _predicate(predicate), _type(type)
5935 virtual const SMDS_MeshElement* next()
5937 const SMDS_MeshElement* res = _elem;
5939 while ( _elemIter->more() && !_elem )
5941 if ((_elem = _elemIter->next()) &&
5942 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5943 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5950 //-----------------------------------------------------------------------------
5951 struct IDSourceIterator : public SMDS_ElemIterator
5953 const CORBA::Long* _idPtr;
5954 const CORBA::Long* _idEndPtr;
5955 SMESH::long_array_var _idArray;
5956 const SMDS_Mesh* _mesh;
5957 const SMDSAbs_ElementType _type;
5958 const SMDS_MeshElement* _elem;
5960 IDSourceIterator( const SMDS_Mesh* mesh,
5961 const CORBA::Long* ids,
5963 SMDSAbs_ElementType type):
5964 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5966 if ( _idPtr && nbIds && _mesh )
5969 IDSourceIterator( const SMDS_Mesh* mesh,
5970 SMESH::long_array* idArray,
5971 SMDSAbs_ElementType type):
5972 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5974 if ( idArray && _mesh )
5976 _idPtr = &_idArray[0];
5977 _idEndPtr = _idPtr + _idArray->length();
5985 virtual const SMDS_MeshElement* next()
5987 const SMDS_MeshElement* res = _elem;
5989 while ( _idPtr < _idEndPtr && !_elem )
5991 if ( _type == SMDSAbs_Node )
5993 _elem = _mesh->FindNode( *_idPtr++ );
5995 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5996 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6004 //-----------------------------------------------------------------------------
6006 struct NodeOfElemIterator : public SMDS_ElemIterator
6008 TColStd_MapOfInteger _checkedNodeIDs;
6009 SMDS_ElemIteratorPtr _elemIter;
6010 SMDS_ElemIteratorPtr _nodeIter;
6011 const SMDS_MeshElement* _node;
6013 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6015 if ( _elemIter && _elemIter->more() )
6017 _nodeIter = _elemIter->next()->nodesIterator();
6025 virtual const SMDS_MeshElement* next()
6027 const SMDS_MeshElement* res = _node;
6029 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6031 if ( _nodeIter->more() )
6033 _node = _nodeIter->next();
6034 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6039 _nodeIter = _elemIter->next()->nodesIterator();
6047 //=============================================================================
6049 * Return iterator on elements of given type in given object
6051 //=============================================================================
6053 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6054 SMESH::ElementType theType)
6056 SMDS_ElemIteratorPtr elemIt;
6057 bool typeOK = ( theType == SMESH::ALL );
6058 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6060 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6061 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6062 if ( !mesh_i ) return elemIt;
6063 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6065 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6067 elemIt = meshDS->elementsIterator( elemType );
6070 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6072 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6075 elemIt = sm->GetElements();
6076 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6078 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6079 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6083 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6085 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6086 if ( groupDS && ( elemType == groupDS->GetType() ||
6087 elemType == SMDSAbs_Node ||
6088 elemType == SMDSAbs_All ))
6090 elemIt = groupDS->GetElements();
6091 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6094 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6096 if ( filter_i->GetElementType() == theType ||
6097 filter_i->GetElementType() == SMESH::ALL ||
6098 elemType == SMDSAbs_Node ||
6099 elemType == SMDSAbs_All)
6101 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6102 if ( pred_i && pred_i->GetPredicate() )
6104 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6105 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6106 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6107 elemIt = SMDS_ElemIteratorPtr
6108 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6109 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6115 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6116 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6117 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6119 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6120 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6123 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6124 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6128 SMESH::long_array_var ids = theObject->GetIDs();
6129 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6131 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6134 if ( elemIt && elemIt->more() && !typeOK )
6136 if ( elemType == SMDSAbs_Node )
6138 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6142 elemIt = SMDS_ElemIteratorPtr();
6148 //=============================================================================
6149 namespace // Finding concurrent hypotheses
6150 //=============================================================================
6154 * \brief mapping of mesh dimension into shape type
6156 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6158 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6160 case 0: aType = TopAbs_VERTEX; break;
6161 case 1: aType = TopAbs_EDGE; break;
6162 case 2: aType = TopAbs_FACE; break;
6164 default:aType = TopAbs_SOLID; break;
6169 //-----------------------------------------------------------------------------
6171 * \brief Internal structure used to find concurrent submeshes
6173 * It represents a pair < submesh, concurrent dimension >, where
6174 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6175 * with another submesh. In other words, it is dimension of a hypothesis assigned
6182 int _dim; //!< a dimension the algo can build (concurrent dimension)
6183 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6184 TopTools_MapOfShape _shapeMap;
6185 SMESH_subMesh* _subMesh;
6186 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6188 //-----------------------------------------------------------------------------
6189 // Return the algorithm
6190 const SMESH_Algo* GetAlgo() const
6191 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6193 //-----------------------------------------------------------------------------
6195 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6197 const TopoDS_Shape& theShape)
6199 _subMesh = (SMESH_subMesh*)theSubMesh;
6200 SetShape( theDim, theShape );
6203 //-----------------------------------------------------------------------------
6205 void SetShape(const int theDim,
6206 const TopoDS_Shape& theShape)
6209 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6210 if (_dim >= _ownDim)
6211 _shapeMap.Add( theShape );
6213 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6214 for( ; anExp.More(); anExp.Next() )
6215 _shapeMap.Add( anExp.Current() );
6219 //-----------------------------------------------------------------------------
6220 //! Check sharing of sub-shapes
6221 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6222 const TopTools_MapOfShape& theToFind,
6223 const TopAbs_ShapeEnum theType)
6225 bool isShared = false;
6226 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6227 for (; !isShared && anItr.More(); anItr.Next() )
6229 const TopoDS_Shape aSubSh = anItr.Key();
6230 // check for case when concurrent dimensions are same
6231 isShared = theToFind.Contains( aSubSh );
6232 // check for sub-shape with concurrent dimension
6233 TopExp_Explorer anExp( aSubSh, theType );
6234 for ( ; !isShared && anExp.More(); anExp.Next() )
6235 isShared = theToFind.Contains( anExp.Current() );
6240 //-----------------------------------------------------------------------------
6241 //! check algorithms
6242 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6243 const SMESHDS_Hypothesis* theA2)
6245 if ( !theA1 || !theA2 ||
6246 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6247 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6248 return false; // one of the hypothesis is not algorithm
6249 // check algorithm names (should be equal)
6250 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6254 //-----------------------------------------------------------------------------
6255 //! Check if sub-shape hypotheses are concurrent
6256 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6258 if ( _subMesh == theOther->_subMesh )
6259 return false; // same sub-shape - should not be
6261 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6262 // any of the two submeshes is not on COMPOUND shape )
6263 // -> no concurrency
6264 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6265 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6266 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6267 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6268 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6271 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6272 if ( !checkSubShape )
6275 // check algorithms to be same
6276 const SMESH_Algo* a1 = this->GetAlgo();
6277 const SMESH_Algo* a2 = theOther->GetAlgo();
6278 bool isSame = checkAlgo( a1, a2 );
6282 return false; // pb?
6283 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6286 // check hypothesises for concurrence (skip first as algorithm)
6288 // pointers should be same, because it is referened from mesh hypothesis partition
6289 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6290 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6291 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6292 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6294 // the submeshes are concurrent if their algorithms has different parameters
6295 return nbSame != theOther->_hypotheses.size() - 1;
6298 // Return true if algorithm of this SMESH_DimHyp is used if no
6299 // sub-mesh order is imposed by the user
6300 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6302 // NeedDiscreteBoundary() algo has a higher priority
6303 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6304 theOther->GetAlgo()->NeedDiscreteBoundary() )
6305 return !this->GetAlgo()->NeedDiscreteBoundary();
6307 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6310 }; // end of SMESH_DimHyp
6311 //-----------------------------------------------------------------------------
6313 typedef list<const SMESH_DimHyp*> TDimHypList;
6315 //-----------------------------------------------------------------------------
6317 void addDimHypInstance(const int theDim,
6318 const TopoDS_Shape& theShape,
6319 const SMESH_Algo* theAlgo,
6320 const SMESH_subMesh* theSubMesh,
6321 const list <const SMESHDS_Hypothesis*>& theHypList,
6322 TDimHypList* theDimHypListArr )
6324 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6325 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6326 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6327 dimHyp->_hypotheses.push_front(theAlgo);
6328 listOfdimHyp.push_back( dimHyp );
6331 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6332 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6333 theHypList.begin(), theHypList.end() );
6336 //-----------------------------------------------------------------------------
6337 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6338 TDimHypList& theListOfConcurr)
6340 if ( theListOfConcurr.empty() )
6342 theListOfConcurr.push_back( theDimHyp );
6346 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6347 while ( hypIt != theListOfConcurr.end() &&
6348 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6350 theListOfConcurr.insert( hypIt, theDimHyp );
6354 //-----------------------------------------------------------------------------
6355 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6356 const TDimHypList& theListOfDimHyp,
6357 TDimHypList& theListOfConcurrHyp,
6358 set<int>& theSetOfConcurrId )
6360 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6361 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6363 const SMESH_DimHyp* curDimHyp = *rIt;
6364 if ( curDimHyp == theDimHyp )
6365 break; // meet own dimHyp pointer in same dimension
6367 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6368 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6370 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6375 //-----------------------------------------------------------------------------
6376 void unionLists(TListOfInt& theListOfId,
6377 TListOfListOfInt& theListOfListOfId,
6380 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6381 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6383 continue; //skip already treated lists
6384 // check if other list has any same submesh object
6385 TListOfInt& otherListOfId = *it;
6386 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6387 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6390 // union two lists (from source into target)
6391 TListOfInt::iterator it2 = otherListOfId.begin();
6392 for ( ; it2 != otherListOfId.end(); it2++ ) {
6393 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6394 theListOfId.push_back(*it2);
6396 // clear source list
6397 otherListOfId.clear();
6400 //-----------------------------------------------------------------------------
6402 //! free memory allocated for dimension-hypothesis objects
6403 void removeDimHyps( TDimHypList* theArrOfList )
6405 for (int i = 0; i < 4; i++ ) {
6406 TDimHypList& listOfdimHyp = theArrOfList[i];
6407 TDimHypList::const_iterator it = listOfdimHyp.begin();
6408 for ( ; it != listOfdimHyp.end(); it++ )
6413 //-----------------------------------------------------------------------------
6415 * \brief find common submeshes with given submesh
6416 * \param theSubMeshList list of already collected submesh to check
6417 * \param theSubMesh given submesh to intersect with other
6418 * \param theCommonSubMeshes collected common submeshes
6420 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6421 const SMESH_subMesh* theSubMesh,
6422 set<const SMESH_subMesh*>& theCommon )
6426 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6427 for ( ; it != theSubMeshList.end(); it++ )
6428 theSubMesh->FindIntersection( *it, theCommon );
6429 theSubMeshList.push_back( theSubMesh );
6430 //theCommon.insert( theSubMesh );
6433 //-----------------------------------------------------------------------------
6434 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6436 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6437 for ( ; listsIt != smLists.end(); ++listsIt )
6439 const TListOfInt& smIDs = *listsIt;
6440 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6448 //=============================================================================
6450 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6452 //=============================================================================
6454 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6456 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6457 if ( isSubMeshInList( submeshID, anOrder ))
6460 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6461 return isSubMeshInList( submeshID, allConurrent );
6464 //=============================================================================
6466 * \brief Return submesh objects list in meshing order
6468 //=============================================================================
6470 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6472 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6474 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6476 return aResult._retn();
6478 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6479 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6480 anOrder.splice( anOrder.end(), allConurrent );
6483 TListOfListOfInt::iterator listIt = anOrder.begin();
6484 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6485 unionLists( *listIt, anOrder, listIndx + 1 );
6487 // convert submesh ids into interface instances
6488 // and dump command into python
6489 convertMeshOrder( anOrder, aResult, false );
6491 return aResult._retn();
6494 //=============================================================================
6496 * \brief Finds concurrent sub-meshes
6498 //=============================================================================
6500 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6502 TListOfListOfInt anOrder;
6503 ::SMESH_Mesh& mesh = GetImpl();
6505 // collect submeshes and detect concurrent algorithms and hypothesises
6506 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6508 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6509 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6510 ::SMESH_subMesh* sm = (*i_sm).second;
6512 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6514 // list of assigned hypothesises
6515 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6516 // Find out dimensions where the submesh can be concurrent.
6517 // We define the dimensions by algo of each of hypotheses in hypList
6518 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6519 for( ; hypIt != hypList.end(); hypIt++ ) {
6520 SMESH_Algo* anAlgo = 0;
6521 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6522 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6523 // hyp it-self is algo
6524 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6526 // try to find algorithm with help of sub-shapes
6527 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6528 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6529 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6532 continue; // no algorithm assigned to a current submesh
6534 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6535 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6537 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6538 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6539 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6541 } // end iterations on submesh
6543 // iterate on created dimension-hypotheses and check for concurrents
6544 for ( int i = 0; i < 4; i++ ) {
6545 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6546 // check for concurrents in own and other dimensions (step-by-step)
6547 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6548 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6549 const SMESH_DimHyp* dimHyp = *dhIt;
6550 TDimHypList listOfConcurr;
6551 set<int> setOfConcurrIds;
6552 // looking for concurrents and collect into own list
6553 for ( int j = i; j < 4; j++ )
6554 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6555 // check if any concurrents found
6556 if ( listOfConcurr.size() > 0 ) {
6557 // add own submesh to list of concurrent
6558 addInOrderOfPriority( dimHyp, listOfConcurr );
6559 list<int> listOfConcurrIds;
6560 TDimHypList::iterator hypIt = listOfConcurr.begin();
6561 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6562 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6563 anOrder.push_back( listOfConcurrIds );
6568 removeDimHyps(dimHypListArr);
6570 // now, minimize the number of concurrent groups
6571 // Here we assume that lists of submeshes can have same submesh
6572 // in case of multi-dimension algorithms, as result
6573 // list with common submesh has to be united into one list
6575 TListOfListOfInt::iterator listIt = anOrder.begin();
6576 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6577 unionLists( *listIt, anOrder, listIndx + 1 );
6583 //=============================================================================
6585 * \brief Set submesh object order
6586 * \param theSubMeshArray submesh array order
6588 //=============================================================================
6590 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6593 _preMeshInfo->ForgetOrLoad();
6596 ::SMESH_Mesh& mesh = GetImpl();
6598 TPythonDump aPythonDump; // prevent dump of called methods
6599 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6601 TListOfListOfInt subMeshOrder;
6602 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6604 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6605 TListOfInt subMeshIds;
6607 aPythonDump << ", ";
6608 aPythonDump << "[ ";
6609 // Collect subMeshes which should be clear
6610 // do it list-by-list, because modification of submesh order
6611 // take effect between concurrent submeshes only
6612 set<const SMESH_subMesh*> subMeshToClear;
6613 list<const SMESH_subMesh*> subMeshList;
6614 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6616 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6618 aPythonDump << ", ";
6619 aPythonDump << subMesh;
6620 subMeshIds.push_back( subMesh->GetId() );
6621 // detect common parts of submeshes
6622 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6623 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6625 aPythonDump << " ]";
6626 subMeshOrder.push_back( subMeshIds );
6628 // clear collected sub-meshes
6629 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6630 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6631 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6633 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6634 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6635 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6638 aPythonDump << " ])";
6640 mesh.SetMeshOrder( subMeshOrder );
6643 SMESH::SMESH_Mesh_var me = _this();
6644 _gen_i->UpdateIcons( me );
6649 //=============================================================================
6651 * \brief Convert submesh ids into submesh interfaces
6653 //=============================================================================
6655 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6656 SMESH::submesh_array_array& theResOrder,
6657 const bool theIsDump)
6659 int nbSet = theIdsOrder.size();
6660 TPythonDump aPythonDump; // prevent dump of called methods
6662 aPythonDump << "[ ";
6663 theResOrder.length(nbSet);
6664 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6666 for( ; it != theIdsOrder.end(); it++ ) {
6667 // translate submesh identificators into submesh objects
6668 // takeing into account real number of concurrent lists
6669 const TListOfInt& aSubOrder = (*it);
6670 if (!aSubOrder.size())
6673 aPythonDump << "[ ";
6674 // convert shape indices into interfaces
6675 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6676 aResSubSet->length(aSubOrder.size());
6677 TListOfInt::const_iterator subIt = aSubOrder.begin();
6679 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6680 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6682 SMESH::SMESH_subMesh_var subMesh =
6683 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6686 aPythonDump << ", ";
6687 aPythonDump << subMesh;
6689 aResSubSet[ j++ ] = subMesh;
6692 aPythonDump << " ]";
6694 theResOrder[ listIndx++ ] = aResSubSet;
6696 // correct number of lists
6697 theResOrder.length( listIndx );
6700 // finilise python dump
6701 aPythonDump << " ]";
6702 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6706 namespace // utils used by SMESH_MeshPartDS
6709 * \brief Class used to access to protected data of SMDS_MeshInfo
6711 struct TMeshInfo : public SMDS_MeshInfo
6713 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6716 * \brief Element holing its ID only
6718 struct TElemID : public SMDS_LinearEdge
6720 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6724 //================================================================================
6726 // Implementation of SMESH_MeshPartDS
6728 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6729 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6731 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6732 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6735 _meshDS = mesh_i->GetImpl().GetMeshDS();
6737 SetPersistentId( _meshDS->GetPersistentId() );
6739 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6741 // <meshPart> is the whole mesh
6742 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6744 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6745 myGroupSet = _meshDS->GetGroups();
6750 SMESH::long_array_var anIDs = meshPart->GetIDs();
6751 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6752 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6754 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6755 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6756 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6761 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6762 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6763 if ( _elements[ e->GetType() ].insert( e ).second )
6766 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6767 while ( nIt->more() )
6769 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6770 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6777 ShapeToMesh( _meshDS->ShapeToMesh() );
6779 _meshDS = 0; // to enforce iteration on _elements and _nodes
6782 // -------------------------------------------------------------------------------------
6783 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6784 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6787 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6788 for ( ; partIt != meshPart.end(); ++partIt )
6789 if ( const SMDS_MeshElement * e = *partIt )
6790 if ( _elements[ e->GetType() ].insert( e ).second )
6793 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6794 while ( nIt->more() )
6796 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6797 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6803 // -------------------------------------------------------------------------------------
6804 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6806 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6808 TElemID elem( IDelem );
6809 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6810 if ( !_elements[ iType ].empty() )
6812 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6813 if ( it != _elements[ iType ].end() )
6818 // -------------------------------------------------------------------------------------
6819 bool SMESH_MeshPartDS::HasNumerationHoles()
6821 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6823 return ( MinNodeID() != 1 ||
6824 MaxNodeID() != NbNodes() ||
6825 MinElementID() != 1 ||
6826 MaxElementID() != NbElements() );
6828 // -------------------------------------------------------------------------------------
6829 int SMESH_MeshPartDS::MaxNodeID() const
6831 if ( _meshDS ) return _meshDS->MaxNodeID();
6832 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6834 // -------------------------------------------------------------------------------------
6835 int SMESH_MeshPartDS::MinNodeID() const
6837 if ( _meshDS ) return _meshDS->MinNodeID();
6838 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6840 // -------------------------------------------------------------------------------------
6841 int SMESH_MeshPartDS::MaxElementID() const
6843 if ( _meshDS ) return _meshDS->MaxElementID();
6845 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6846 if ( !_elements[ iType ].empty() )
6847 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6850 // -------------------------------------------------------------------------------------
6851 int SMESH_MeshPartDS::MinElementID() const
6853 if ( _meshDS ) return _meshDS->MinElementID();
6855 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6856 if ( !_elements[ iType ].empty() )
6857 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6860 // -------------------------------------------------------------------------------------
6861 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6863 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6865 typedef SMDS_SetIterator
6866 <const SMDS_MeshElement*,
6867 TIDSortedElemSet::const_iterator,
6868 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6869 SMDS_MeshElement::GeomFilter
6872 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6874 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6875 _elements[type].end(),
6876 SMDS_MeshElement::GeomFilter( geomType )));
6878 // -------------------------------------------------------------------------------------
6879 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6881 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6883 typedef SMDS_SetIterator
6884 <const SMDS_MeshElement*,
6885 TIDSortedElemSet::const_iterator,
6886 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6887 SMDS_MeshElement::EntityFilter
6890 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6892 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6893 _elements[type].end(),
6894 SMDS_MeshElement::EntityFilter( entity )));
6896 // -------------------------------------------------------------------------------------
6897 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6899 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6900 if ( type == SMDSAbs_All && !_meshDS )
6902 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6904 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6905 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6907 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6909 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6910 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6912 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6913 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6915 // -------------------------------------------------------------------------------------
6916 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6917 iterType SMESH_MeshPartDS::methName() const \
6919 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6920 return _meshDS ? _meshDS->methName() : iterType \
6921 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6923 // -------------------------------------------------------------------------------------
6924 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6925 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6926 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6927 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6928 #undef _GET_ITER_DEFINE
6930 // END Implementation of SMESH_MeshPartDS
6932 //================================================================================