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 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2426 TopoDS_Shape newShape = newGroupShape( *data, how );
2427 if ( !newShape.IsNull() )
2429 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2431 TopoDS_Compound compound;
2432 BRep_Builder().MakeCompound( compound );
2433 BRep_Builder().Add( compound, newShape );
2434 newShape = compound;
2436 int newID = _impl->GetSubMesh( newShape )->GetId();
2437 if ( oldID && oldID != newID )
2438 old2newIDs.insert( std::make_pair( oldID, newID ));
2442 // re-assign hypotheses
2443 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2445 int sID = ids2Hyps[i].first;
2446 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2447 if ( o2n != old2newIDs.end() )
2449 else if ( sID != 1 )
2451 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2452 const THypList& hyps = ids2Hyps[i].second;
2453 THypList::const_iterator h = hyps.begin();
2454 for ( ; h != hyps.end(); ++h )
2455 _impl->AddHypothesis( s, (*h)->GetID() );
2459 // restore groups on geometry
2460 for ( size_t i = 0; i < groupsData.size(); ++i )
2462 const TGroupOnGeomData& data = groupsData[i];
2463 if ( data._shape.IsNull() )
2466 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2467 if ( i2g == _mapGroups.end() ) continue;
2469 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2470 if ( !gr_i ) continue;
2472 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2474 _mapGroups.erase( i2g );
2476 g->GetGroupDS()->SetColor( data._color );
2479 std::map< int, int >::iterator o2n = old2newIDs.begin();
2480 for ( ; o2n != old2newIDs.end(); ++o2n )
2482 int newID = o2n->second, oldID = o2n->first;
2483 if ( !_mapSubMesh.count( oldID ))
2487 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2488 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2489 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2491 _mapSubMesh. erase(oldID);
2492 _mapSubMesh_i. erase(oldID);
2493 _mapSubMeshIor.erase(oldID);
2495 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2498 // update _mapSubMesh
2499 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2500 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2501 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2504 if ( !sameTopology )
2506 // remove invalid study sub-objects
2507 CheckGeomGroupModif();
2510 _gen_i->UpdateIcons( me );
2512 if ( !isBreakLink && isShaper )
2514 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2515 if ( !meshSO->_is_nil() )
2516 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2520 //=============================================================================
2522 * \brief Update objects depending on changed geom groups
2524 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2525 * issue 0020210: Update of a smesh group after modification of the associated geom group
2527 //=============================================================================
2529 void SMESH_Mesh_i::CheckGeomGroupModif()
2531 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2532 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2533 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2534 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2535 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2537 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2538 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2539 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2541 int nbValid = 0, nbRemoved = 0;
2542 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2543 for ( ; chItr->More(); chItr->Next() )
2545 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2546 if ( !smSO->_is_nil() &&
2547 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2548 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2550 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2551 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2552 if ( !geom->_non_existent() )
2555 continue; // keep the sub-mesh
2558 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2559 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2560 if ( !sm->_is_nil() && !sm->_non_existent() )
2562 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2563 if ( smGeom->_is_nil() )
2565 RemoveSubMesh( sm );
2572 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2573 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2577 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2578 builder->RemoveObjectWithChildren( rootSO );
2582 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2583 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2584 while ( i_gr != _mapGroups.end())
2586 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2588 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2589 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2590 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2591 bool isValidGeom = false;
2592 if ( !onGeom->_is_nil() )
2594 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2596 else if ( !onFilt->_is_nil() )
2598 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2602 isValidGeom = ( !groupSO->_is_nil() &&
2603 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2607 if ( !IsLoaded() || group->IsEmpty() )
2609 RemoveGroup( group );
2611 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2613 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2615 else // is it possible?
2617 builder->RemoveObjectWithChildren( refSO );
2623 if ( !_impl->HasShapeToMesh() ) return;
2625 CORBA::Long nbEntities = NbNodes() + NbElements();
2627 // Check if group contents changed
2629 typedef map< string, TopoDS_Shape > TEntry2Geom;
2630 TEntry2Geom newGroupContents;
2632 list<TGeomGroupData>::iterator
2633 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2634 for ( ; data != dataEnd; ++data )
2636 pair< TEntry2Geom::iterator, bool > it_new =
2637 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2638 bool processedGroup = !it_new.second;
2639 TopoDS_Shape& newShape = it_new.first->second;
2640 if ( !processedGroup )
2641 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2642 if ( newShape.IsNull() )
2643 continue; // no changes
2646 _preMeshInfo->ForgetOrLoad();
2648 if ( processedGroup ) { // update group indices
2649 list<TGeomGroupData>::iterator data2 = data;
2650 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2651 data->_indices = data2->_indices;
2654 // Update SMESH objects according to new GEOM group contents
2656 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2657 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2659 int oldID = submesh->GetId();
2660 if ( !_mapSubMeshIor.count( oldID ))
2662 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2664 // update hypotheses
2665 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2666 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2667 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2669 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2670 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2672 // care of submeshes
2673 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2674 int newID = newSubmesh->GetId();
2675 if ( newID != oldID ) {
2676 _mapSubMesh [ newID ] = newSubmesh;
2677 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2678 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2679 _mapSubMesh. erase(oldID);
2680 _mapSubMesh_i. erase(oldID);
2681 _mapSubMeshIor.erase(oldID);
2682 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2687 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2688 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2689 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2691 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2693 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2694 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2695 ds->SetShape( newShape );
2700 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2701 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2703 // Remove groups and submeshes basing on removed sub-shapes
2705 TopTools_MapOfShape newShapeMap;
2706 TopoDS_Iterator shapeIt( newShape );
2707 for ( ; shapeIt.More(); shapeIt.Next() )
2708 newShapeMap.Add( shapeIt.Value() );
2710 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2711 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2713 if ( newShapeMap.Contains( shapeIt.Value() ))
2715 TopTools_IndexedMapOfShape oldShapeMap;
2716 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2717 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2719 const TopoDS_Shape& oldShape = oldShapeMap(i);
2720 int oldInd = meshDS->ShapeToIndex( oldShape );
2722 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2723 if ( i_smIor != _mapSubMeshIor.end() ) {
2724 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2727 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2728 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2730 // check if a group bases on oldInd shape
2731 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2732 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2733 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2734 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2736 RemoveGroup( i_grp->second ); // several groups can base on same shape
2737 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2742 // Reassign hypotheses and update groups after setting the new shape to mesh
2744 // collect anassigned hypotheses
2745 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2746 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2747 TShapeHypList assignedHyps;
2748 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2750 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2751 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2752 if ( !hyps.empty() ) {
2753 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2754 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2755 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2758 // collect shapes supporting groups
2759 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2760 TShapeTypeList groupData;
2761 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2762 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2763 for ( ; grIt != groups.end(); ++grIt )
2765 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2767 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2769 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2771 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2772 _impl->ShapeToMesh( newShape );
2774 // reassign hypotheses
2775 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2776 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2778 TIndexedShape& geom = indS_hyps->first;
2779 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2780 int oldID = geom._index;
2781 int newID = meshDS->ShapeToIndex( geom._shape );
2782 if ( oldID == 1 ) { // main shape
2784 geom._shape = newShape;
2788 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2789 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2790 // care of sub-meshes
2791 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2792 if ( newID != oldID ) {
2793 _mapSubMesh [ newID ] = newSubmesh;
2794 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2795 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2796 _mapSubMesh. erase(oldID);
2797 _mapSubMesh_i. erase(oldID);
2798 _mapSubMeshIor.erase(oldID);
2799 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2803 TShapeTypeList::iterator geomType = groupData.begin();
2804 for ( ; geomType != groupData.end(); ++geomType )
2806 const TIndexedShape& geom = geomType->first;
2807 int oldID = geom._index;
2808 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2811 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2812 CORBA::String_var name = groupSO->GetName();
2814 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2815 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2816 /*id=*/-1, geom._shape ))
2817 group_i->changeLocalId( group->GetID() );
2820 break; // everything has been updated
2823 } // loop on group data
2827 CORBA::Long newNbEntities = NbNodes() + NbElements();
2828 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2829 if ( newNbEntities != nbEntities )
2831 // Add all SObjects with icons to soToUpdateIcons
2832 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2834 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2835 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2836 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2838 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2839 i_gr != _mapGroups.end(); ++i_gr ) // groups
2840 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2843 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2844 for ( ; so != soToUpdateIcons.end(); ++so )
2845 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2848 //=============================================================================
2850 * \brief Create standalone group from a group on geometry or filter
2852 //=============================================================================
2854 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2855 throw (SALOME::SALOME_Exception)
2857 SMESH::SMESH_Group_var aGroup;
2862 _preMeshInfo->FullLoadFromFile();
2864 if ( theGroup->_is_nil() )
2865 return aGroup._retn();
2867 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2869 return aGroup._retn();
2871 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2873 const int anId = aGroupToRem->GetLocalID();
2874 if ( !_impl->ConvertToStandalone( anId ) )
2875 return aGroup._retn();
2876 removeGeomGroupData( theGroup );
2878 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2880 // remove old instance of group from own map
2881 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2882 _mapGroups.erase( anId );
2884 SALOMEDS::StudyBuilder_var builder;
2885 SALOMEDS::SObject_wrap aGroupSO;
2886 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2887 if ( !aStudy->_is_nil() ) {
2888 builder = aStudy->NewBuilder();
2889 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2890 if ( !aGroupSO->_is_nil() )
2892 // remove reference to geometry
2893 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2894 for ( ; chItr->More(); chItr->Next() )
2896 // Remove group's child SObject
2897 SALOMEDS::SObject_wrap so = chItr->Value();
2898 builder->RemoveObject( so );
2900 // Update Python script
2901 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2902 << ".ConvertToStandalone( " << aGroupSO << " )";
2904 // change icon of Group on Filter
2907 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2908 // const int isEmpty = ( elemTypes->length() == 0 );
2911 SALOMEDS::GenericAttribute_wrap anAttr =
2912 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2913 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2914 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2920 // remember new group in own map
2921 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2922 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2924 // register CORBA object for persistence
2925 _gen_i->RegisterObject( aGroup );
2927 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2928 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2929 //aGroup->Register();
2930 aGroupToRem->UnRegister();
2932 SMESH_CATCH( SMESH::throwCorbaException );
2934 return aGroup._retn();
2937 //=============================================================================
2941 //=============================================================================
2943 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2945 if(MYDEBUG) MESSAGE( "createSubMesh" );
2946 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2947 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2950 SMESH_subMesh_i * subMeshServant;
2953 subMeshId = mySubMesh->GetId();
2954 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2956 else // "invalid sub-mesh"
2958 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2959 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2960 if ( _mapSubMesh.empty() )
2963 subMeshId = _mapSubMesh.begin()->first - 1;
2964 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2967 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2969 _mapSubMesh [subMeshId] = mySubMesh;
2970 _mapSubMesh_i [subMeshId] = subMeshServant;
2971 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2973 subMeshServant->Register();
2975 // register CORBA object for persistence
2976 int nextId = _gen_i->RegisterObject( subMesh );
2977 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2978 else { nextId = 0; } // avoid "unused variable" warning
2980 // to track changes of GEOM groups
2981 if ( subMeshId > 0 )
2982 addGeomGroupData( theSubShapeObject, subMesh );
2984 return subMesh._retn();
2987 //=======================================================================
2988 //function : getSubMesh
2990 //=======================================================================
2992 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2994 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2995 if ( it == _mapSubMeshIor.end() )
2996 return SMESH::SMESH_subMesh::_nil();
2998 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3001 //=============================================================================
3005 //=============================================================================
3007 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3008 GEOM::GEOM_Object_ptr theSubShapeObject )
3010 bool isHypChanged = false;
3011 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3012 return isHypChanged;
3014 const int subMeshId = theSubMesh->GetId();
3016 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3019 if (( _mapSubMesh.count( subMeshId )) &&
3020 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3022 TopoDS_Shape S = sm->GetSubShape();
3025 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3026 isHypChanged = !hyps.empty();
3027 if ( isHypChanged && _preMeshInfo )
3028 _preMeshInfo->ForgetOrLoad();
3029 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3030 for ( ; hyp != hyps.end(); ++hyp )
3031 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3038 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3039 isHypChanged = ( aHypList->length() > 0 );
3040 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3041 removeHypothesis( theSubShapeObject, aHypList[i] );
3044 catch( const SALOME::SALOME_Exception& ) {
3045 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3047 removeGeomGroupData( theSubShapeObject );
3051 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3052 if ( id_smi != _mapSubMesh_i.end() )
3053 id_smi->second->UnRegister();
3055 // remove a CORBA object
3056 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3057 if ( id_smptr != _mapSubMeshIor.end() )
3058 SMESH::SMESH_subMesh_var( id_smptr->second );
3060 _mapSubMesh.erase(subMeshId);
3061 _mapSubMesh_i.erase(subMeshId);
3062 _mapSubMeshIor.erase(subMeshId);
3064 return isHypChanged;
3067 //=============================================================================
3071 //=============================================================================
3073 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3074 const char* theName,
3076 const TopoDS_Shape& theShape,
3077 const SMESH_PredicatePtr& thePredicate )
3079 std::string newName;
3080 if ( !theName || !theName[0] )
3082 std::set< std::string > presentNames;
3083 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3084 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3086 CORBA::String_var name = i_gr->second->GetName();
3087 presentNames.insert( name.in() );
3090 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3091 } while ( !presentNames.insert( newName ).second );
3092 theName = newName.c_str();
3094 SMESH::SMESH_GroupBase_var aGroup;
3095 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3096 theID, theShape, thePredicate ))
3098 int anId = g->GetID();
3099 SMESH_GroupBase_i* aGroupImpl;
3100 if ( !theShape.IsNull() )
3101 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3102 else if ( thePredicate )
3103 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3105 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3107 aGroup = aGroupImpl->_this();
3108 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3109 aGroupImpl->Register();
3111 // register CORBA object for persistence
3112 int nextId = _gen_i->RegisterObject( aGroup );
3113 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3114 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3116 // to track changes of GEOM groups
3117 if ( !theShape.IsNull() ) {
3118 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3119 addGeomGroupData( geom, aGroup );
3122 return aGroup._retn();
3125 //=============================================================================
3127 * SMESH_Mesh_i::removeGroup
3129 * Should be called by ~SMESH_Group_i()
3131 //=============================================================================
3133 void SMESH_Mesh_i::removeGroup( const int theId )
3135 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3136 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3137 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3138 _mapGroups.erase( theId );
3139 removeGeomGroupData( group );
3140 if ( !_impl->RemoveGroup( theId ))
3142 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3143 RemoveGroup( group );
3145 group->UnRegister();
3149 //=============================================================================
3153 //=============================================================================
3155 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3156 throw(SALOME::SALOME_Exception)
3158 SMESH::log_array_var aLog;
3162 _preMeshInfo->FullLoadFromFile();
3164 list < SMESHDS_Command * >logDS = _impl->GetLog();
3165 aLog = new SMESH::log_array;
3167 int lg = logDS.size();
3170 list < SMESHDS_Command * >::iterator its = logDS.begin();
3171 while(its != logDS.end()){
3172 SMESHDS_Command *com = *its;
3173 int comType = com->GetType();
3175 int lgcom = com->GetNumber();
3177 const list < int >&intList = com->GetIndexes();
3178 int inum = intList.size();
3180 list < int >::const_iterator ii = intList.begin();
3181 const list < double >&coordList = com->GetCoords();
3182 int rnum = coordList.size();
3184 list < double >::const_iterator ir = coordList.begin();
3185 aLog[indexLog].commandType = comType;
3186 aLog[indexLog].number = lgcom;
3187 aLog[indexLog].coords.length(rnum);
3188 aLog[indexLog].indexes.length(inum);
3189 for(int i = 0; i < rnum; i++){
3190 aLog[indexLog].coords[i] = *ir;
3191 //MESSAGE(" "<<i<<" "<<ir.Value());
3194 for(int i = 0; i < inum; i++){
3195 aLog[indexLog].indexes[i] = *ii;
3196 //MESSAGE(" "<<i<<" "<<ii.Value());
3205 SMESH_CATCH( SMESH::throwCorbaException );
3207 return aLog._retn();
3211 //=============================================================================
3215 //=============================================================================
3217 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3221 SMESH_CATCH( SMESH::throwCorbaException );
3224 //=============================================================================
3228 //=============================================================================
3230 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3235 //=============================================================================
3238 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3239 // issue 0020918: groups removal is caused by hyp modification
3240 // issue 0021208: to forget not loaded mesh data at hyp modification
3241 struct TCallUp_i : public SMESH_Mesh::TCallUp
3243 SMESH_Mesh_i* _mesh;
3244 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3245 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3246 virtual void HypothesisModified( int hypID,
3247 bool updIcons) { _mesh->onHypothesisModified( hypID,
3249 virtual void Load () { _mesh->Load(); }
3250 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3254 //================================================================================
3256 * \brief callback from _impl to
3257 * 1) forget not loaded mesh data (issue 0021208)
3258 * 2) mark hypothesis as valid
3260 //================================================================================
3262 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3265 _preMeshInfo->ForgetOrLoad();
3267 if ( theUpdateIcons )
3269 SMESH::SMESH_Mesh_var mesh = _this();
3270 _gen_i->UpdateIcons( mesh );
3273 if ( _nbInvalidHypos != 0 )
3275 // mark a hypothesis as valid after edition
3277 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3278 SALOMEDS::SObject_wrap hypRoot;
3279 if ( !smeshComp->_is_nil() &&
3280 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3282 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3283 for ( ; anIter->More(); anIter->Next() )
3285 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3286 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3287 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3288 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3289 _gen_i->HighLightInvalid( hyp, false );
3291 nbInvalid += _gen_i->IsInvalid( hypSO );
3294 _nbInvalidHypos = nbInvalid;
3298 //=============================================================================
3302 //=============================================================================
3304 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3306 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3309 _impl->SetCallUp( new TCallUp_i(this));
3312 //=============================================================================
3316 //=============================================================================
3318 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3320 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3324 //=============================================================================
3326 * Return mesh editor
3328 //=============================================================================
3330 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3331 throw (SALOME::SALOME_Exception)
3333 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3337 _preMeshInfo->FullLoadFromFile();
3339 // Create MeshEditor
3341 _editor = new SMESH_MeshEditor_i( this, false );
3342 aMeshEdVar = _editor->_this();
3344 // Update Python script
3345 TPythonDump() << _editor << " = "
3346 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3348 SMESH_CATCH( SMESH::throwCorbaException );
3350 return aMeshEdVar._retn();
3353 //=============================================================================
3355 * Return mesh edition previewer
3357 //=============================================================================
3359 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3360 throw (SALOME::SALOME_Exception)
3362 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3366 _preMeshInfo->FullLoadFromFile();
3368 if ( !_previewEditor )
3369 _previewEditor = new SMESH_MeshEditor_i( this, true );
3370 aMeshEdVar = _previewEditor->_this();
3372 SMESH_CATCH( SMESH::throwCorbaException );
3374 return aMeshEdVar._retn();
3377 //================================================================================
3379 * \brief Return true if the mesh has been edited since a last total re-compute
3380 * and those modifications may prevent successful partial re-compute
3382 //================================================================================
3384 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3386 Unexpect aCatch(SALOME_SalomeException);
3387 return _impl->HasModificationsToDiscard();
3390 //================================================================================
3392 * \brief Returns a random unique color
3394 //================================================================================
3396 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3398 const int MAX_ATTEMPTS = 100;
3400 double tolerance = 0.5;
3401 SALOMEDS::Color col;
3405 // generate random color
3406 double red = (double)rand() / RAND_MAX;
3407 double green = (double)rand() / RAND_MAX;
3408 double blue = (double)rand() / RAND_MAX;
3409 // check existence in the list of the existing colors
3410 bool matched = false;
3411 std::list<SALOMEDS::Color>::const_iterator it;
3412 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3413 SALOMEDS::Color color = *it;
3414 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3415 matched = tol < tolerance;
3417 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3418 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3426 //=============================================================================
3428 * Sets auto-color mode. If it is on, groups get unique random colors
3430 //=============================================================================
3432 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3434 Unexpect aCatch(SALOME_SalomeException);
3435 _impl->SetAutoColor(theAutoColor);
3437 TPythonDump pyDump; // not to dump group->SetColor() from below code
3438 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3440 std::list<SALOMEDS::Color> aReservedColors;
3441 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3442 for ( ; it != _mapGroups.end(); it++ ) {
3443 if ( CORBA::is_nil( it->second )) continue;
3444 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3445 it->second->SetColor( aColor );
3446 aReservedColors.push_back( aColor );
3450 //=============================================================================
3452 * Returns true if auto-color mode is on
3454 //=============================================================================
3456 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3458 Unexpect aCatch(SALOME_SalomeException);
3459 return _impl->GetAutoColor();
3462 //=============================================================================
3464 * Checks if there are groups with equal names
3466 //=============================================================================
3468 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3470 return _impl->HasDuplicatedGroupNamesMED();
3473 //================================================================================
3475 * \brief Care of a file before exporting mesh into it
3477 //================================================================================
3479 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3481 SMESH_File aFile( file, false );
3483 if ( aFile.exists() ) {
3484 // existing filesystem node
3485 if ( !aFile.isDirectory() ) {
3486 if ( aFile.openForWriting() ) {
3487 if ( overwrite && ! aFile.remove()) {
3488 msg << "Can't replace " << aFile.getName();
3491 msg << "Can't write into " << aFile.getName();
3494 msg << "Location " << aFile.getName() << " is not a file";
3498 // nonexisting file; check if it can be created
3499 if ( !aFile.openForWriting() ) {
3500 msg << "You cannot create the file "
3502 << ". Check the directory existence and access rights";
3510 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3514 //================================================================================
3516 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3517 * \param file - file name
3518 * \param overwrite - to erase the file or not
3519 * \retval string - mesh name
3521 //================================================================================
3523 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3524 CORBA::Boolean overwrite)
3527 PrepareForWriting(file, overwrite);
3528 string aMeshName = "Mesh";
3529 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3530 if ( !aStudy->_is_nil() ) {
3531 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3532 if ( !aMeshSO->_is_nil() ) {
3533 CORBA::String_var name = aMeshSO->GetName();
3535 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3536 if ( !aStudy->GetProperties()->IsLocked() )
3538 SALOMEDS::GenericAttribute_wrap anAttr;
3539 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3540 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3541 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3542 ASSERT(!aFileName->_is_nil());
3543 aFileName->SetValue(file);
3544 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3545 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3546 ASSERT(!aFileType->_is_nil());
3547 aFileType->SetValue("FICHIERMED");
3551 // Update Python script
3552 // set name of mesh before export
3553 TPythonDump() << _gen_i << ".SetName("
3554 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3556 // check names of groups
3562 //================================================================================
3564 * \brief Export to MED file
3566 //================================================================================
3568 void SMESH_Mesh_i::ExportMED(const char* file,
3569 CORBA::Boolean auto_groups,
3570 CORBA::Long version,
3571 CORBA::Boolean overwrite,
3572 CORBA::Boolean autoDimension)
3573 throw(SALOME::SALOME_Exception)
3575 //MESSAGE("MED minor version: "<< minor);
3578 _preMeshInfo->FullLoadFromFile();
3580 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3581 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3583 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3585 << "auto_groups=" <<auto_groups << ", "
3586 << "minor=" << version << ", "
3587 << "overwrite=" << overwrite << ", "
3588 << "meshPart=None, "
3589 << "autoDimension=" << autoDimension << " )";
3591 SMESH_CATCH( SMESH::throwCorbaException );
3594 //================================================================================
3596 * \brief Export a mesh to a SAUV file
3598 //================================================================================
3600 void SMESH_Mesh_i::ExportSAUV (const char* file,
3601 CORBA::Boolean auto_groups)
3602 throw(SALOME::SALOME_Exception)
3604 Unexpect aCatch(SALOME_SalomeException);
3606 _preMeshInfo->FullLoadFromFile();
3608 string aMeshName = prepareMeshNameAndGroups(file, true);
3609 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3610 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3611 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3615 //================================================================================
3617 * \brief Export a mesh to a DAT file
3619 //================================================================================
3621 void SMESH_Mesh_i::ExportDAT (const char *file)
3622 throw(SALOME::SALOME_Exception)
3624 Unexpect aCatch(SALOME_SalomeException);
3626 _preMeshInfo->FullLoadFromFile();
3628 // Update Python script
3629 // check names of groups
3631 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3634 PrepareForWriting(file);
3635 _impl->ExportDAT(file);
3638 //================================================================================
3640 * \brief Export a mesh to an UNV file
3642 //================================================================================
3644 void SMESH_Mesh_i::ExportUNV (const char *file)
3645 throw(SALOME::SALOME_Exception)
3647 Unexpect aCatch(SALOME_SalomeException);
3649 _preMeshInfo->FullLoadFromFile();
3651 // Update Python script
3652 // check names of groups
3654 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3657 PrepareForWriting(file);
3658 _impl->ExportUNV(file);
3661 //================================================================================
3663 * \brief Export a mesh to an STL file
3665 //================================================================================
3667 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3668 throw(SALOME::SALOME_Exception)
3670 Unexpect aCatch(SALOME_SalomeException);
3672 _preMeshInfo->FullLoadFromFile();
3674 // Update Python script
3675 // check names of groups
3677 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3678 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3680 CORBA::String_var name;
3681 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3682 if ( !so->_is_nil() )
3683 name = so->GetName();
3686 PrepareForWriting( file );
3687 _impl->ExportSTL( file, isascii, name.in() );
3690 //================================================================================
3692 * \brief Export a part of mesh to a med file
3694 //================================================================================
3696 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3698 CORBA::Boolean auto_groups,
3699 CORBA::Long version,
3700 CORBA::Boolean overwrite,
3701 CORBA::Boolean autoDimension,
3702 const GEOM::ListOfFields& fields,
3703 const char* geomAssocFields,
3704 CORBA::Double ZTolerance)
3705 throw (SALOME::SALOME_Exception)
3707 MESSAGE("MED version: "<< version);
3710 _preMeshInfo->FullLoadFromFile();
3713 bool have0dField = false;
3714 if ( fields.length() > 0 )
3716 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3717 if ( shapeToMesh->_is_nil() )
3718 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3720 for ( size_t i = 0; i < fields.length(); ++i )
3722 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3723 THROW_SALOME_CORBA_EXCEPTION
3724 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3725 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3726 if ( fieldShape->_is_nil() )
3727 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3728 if ( !fieldShape->IsSame( shapeToMesh ) )
3729 THROW_SALOME_CORBA_EXCEPTION
3730 ( "Field defined not on shape", SALOME::BAD_PARAM);
3731 if ( fields[i]->GetDimension() == 0 )
3734 if ( geomAssocFields )
3735 for ( int i = 0; geomAssocFields[i]; ++i )
3736 switch ( geomAssocFields[i] ) {
3737 case 'v':case 'e':case 'f':case 's': break;
3738 case 'V':case 'E':case 'F':case 'S': break;
3739 default: THROW_SALOME_CORBA_EXCEPTION
3740 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3744 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3748 string aMeshName = "Mesh";
3749 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3750 if ( CORBA::is_nil( meshPart ) ||
3751 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3753 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3754 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3755 0, autoDimension, /*addODOnVertices=*/have0dField,
3757 meshDS = _impl->GetMeshDS();
3762 _preMeshInfo->FullLoadFromFile();
3764 PrepareForWriting(file, overwrite);
3766 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3767 if ( !SO->_is_nil() ) {
3768 CORBA::String_var name = SO->GetName();
3772 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3773 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3774 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3775 meshDS = tmpDSDeleter._obj = partDS;
3780 if ( _impl->HasShapeToMesh() )
3782 DriverMED_W_Field fieldWriter;
3783 fieldWriter.SetFile( file );
3784 fieldWriter.SetMeshName( aMeshName );
3785 fieldWriter.AddODOnVertices( have0dField );
3787 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3791 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3792 goList->length( fields.length() );
3793 for ( size_t i = 0; i < fields.length(); ++i )
3795 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3798 TPythonDump() << _this() << ".ExportPartToMED( "
3799 << meshPart << ", r'"
3801 << auto_groups << ", "
3803 << overwrite << ", "
3804 << autoDimension << ", "
3806 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3807 << TVar( ZTolerance )
3810 SMESH_CATCH( SMESH::throwCorbaException );
3813 //================================================================================
3815 * Write GEOM fields to MED file
3817 //================================================================================
3819 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3820 SMESHDS_Mesh* meshDS,
3821 const GEOM::ListOfFields& fields,
3822 const char* geomAssocFields)
3824 #define METH "SMESH_Mesh_i::exportMEDFields() "
3826 if (( fields.length() < 1 ) &&
3827 ( !geomAssocFields || !geomAssocFields[0] ))
3830 std::vector< std::vector< double > > dblVals;
3831 std::vector< std::vector< int > > intVals;
3832 std::vector< int > subIdsByDim[ 4 ];
3833 const double noneDblValue = 0.;
3834 const double noneIntValue = 0;
3836 for ( size_t iF = 0; iF < fields.length(); ++iF )
3840 int dim = fields[ iF ]->GetDimension();
3841 SMDSAbs_ElementType elemType;
3842 TopAbs_ShapeEnum shapeType;
3844 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3845 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3846 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3847 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3849 continue; // skip fields on whole shape
3851 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3852 if ( dataType == GEOM::FDT_String )
3854 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3855 if ( stepIDs->length() < 1 )
3857 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3858 if ( comps->length() < 1 )
3860 CORBA::String_var name = fields[ iF ]->GetName();
3862 if ( !fieldWriter.Set( meshDS,
3866 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3869 for ( size_t iC = 0; iC < comps->length(); ++iC )
3870 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3872 dblVals.resize( comps->length() );
3873 intVals.resize( comps->length() );
3875 // find sub-shape IDs
3877 std::vector< int >& subIds = subIdsByDim[ dim ];
3878 if ( subIds.empty() )
3879 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3880 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3881 subIds.push_back( id );
3885 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3889 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3891 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3892 if ( step->_is_nil() )
3895 CORBA::Long stamp = step->GetStamp();
3896 CORBA::Long id = step->GetID();
3897 fieldWriter.SetDtIt( int( stamp ), int( id ));
3899 // fill dblVals or intVals
3900 for ( size_t iC = 0; iC < comps->length(); ++iC )
3901 if ( dataType == GEOM::FDT_Double )
3903 dblVals[ iC ].clear();
3904 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3908 intVals[ iC ].clear();
3909 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3913 case GEOM::FDT_Double:
3915 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3916 if ( dblStep->_is_nil() ) continue;
3917 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3918 if ( vv->length() != subIds.size() * comps->length() )
3919 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3920 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3921 for ( size_t iC = 0; iC < comps->length(); ++iC )
3922 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3927 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3928 if ( intStep->_is_nil() ) continue;
3929 GEOM::ListOfLong_var vv = intStep->GetValues();
3930 if ( vv->length() != subIds.size() * comps->length() )
3931 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3932 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3933 for ( size_t iC = 0; iC < comps->length(); ++iC )
3934 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3937 case GEOM::FDT_Bool:
3939 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3940 if ( boolStep->_is_nil() ) continue;
3941 GEOM::short_array_var vv = boolStep->GetValues();
3942 if ( vv->length() != subIds.size() * comps->length() )
3943 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3944 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3945 for ( size_t iC = 0; iC < comps->length(); ++iC )
3946 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3952 // pass values to fieldWriter
3953 elemIt = fieldWriter.GetOrderedElems();
3954 if ( dataType == GEOM::FDT_Double )
3955 while ( elemIt->more() )
3957 const SMDS_MeshElement* e = elemIt->next();
3958 const int shapeID = e->getshapeId();
3959 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3960 for ( size_t iC = 0; iC < comps->length(); ++iC )
3961 fieldWriter.AddValue( noneDblValue );
3963 for ( size_t iC = 0; iC < comps->length(); ++iC )
3964 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3967 while ( elemIt->more() )
3969 const SMDS_MeshElement* e = elemIt->next();
3970 const int shapeID = e->getshapeId();
3971 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3972 for ( size_t iC = 0; iC < comps->length(); ++iC )
3973 fieldWriter.AddValue( (double) noneIntValue );
3975 for ( size_t iC = 0; iC < comps->length(); ++iC )
3976 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3980 fieldWriter.Perform();
3981 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3982 if ( res && res->IsKO() )
3984 if ( res->myComment.empty() )
3985 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3987 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3993 if ( !geomAssocFields || !geomAssocFields[0] )
3996 // write geomAssocFields
3998 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3999 shapeDim[ TopAbs_COMPOUND ] = 3;
4000 shapeDim[ TopAbs_COMPSOLID ] = 3;
4001 shapeDim[ TopAbs_SOLID ] = 3;
4002 shapeDim[ TopAbs_SHELL ] = 2;
4003 shapeDim[ TopAbs_FACE ] = 2;
4004 shapeDim[ TopAbs_WIRE ] = 1;
4005 shapeDim[ TopAbs_EDGE ] = 1;
4006 shapeDim[ TopAbs_VERTEX ] = 0;
4007 shapeDim[ TopAbs_SHAPE ] = 3;
4009 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4011 std::vector< std::string > compNames;
4012 switch ( geomAssocFields[ iF ]) {
4014 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4015 compNames.push_back( "dim" );
4018 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4021 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4024 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4028 compNames.push_back( "id" );
4029 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4030 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4032 fieldWriter.SetDtIt( -1, -1 );
4034 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4038 if ( compNames.size() == 2 ) // _vertices_
4039 while ( elemIt->more() )
4041 const SMDS_MeshElement* e = elemIt->next();
4042 const int shapeID = e->getshapeId();
4045 fieldWriter.AddValue( (double) -1 );
4046 fieldWriter.AddValue( (double) -1 );
4050 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4051 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4052 fieldWriter.AddValue( (double) shapeID );
4056 while ( elemIt->more() )
4058 const SMDS_MeshElement* e = elemIt->next();
4059 const int shapeID = e->getshapeId();
4061 fieldWriter.AddValue( (double) -1 );
4063 fieldWriter.AddValue( (double) shapeID );
4067 fieldWriter.Perform();
4068 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4069 if ( res && res->IsKO() )
4071 if ( res->myComment.empty() )
4072 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4074 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4077 } // loop on geomAssocFields
4082 //================================================================================
4084 * \brief Export a part of mesh to a DAT file
4086 //================================================================================
4088 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4090 throw (SALOME::SALOME_Exception)
4092 Unexpect aCatch(SALOME_SalomeException);
4094 _preMeshInfo->FullLoadFromFile();
4096 PrepareForWriting(file);
4098 SMESH_MeshPartDS partDS( meshPart );
4099 _impl->ExportDAT(file,&partDS);
4101 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4102 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4104 //================================================================================
4106 * \brief Export a part of mesh to an UNV file
4108 //================================================================================
4110 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4112 throw (SALOME::SALOME_Exception)
4114 Unexpect aCatch(SALOME_SalomeException);
4116 _preMeshInfo->FullLoadFromFile();
4118 PrepareForWriting(file);
4120 SMESH_MeshPartDS partDS( meshPart );
4121 _impl->ExportUNV(file, &partDS);
4123 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4124 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4126 //================================================================================
4128 * \brief Export a part of mesh to an STL file
4130 //================================================================================
4132 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4134 ::CORBA::Boolean isascii)
4135 throw (SALOME::SALOME_Exception)
4137 Unexpect aCatch(SALOME_SalomeException);
4139 _preMeshInfo->FullLoadFromFile();
4141 PrepareForWriting(file);
4143 CORBA::String_var name;
4144 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4145 if ( !so->_is_nil() )
4146 name = so->GetName();
4148 SMESH_MeshPartDS partDS( meshPart );
4149 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4151 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4152 << meshPart<< ", r'" << file << "', " << isascii << ")";
4155 //================================================================================
4157 * \brief Export a part of mesh to an STL file
4159 //================================================================================
4161 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4163 CORBA::Boolean overwrite,
4164 CORBA::Boolean groupElemsByType)
4165 throw (SALOME::SALOME_Exception)
4168 Unexpect aCatch(SALOME_SalomeException);
4170 _preMeshInfo->FullLoadFromFile();
4172 PrepareForWriting(file,overwrite);
4174 std::string meshName("");
4175 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4176 if ( !so->_is_nil() )
4178 CORBA::String_var name = so->GetName();
4179 meshName = name.in();
4183 SMESH_MeshPartDS partDS( meshPart );
4184 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4186 SMESH_CATCH( SMESH::throwCorbaException );
4188 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4189 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4191 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4195 //================================================================================
4197 * \brief Export a part of mesh to a GMF file
4199 //================================================================================
4201 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4203 bool withRequiredGroups)
4204 throw (SALOME::SALOME_Exception)
4206 Unexpect aCatch(SALOME_SalomeException);
4208 _preMeshInfo->FullLoadFromFile();
4210 PrepareForWriting(file,/*overwrite=*/true);
4212 SMESH_MeshPartDS partDS( meshPart );
4213 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4215 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4216 << meshPart<< ", r'"
4218 << withRequiredGroups << ")";
4221 //=============================================================================
4223 * Return computation progress [0.,1]
4225 //=============================================================================
4227 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4231 return _impl->GetComputeProgress();
4233 SMESH_CATCH( SMESH::doNothing );
4237 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4239 Unexpect aCatch(SALOME_SalomeException);
4241 return _preMeshInfo->NbNodes();
4243 return _impl->NbNodes();
4246 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4248 Unexpect aCatch(SALOME_SalomeException);
4250 return _preMeshInfo->NbElements();
4252 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4255 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4257 Unexpect aCatch(SALOME_SalomeException);
4259 return _preMeshInfo->Nb0DElements();
4261 return _impl->Nb0DElements();
4264 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4266 Unexpect aCatch(SALOME_SalomeException);
4268 return _preMeshInfo->NbBalls();
4270 return _impl->NbBalls();
4273 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4275 Unexpect aCatch(SALOME_SalomeException);
4277 return _preMeshInfo->NbEdges();
4279 return _impl->NbEdges();
4282 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4283 throw(SALOME::SALOME_Exception)
4285 Unexpect aCatch(SALOME_SalomeException);
4287 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4289 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4292 //=============================================================================
4294 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4296 Unexpect aCatch(SALOME_SalomeException);
4298 return _preMeshInfo->NbFaces();
4300 return _impl->NbFaces();
4303 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4305 Unexpect aCatch(SALOME_SalomeException);
4307 return _preMeshInfo->NbTriangles();
4309 return _impl->NbTriangles();
4312 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4314 Unexpect aCatch(SALOME_SalomeException);
4316 return _preMeshInfo->NbBiQuadTriangles();
4318 return _impl->NbBiQuadTriangles();
4321 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4323 Unexpect aCatch(SALOME_SalomeException);
4325 return _preMeshInfo->NbQuadrangles();
4327 return _impl->NbQuadrangles();
4330 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4332 Unexpect aCatch(SALOME_SalomeException);
4334 return _preMeshInfo->NbBiQuadQuadrangles();
4336 return _impl->NbBiQuadQuadrangles();
4339 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4341 Unexpect aCatch(SALOME_SalomeException);
4343 return _preMeshInfo->NbPolygons();
4345 return _impl->NbPolygons();
4348 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4350 Unexpect aCatch(SALOME_SalomeException);
4352 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4354 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4357 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4358 throw(SALOME::SALOME_Exception)
4360 Unexpect aCatch(SALOME_SalomeException);
4362 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4364 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4367 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4368 throw(SALOME::SALOME_Exception)
4370 Unexpect aCatch(SALOME_SalomeException);
4372 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4374 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4377 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4378 throw(SALOME::SALOME_Exception)
4380 Unexpect aCatch(SALOME_SalomeException);
4382 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4384 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4387 //=============================================================================
4389 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4391 Unexpect aCatch(SALOME_SalomeException);
4393 return _preMeshInfo->NbVolumes();
4395 return _impl->NbVolumes();
4398 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4400 Unexpect aCatch(SALOME_SalomeException);
4402 return _preMeshInfo->NbTetras();
4404 return _impl->NbTetras();
4407 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4409 Unexpect aCatch(SALOME_SalomeException);
4411 return _preMeshInfo->NbHexas();
4413 return _impl->NbHexas();
4416 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4418 Unexpect aCatch(SALOME_SalomeException);
4420 return _preMeshInfo->NbTriQuadHexas();
4422 return _impl->NbTriQuadraticHexas();
4425 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4427 Unexpect aCatch(SALOME_SalomeException);
4429 return _preMeshInfo->NbPyramids();
4431 return _impl->NbPyramids();
4434 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4436 Unexpect aCatch(SALOME_SalomeException);
4438 return _preMeshInfo->NbPrisms();
4440 return _impl->NbPrisms();
4443 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4445 Unexpect aCatch(SALOME_SalomeException);
4447 return _preMeshInfo->NbHexPrisms();
4449 return _impl->NbHexagonalPrisms();
4452 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4454 Unexpect aCatch(SALOME_SalomeException);
4456 return _preMeshInfo->NbPolyhedrons();
4458 return _impl->NbPolyhedrons();
4461 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4462 throw(SALOME::SALOME_Exception)
4464 Unexpect aCatch(SALOME_SalomeException);
4466 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4468 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4471 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4472 throw(SALOME::SALOME_Exception)
4474 Unexpect aCatch(SALOME_SalomeException);
4476 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4478 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4481 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4482 throw(SALOME::SALOME_Exception)
4484 Unexpect aCatch(SALOME_SalomeException);
4486 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4488 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4491 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4492 throw(SALOME::SALOME_Exception)
4494 Unexpect aCatch(SALOME_SalomeException);
4496 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4498 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4501 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4502 throw(SALOME::SALOME_Exception)
4504 Unexpect aCatch(SALOME_SalomeException);
4506 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4508 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4511 //=============================================================================
4513 * Returns nb of published sub-meshes
4515 //=============================================================================
4517 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4519 Unexpect aCatch(SALOME_SalomeException);
4520 return _mapSubMesh_i.size();
4523 //=============================================================================
4525 * Dumps mesh into a string
4527 //=============================================================================
4529 char* SMESH_Mesh_i::Dump()
4533 return CORBA::string_dup( os.str().c_str() );
4536 //=============================================================================
4538 * Method of SMESH_IDSource interface
4540 //=============================================================================
4542 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4544 return GetElementsId();
4547 //=============================================================================
4549 * Returns ids of all elements
4551 //=============================================================================
4553 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4554 throw (SALOME::SALOME_Exception)
4556 Unexpect aCatch(SALOME_SalomeException);
4558 _preMeshInfo->FullLoadFromFile();
4560 SMESH::long_array_var aResult = new SMESH::long_array();
4561 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4563 if ( aSMESHDS_Mesh == NULL )
4564 return aResult._retn();
4566 long nbElements = NbElements();
4567 aResult->length( nbElements );
4568 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4569 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4570 aResult[i] = anIt->next()->GetID();
4572 return aResult._retn();
4576 //=============================================================================
4578 * Returns ids of all elements of given type
4580 //=============================================================================
4582 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4583 throw (SALOME::SALOME_Exception)
4585 Unexpect aCatch(SALOME_SalomeException);
4587 _preMeshInfo->FullLoadFromFile();
4589 SMESH::long_array_var aResult = new SMESH::long_array();
4590 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4592 if ( aSMESHDS_Mesh == NULL )
4593 return aResult._retn();
4595 long nbElements = NbElements();
4597 // No sense in returning ids of elements along with ids of nodes:
4598 // when theElemType == SMESH::ALL, return node ids only if
4599 // there are no elements
4600 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4601 return GetNodesId();
4603 aResult->length( nbElements );
4607 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4608 while ( i < nbElements && anIt->more() )
4609 aResult[i++] = anIt->next()->GetID();
4611 aResult->length( i );
4613 return aResult._retn();
4616 //=============================================================================
4618 * Returns ids of all nodes
4620 //=============================================================================
4622 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4623 throw (SALOME::SALOME_Exception)
4625 Unexpect aCatch(SALOME_SalomeException);
4627 _preMeshInfo->FullLoadFromFile();
4629 SMESH::long_array_var aResult = new SMESH::long_array();
4630 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4632 if ( aMeshDS == NULL )
4633 return aResult._retn();
4635 long nbNodes = NbNodes();
4636 aResult->length( nbNodes );
4637 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4638 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4639 aResult[i] = anIt->next()->GetID();
4641 return aResult._retn();
4644 //=============================================================================
4648 //=============================================================================
4650 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4651 throw (SALOME::SALOME_Exception)
4653 SMESH::ElementType type = SMESH::ALL;
4657 _preMeshInfo->FullLoadFromFile();
4659 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4661 SMESH_CATCH( SMESH::throwCorbaException );
4666 //=============================================================================
4670 //=============================================================================
4672 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4673 throw (SALOME::SALOME_Exception)
4676 _preMeshInfo->FullLoadFromFile();
4678 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4680 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4682 return ( SMESH::EntityType ) e->GetEntityType();
4685 //=============================================================================
4689 //=============================================================================
4691 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4692 throw (SALOME::SALOME_Exception)
4695 _preMeshInfo->FullLoadFromFile();
4697 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4699 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4701 return ( SMESH::GeometryType ) e->GetGeomType();
4704 //=============================================================================
4706 * Returns ID of elements for given submesh
4708 //=============================================================================
4709 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4710 throw (SALOME::SALOME_Exception)
4712 SMESH::long_array_var aResult = new SMESH::long_array();
4716 _preMeshInfo->FullLoadFromFile();
4718 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4719 if(!SM) return aResult._retn();
4721 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4722 if(!SDSM) return aResult._retn();
4724 aResult->length(SDSM->NbElements());
4726 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4728 while ( eIt->more() ) {
4729 aResult[i++] = eIt->next()->GetID();
4732 SMESH_CATCH( SMESH::throwCorbaException );
4734 return aResult._retn();
4737 //=============================================================================
4739 * Returns ID of nodes for given submesh
4740 * If param all==true - returns all nodes, else -
4741 * returns only nodes on shapes.
4743 //=============================================================================
4745 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4747 throw (SALOME::SALOME_Exception)
4749 SMESH::long_array_var aResult = new SMESH::long_array();
4753 _preMeshInfo->FullLoadFromFile();
4755 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4756 if(!SM) return aResult._retn();
4758 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4759 if(!SDSM) return aResult._retn();
4762 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4763 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4764 while ( nIt->more() ) {
4765 const SMDS_MeshNode* elem = nIt->next();
4766 theElems.insert( elem->GetID() );
4769 else { // all nodes of submesh elements
4770 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4771 while ( eIt->more() ) {
4772 const SMDS_MeshElement* anElem = eIt->next();
4773 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4774 while ( nIt->more() ) {
4775 const SMDS_MeshElement* elem = nIt->next();
4776 theElems.insert( elem->GetID() );
4781 aResult->length(theElems.size());
4782 set<int>::iterator itElem;
4784 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4785 aResult[i++] = *itElem;
4787 SMESH_CATCH( SMESH::throwCorbaException );
4789 return aResult._retn();
4792 //=============================================================================
4794 * Returns type of elements for given submesh
4796 //=============================================================================
4798 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4799 throw (SALOME::SALOME_Exception)
4801 SMESH::ElementType type = SMESH::ALL;
4805 _preMeshInfo->FullLoadFromFile();
4807 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4808 if(!SM) return SMESH::ALL;
4810 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4811 if(!SDSM) return SMESH::ALL;
4813 if(SDSM->NbElements()==0)
4814 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4816 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4817 const SMDS_MeshElement* anElem = eIt->next();
4819 type = ( SMESH::ElementType ) anElem->GetType();
4821 SMESH_CATCH( SMESH::throwCorbaException );
4827 //=============================================================================
4829 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4831 //=============================================================================
4833 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4836 _preMeshInfo->FullLoadFromFile();
4838 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4839 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4844 //=============================================================================
4846 * Get XYZ coordinates of node as list of double
4847 * If there is not node for given ID - returns empty list
4849 //=============================================================================
4851 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4854 _preMeshInfo->FullLoadFromFile();
4856 SMESH::double_array_var aResult = new SMESH::double_array();
4857 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4858 if ( aMeshDS == NULL )
4859 return aResult._retn();
4862 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4864 return aResult._retn();
4868 aResult[0] = aNode->X();
4869 aResult[1] = aNode->Y();
4870 aResult[2] = aNode->Z();
4871 return aResult._retn();
4875 //=============================================================================
4877 * For given node returns list of IDs of inverse elements
4878 * If there is not node for given ID - returns empty list
4880 //=============================================================================
4882 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4883 SMESH::ElementType elemType)
4886 _preMeshInfo->FullLoadFromFile();
4888 SMESH::long_array_var aResult = new SMESH::long_array();
4889 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4890 if ( aMeshDS == NULL )
4891 return aResult._retn();
4894 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4896 return aResult._retn();
4898 // find inverse elements
4899 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4900 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4901 aResult->length( aNode->NbInverseElements( type ));
4902 for( int i = 0; eIt->more(); ++i )
4904 const SMDS_MeshElement* elem = eIt->next();
4905 aResult[ i ] = elem->GetID();
4907 return aResult._retn();
4910 //=============================================================================
4912 * \brief Return position of a node on shape
4914 //=============================================================================
4916 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4919 _preMeshInfo->FullLoadFromFile();
4921 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4922 aNodePosition->shapeID = 0;
4923 aNodePosition->shapeType = GEOM::SHAPE;
4925 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4926 if ( !mesh ) return aNodePosition;
4928 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4930 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4932 aNodePosition->shapeID = aNode->getshapeId();
4933 switch ( pos->GetTypeOfPosition() ) {
4935 aNodePosition->shapeType = GEOM::EDGE;
4936 aNodePosition->params.length(1);
4937 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4939 case SMDS_TOP_FACE: {
4940 SMDS_FacePositionPtr fPos = pos;
4941 aNodePosition->shapeType = GEOM::FACE;
4942 aNodePosition->params.length(2);
4943 aNodePosition->params[0] = fPos->GetUParameter();
4944 aNodePosition->params[1] = fPos->GetVParameter();
4947 case SMDS_TOP_VERTEX:
4948 aNodePosition->shapeType = GEOM::VERTEX;
4950 case SMDS_TOP_3DSPACE:
4951 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4952 aNodePosition->shapeType = GEOM::SOLID;
4953 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4954 aNodePosition->shapeType = GEOM::SHELL;
4960 return aNodePosition;
4963 //=============================================================================
4965 * \brief Return position of an element on shape
4967 //=============================================================================
4969 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4972 _preMeshInfo->FullLoadFromFile();
4974 SMESH::ElementPosition anElementPosition;
4975 anElementPosition.shapeID = 0;
4976 anElementPosition.shapeType = GEOM::SHAPE;
4978 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4979 if ( !mesh ) return anElementPosition;
4981 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4983 anElementPosition.shapeID = anElem->getshapeId();
4984 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4985 if ( !aSp.IsNull() ) {
4986 switch ( aSp.ShapeType() ) {
4988 anElementPosition.shapeType = GEOM::EDGE;
4991 anElementPosition.shapeType = GEOM::FACE;
4994 anElementPosition.shapeType = GEOM::VERTEX;
4997 anElementPosition.shapeType = GEOM::SOLID;
5000 anElementPosition.shapeType = GEOM::SHELL;
5006 return anElementPosition;
5009 //=============================================================================
5011 * If given element is node returns IDs of shape from position
5012 * If there is not node for given ID - returns -1
5014 //=============================================================================
5016 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5019 _preMeshInfo->FullLoadFromFile();
5021 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5022 if ( aMeshDS == NULL )
5026 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5028 return aNode->getshapeId();
5035 //=============================================================================
5037 * For given element returns ID of result shape after
5038 * ::FindShape() from SMESH_MeshEditor
5039 * If there is not element for given ID - returns -1
5041 //=============================================================================
5043 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5046 _preMeshInfo->FullLoadFromFile();
5048 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5049 if ( aMeshDS == NULL )
5052 // try to find element
5053 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5057 ::SMESH_MeshEditor aMeshEditor(_impl);
5058 int index = aMeshEditor.FindShape( elem );
5066 //=============================================================================
5068 * Returns number of nodes for given element
5069 * If there is not element for given ID - returns -1
5071 //=============================================================================
5073 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5076 _preMeshInfo->FullLoadFromFile();
5078 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5079 if ( aMeshDS == NULL ) return -1;
5080 // try to find element
5081 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5082 if(!elem) return -1;
5083 return elem->NbNodes();
5087 //=============================================================================
5089 * Returns ID of node by given index for given element
5090 * If there is not element for given ID - returns -1
5091 * If there is not node for given index - returns -2
5093 //=============================================================================
5095 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5098 _preMeshInfo->FullLoadFromFile();
5100 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5101 if ( aMeshDS == NULL ) return -1;
5102 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5103 if(!elem) return -1;
5104 if( index>=elem->NbNodes() || index<0 ) return -1;
5105 return elem->GetNode(index)->GetID();
5108 //=============================================================================
5110 * Returns IDs of nodes of given element
5112 //=============================================================================
5114 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5117 _preMeshInfo->FullLoadFromFile();
5119 SMESH::long_array_var aResult = new SMESH::long_array();
5120 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5122 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5124 aResult->length( elem->NbNodes() );
5125 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5126 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5127 aResult[ i ] = n->GetID();
5130 return aResult._retn();
5133 //=============================================================================
5135 * Returns true if given node is medium node
5136 * in given quadratic element
5138 //=============================================================================
5140 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5143 _preMeshInfo->FullLoadFromFile();
5145 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5146 if ( aMeshDS == NULL ) return false;
5148 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5149 if(!aNode) return false;
5150 // try to find element
5151 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5152 if(!elem) return false;
5154 return elem->IsMediumNode(aNode);
5158 //=============================================================================
5160 * Returns true if given node is medium node
5161 * in one of quadratic elements
5163 //=============================================================================
5165 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5166 SMESH::ElementType theElemType)
5169 _preMeshInfo->FullLoadFromFile();
5171 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5172 if ( aMeshDS == NULL ) return false;
5175 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5176 if(!aNode) return false;
5178 SMESH_MesherHelper aHelper( *(_impl) );
5180 SMDSAbs_ElementType aType;
5181 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5182 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5183 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5184 else aType = SMDSAbs_All;
5186 return aHelper.IsMedium(aNode,aType);
5190 //=============================================================================
5192 * Returns number of edges for given element
5194 //=============================================================================
5196 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5199 _preMeshInfo->FullLoadFromFile();
5201 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5202 if ( aMeshDS == NULL ) return -1;
5203 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5204 if(!elem) return -1;
5205 return elem->NbEdges();
5209 //=============================================================================
5211 * Returns number of faces for given element
5213 //=============================================================================
5215 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5218 _preMeshInfo->FullLoadFromFile();
5220 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5221 if ( aMeshDS == NULL ) return -1;
5222 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5223 if(!elem) return -1;
5224 return elem->NbFaces();
5227 //=======================================================================
5228 //function : GetElemFaceNodes
5229 //purpose : Returns nodes of given face (counted from zero) for given element.
5230 //=======================================================================
5232 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5233 CORBA::Short faceIndex)
5236 _preMeshInfo->FullLoadFromFile();
5238 SMESH::long_array_var aResult = new SMESH::long_array();
5239 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5241 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5243 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5244 if ( faceIndex < vtool.NbFaces() )
5246 aResult->length( vtool.NbFaceNodes( faceIndex ));
5247 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5248 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5249 aResult[ i ] = nn[ i ]->GetID();
5253 return aResult._retn();
5256 //=======================================================================
5257 //function : GetFaceNormal
5258 //purpose : Returns three components of normal of given mesh face.
5259 //=======================================================================
5261 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5262 CORBA::Boolean normalized)
5265 _preMeshInfo->FullLoadFromFile();
5267 SMESH::double_array_var aResult = new SMESH::double_array();
5269 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5272 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5274 aResult->length( 3 );
5275 aResult[ 0 ] = normal.X();
5276 aResult[ 1 ] = normal.Y();
5277 aResult[ 2 ] = normal.Z();
5280 return aResult._retn();
5283 //=======================================================================
5284 //function : FindElementByNodes
5285 //purpose : Returns an element based on all given nodes.
5286 //=======================================================================
5288 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5291 _preMeshInfo->FullLoadFromFile();
5293 CORBA::Long elemID(0);
5294 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5296 vector< const SMDS_MeshNode * > nn( nodes.length() );
5297 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5298 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5301 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5302 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5303 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5304 _impl->NbVolumes( ORDER_QUADRATIC )))
5305 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5307 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5312 //================================================================================
5314 * \brief Return elements including all given nodes.
5316 //================================================================================
5318 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5319 SMESH::ElementType elemType)
5322 _preMeshInfo->FullLoadFromFile();
5324 SMESH::long_array_var result = new SMESH::long_array();
5326 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5328 vector< const SMDS_MeshNode * > nn( nodes.length() );
5329 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5330 nn[i] = mesh->FindNode( nodes[i] );
5332 std::vector<const SMDS_MeshElement *> elems;
5333 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5334 result->length( elems.size() );
5335 for ( size_t i = 0; i < elems.size(); ++i )
5336 result[i] = elems[i]->GetID();
5338 return result._retn();
5341 //=============================================================================
5343 * Returns true if given element is polygon
5345 //=============================================================================
5347 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5350 _preMeshInfo->FullLoadFromFile();
5352 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5353 if ( aMeshDS == NULL ) return false;
5354 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5355 if(!elem) return false;
5356 return elem->IsPoly();
5360 //=============================================================================
5362 * Returns true if given element is quadratic
5364 //=============================================================================
5366 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5369 _preMeshInfo->FullLoadFromFile();
5371 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5372 if ( aMeshDS == NULL ) return false;
5373 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5374 if(!elem) return false;
5375 return elem->IsQuadratic();
5378 //=============================================================================
5380 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5382 //=============================================================================
5384 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5387 _preMeshInfo->FullLoadFromFile();
5389 if ( const SMDS_BallElement* ball =
5390 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5391 return ball->GetDiameter();
5396 //=============================================================================
5398 * Returns bary center for given element
5400 //=============================================================================
5402 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5405 _preMeshInfo->FullLoadFromFile();
5407 SMESH::double_array_var aResult = new SMESH::double_array();
5408 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5409 if ( aMeshDS == NULL )
5410 return aResult._retn();
5412 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5414 return aResult._retn();
5416 if(elem->GetType()==SMDSAbs_Volume) {
5417 SMDS_VolumeTool aTool;
5418 if(aTool.Set(elem)) {
5420 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5425 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5427 double x=0., y=0., z=0.;
5428 for(; anIt->more(); ) {
5430 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5444 return aResult._retn();
5447 //================================================================================
5449 * \brief Create a group of elements preventing computation of a sub-shape
5451 //================================================================================
5453 SMESH::ListOfGroups*
5454 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5455 const char* theGroupName )
5456 throw ( SALOME::SALOME_Exception )
5458 Unexpect aCatch(SALOME_SalomeException);
5460 if ( !theGroupName || strlen( theGroupName) == 0 )
5461 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5463 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5464 ::SMESH_MeshEditor::ElemFeatures elemType;
5466 // submesh by subshape id
5467 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5468 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5471 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5472 if ( error && error->HasBadElems() )
5474 // sort bad elements by type
5475 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5476 const list<const SMDS_MeshElement*>& badElems =
5477 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5478 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5479 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5480 for ( ; elemIt != elemEnd; ++elemIt )
5482 const SMDS_MeshElement* elem = *elemIt;
5483 if ( !elem ) continue;
5485 if ( elem->GetID() < 1 )
5487 // elem is a temporary element, make a real element
5488 vector< const SMDS_MeshNode* > nodes;
5489 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5490 while ( nIt->more() && elem )
5492 nodes.push_back( nIt->next() );
5493 if ( nodes.back()->GetID() < 1 )
5494 elem = 0; // a temporary element on temporary nodes
5498 ::SMESH_MeshEditor editor( _impl );
5499 elem = editor.AddElement( nodes, elemType.Init( elem ));
5503 elemsByType[ elem->GetType() ].push_back( elem );
5506 // how many groups to create?
5508 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5509 nbTypes += int( !elemsByType[ i ].empty() );
5510 groups->length( nbTypes );
5513 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5515 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5516 if ( elems.empty() ) continue;
5518 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5519 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5521 SMESH::SMESH_Mesh_var mesh = _this();
5522 SALOMEDS::SObject_wrap aSO =
5523 _gen_i->PublishGroup( mesh, groups[ iG ],
5524 GEOM::GEOM_Object::_nil(), theGroupName);
5526 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5527 if ( !grp_i ) continue;
5529 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5530 for ( size_t iE = 0; iE < elems.size(); ++iE )
5531 grpDS->SMDSGroup().Add( elems[ iE ]);
5536 return groups._retn();
5539 //=============================================================================
5541 * Create and publish group servants if any groups were imported or created anyhow
5543 //=============================================================================
5545 void SMESH_Mesh_i::CreateGroupServants()
5547 SMESH::SMESH_Mesh_var aMesh = _this();
5550 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5551 while ( groupIt->more() )
5553 ::SMESH_Group* group = groupIt->next();
5554 int anId = group->GetID();
5556 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5557 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5559 addedIDs.insert( anId );
5561 SMESH_GroupBase_i* aGroupImpl;
5563 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5564 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5566 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5567 shape = groupOnGeom->GetShape();
5570 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5573 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5574 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5575 aGroupImpl->Register();
5577 // register CORBA object for persistence
5578 int nextId = _gen_i->RegisterObject( groupVar );
5579 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5580 else { nextId = 0; } // avoid "unused variable" warning in release mode
5582 // publishing the groups in the study
5583 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5584 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5586 if ( !addedIDs.empty() )
5589 set<int>::iterator id = addedIDs.begin();
5590 for ( ; id != addedIDs.end(); ++id )
5592 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5593 int i = std::distance( _mapGroups.begin(), it );
5594 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5599 //=============================================================================
5601 * \brief Return true if all sub-meshes are computed OK - to update an icon
5603 //=============================================================================
5605 bool SMESH_Mesh_i::IsComputedOK()
5607 return _impl->IsComputedOK();
5610 //=============================================================================
5612 * \brief Return groups cantained in _mapGroups by their IDs
5614 //=============================================================================
5616 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5618 int nbGroups = groupIDs.size();
5619 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5620 aList->length( nbGroups );
5622 list<int>::const_iterator ids = groupIDs.begin();
5623 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5625 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5626 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5627 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5629 aList->length( nbGroups );
5630 return aList._retn();
5633 //=============================================================================
5635 * \brief Return information about imported file
5637 //=============================================================================
5639 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5641 SMESH::MedFileInfo_var res( _medFileInfo );
5642 if ( !res.operator->() ) {
5643 res = new SMESH::MedFileInfo;
5645 res->fileSize = res->major = res->minor = res->release = -1;
5650 //=======================================================================
5651 //function : FileInfoToString
5652 //purpose : Persistence of file info
5653 //=======================================================================
5655 std::string SMESH_Mesh_i::FileInfoToString()
5658 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5660 s = SMESH_Comment( _medFileInfo->fileSize )
5661 << " " << _medFileInfo->major
5662 << " " << _medFileInfo->minor
5663 << " " << _medFileInfo->release
5664 << " " << _medFileInfo->fileName;
5669 //=======================================================================
5670 //function : FileInfoFromString
5671 //purpose : Persistence of file info
5672 //=======================================================================
5674 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5676 std::string size, major, minor, release, fileName;
5677 std::istringstream is(info);
5678 is >> size >> major >> minor >> release;
5679 fileName = info.data() + ( size.size() + 1 +
5682 release.size()+ 1 );
5684 _medFileInfo = new SMESH::MedFileInfo();
5685 _medFileInfo->fileName = fileName.c_str();
5686 _medFileInfo->fileSize = atoi( size.c_str() );
5687 _medFileInfo->major = atoi( major.c_str() );
5688 _medFileInfo->minor = atoi( minor.c_str() );
5689 _medFileInfo->release = atoi( release.c_str() );
5692 //=============================================================================
5694 * \brief Pass names of mesh groups from study to mesh DS
5696 //=============================================================================
5698 void SMESH_Mesh_i::checkGroupNames()
5700 int nbGrp = NbGroups();
5704 SMESH::ListOfGroups* grpList = 0;
5705 // avoid dump of "GetGroups"
5707 // store python dump into a local variable inside local scope
5708 SMESH::TPythonDump pDump; // do not delete this line of code
5709 grpList = GetGroups();
5712 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5713 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5716 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5717 if ( aGrpSO->_is_nil() )
5719 // correct name of the mesh group if necessary
5720 const char* guiName = aGrpSO->GetName();
5721 if ( strcmp(guiName, aGrp->GetName()) )
5722 aGrp->SetName( guiName );
5726 //=============================================================================
5728 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5730 //=============================================================================
5731 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5733 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5737 //=============================================================================
5739 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5741 //=============================================================================
5743 char* SMESH_Mesh_i::GetParameters()
5745 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5748 //=============================================================================
5750 * \brief Returns list of notebook variables used for last Mesh operation
5752 //=============================================================================
5753 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5755 SMESH::string_array_var aResult = new SMESH::string_array();
5756 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5758 CORBA::String_var aParameters = GetParameters();
5759 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5760 if ( aSections->length() > 0 ) {
5761 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5762 aResult->length( aVars.length() );
5763 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5764 aResult[i] = CORBA::string_dup( aVars[i] );
5767 return aResult._retn();
5770 //=======================================================================
5771 //function : GetTypes
5772 //purpose : Returns types of elements it contains
5773 //=======================================================================
5775 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5778 return _preMeshInfo->GetTypes();
5780 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5784 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5785 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5786 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5787 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5788 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5789 if (_impl->NbNodes() &&
5790 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5791 types->length( nbTypes );
5793 return types._retn();
5796 //=======================================================================
5797 //function : GetMesh
5798 //purpose : Returns self
5799 //=======================================================================
5801 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5803 return SMESH::SMESH_Mesh::_duplicate( _this() );
5806 //=======================================================================
5807 //function : IsMeshInfoCorrect
5808 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5809 // * happen if mesh data is not yet fully loaded from the file of study.
5810 //=======================================================================
5812 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5814 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5817 //=============================================================================
5819 * \brief Returns number of mesh elements per each \a EntityType
5821 //=============================================================================
5823 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5826 return _preMeshInfo->GetMeshInfo();
5828 SMESH::long_array_var aRes = new SMESH::long_array();
5829 aRes->length(SMESH::Entity_Last);
5830 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5832 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5834 return aRes._retn();
5835 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5836 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5837 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5838 return aRes._retn();
5841 //=============================================================================
5843 * \brief Returns number of mesh elements per each \a ElementType
5845 //=============================================================================
5847 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5849 SMESH::long_array_var aRes = new SMESH::long_array();
5850 aRes->length(SMESH::NB_ELEMENT_TYPES);
5851 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5854 const SMDS_MeshInfo* meshInfo = 0;
5856 meshInfo = _preMeshInfo;
5857 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5858 meshInfo = & meshDS->GetMeshInfo();
5861 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5862 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5864 return aRes._retn();
5867 //=============================================================================
5869 * Collect statistic of mesh elements given by iterator
5871 //=============================================================================
5873 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5874 SMESH::long_array& theInfo)
5876 if (!theItr) return;
5877 while (theItr->more())
5878 theInfo[ theItr->next()->GetEntityType() ]++;
5880 //=============================================================================
5882 * Returns mesh unstructed grid information.
5884 //=============================================================================
5886 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5888 SALOMEDS::TMPFile_var SeqFile;
5889 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5890 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5892 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5893 aWriter->WriteToOutputStringOn();
5894 aWriter->SetInputData(aGrid);
5895 aWriter->SetFileTypeToBinary();
5897 char* str = aWriter->GetOutputString();
5898 int size = aWriter->GetOutputStringLength();
5900 //Allocate octet buffer of required size
5901 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5902 //Copy ostrstream content to the octet buffer
5903 memcpy(OctetBuf, str, size);
5904 //Create and return TMPFile
5905 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5909 return SeqFile._retn();
5912 //=============================================================================
5913 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5914 * SMESH::ElementType type) */
5916 using namespace SMESH::Controls;
5917 //-----------------------------------------------------------------------------
5918 struct PredicateIterator : public SMDS_ElemIterator
5920 SMDS_ElemIteratorPtr _elemIter;
5921 PredicatePtr _predicate;
5922 const SMDS_MeshElement* _elem;
5923 SMDSAbs_ElementType _type;
5925 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5926 PredicatePtr predicate,
5927 SMDSAbs_ElementType type):
5928 _elemIter(iterator), _predicate(predicate), _type(type)
5936 virtual const SMDS_MeshElement* next()
5938 const SMDS_MeshElement* res = _elem;
5940 while ( _elemIter->more() && !_elem )
5942 if ((_elem = _elemIter->next()) &&
5943 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5944 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5951 //-----------------------------------------------------------------------------
5952 struct IDSourceIterator : public SMDS_ElemIterator
5954 const CORBA::Long* _idPtr;
5955 const CORBA::Long* _idEndPtr;
5956 SMESH::long_array_var _idArray;
5957 const SMDS_Mesh* _mesh;
5958 const SMDSAbs_ElementType _type;
5959 const SMDS_MeshElement* _elem;
5961 IDSourceIterator( const SMDS_Mesh* mesh,
5962 const CORBA::Long* ids,
5964 SMDSAbs_ElementType type):
5965 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5967 if ( _idPtr && nbIds && _mesh )
5970 IDSourceIterator( const SMDS_Mesh* mesh,
5971 SMESH::long_array* idArray,
5972 SMDSAbs_ElementType type):
5973 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5975 if ( idArray && _mesh )
5977 _idPtr = &_idArray[0];
5978 _idEndPtr = _idPtr + _idArray->length();
5986 virtual const SMDS_MeshElement* next()
5988 const SMDS_MeshElement* res = _elem;
5990 while ( _idPtr < _idEndPtr && !_elem )
5992 if ( _type == SMDSAbs_Node )
5994 _elem = _mesh->FindNode( *_idPtr++ );
5996 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5997 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6005 //-----------------------------------------------------------------------------
6007 struct NodeOfElemIterator : public SMDS_ElemIterator
6009 TColStd_MapOfInteger _checkedNodeIDs;
6010 SMDS_ElemIteratorPtr _elemIter;
6011 SMDS_ElemIteratorPtr _nodeIter;
6012 const SMDS_MeshElement* _node;
6014 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6016 if ( _elemIter && _elemIter->more() )
6018 _nodeIter = _elemIter->next()->nodesIterator();
6026 virtual const SMDS_MeshElement* next()
6028 const SMDS_MeshElement* res = _node;
6030 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6032 if ( _nodeIter->more() )
6034 _node = _nodeIter->next();
6035 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6040 _nodeIter = _elemIter->next()->nodesIterator();
6048 //=============================================================================
6050 * Return iterator on elements of given type in given object
6052 //=============================================================================
6054 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6055 SMESH::ElementType theType)
6057 SMDS_ElemIteratorPtr elemIt;
6058 bool typeOK = ( theType == SMESH::ALL );
6059 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6061 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6062 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6063 if ( !mesh_i ) return elemIt;
6064 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6066 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6068 elemIt = meshDS->elementsIterator( elemType );
6071 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6073 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6076 elemIt = sm->GetElements();
6077 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6079 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6080 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6084 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6086 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6087 if ( groupDS && ( elemType == groupDS->GetType() ||
6088 elemType == SMDSAbs_Node ||
6089 elemType == SMDSAbs_All ))
6091 elemIt = groupDS->GetElements();
6092 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6095 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6097 if ( filter_i->GetElementType() == theType ||
6098 filter_i->GetElementType() == SMESH::ALL ||
6099 elemType == SMDSAbs_Node ||
6100 elemType == SMDSAbs_All)
6102 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6103 if ( pred_i && pred_i->GetPredicate() )
6105 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6106 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6107 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6108 elemIt = SMDS_ElemIteratorPtr
6109 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6110 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6116 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6117 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6118 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6120 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6121 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6124 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6125 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6129 SMESH::long_array_var ids = theObject->GetIDs();
6130 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6132 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6135 if ( elemIt && elemIt->more() && !typeOK )
6137 if ( elemType == SMDSAbs_Node )
6139 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6143 elemIt = SMDS_ElemIteratorPtr();
6149 //=============================================================================
6150 namespace // Finding concurrent hypotheses
6151 //=============================================================================
6155 * \brief mapping of mesh dimension into shape type
6157 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6159 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6161 case 0: aType = TopAbs_VERTEX; break;
6162 case 1: aType = TopAbs_EDGE; break;
6163 case 2: aType = TopAbs_FACE; break;
6165 default:aType = TopAbs_SOLID; break;
6170 //-----------------------------------------------------------------------------
6172 * \brief Internal structure used to find concurrent submeshes
6174 * It represents a pair < submesh, concurrent dimension >, where
6175 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6176 * with another submesh. In other words, it is dimension of a hypothesis assigned
6183 int _dim; //!< a dimension the algo can build (concurrent dimension)
6184 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6185 TopTools_MapOfShape _shapeMap;
6186 SMESH_subMesh* _subMesh;
6187 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6189 //-----------------------------------------------------------------------------
6190 // Return the algorithm
6191 const SMESH_Algo* GetAlgo() const
6192 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6194 //-----------------------------------------------------------------------------
6196 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6198 const TopoDS_Shape& theShape)
6200 _subMesh = (SMESH_subMesh*)theSubMesh;
6201 SetShape( theDim, theShape );
6204 //-----------------------------------------------------------------------------
6206 void SetShape(const int theDim,
6207 const TopoDS_Shape& theShape)
6210 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6211 if (_dim >= _ownDim)
6212 _shapeMap.Add( theShape );
6214 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6215 for( ; anExp.More(); anExp.Next() )
6216 _shapeMap.Add( anExp.Current() );
6220 //-----------------------------------------------------------------------------
6221 //! Check sharing of sub-shapes
6222 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6223 const TopTools_MapOfShape& theToFind,
6224 const TopAbs_ShapeEnum theType)
6226 bool isShared = false;
6227 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6228 for (; !isShared && anItr.More(); anItr.Next() )
6230 const TopoDS_Shape aSubSh = anItr.Key();
6231 // check for case when concurrent dimensions are same
6232 isShared = theToFind.Contains( aSubSh );
6233 // check for sub-shape with concurrent dimension
6234 TopExp_Explorer anExp( aSubSh, theType );
6235 for ( ; !isShared && anExp.More(); anExp.Next() )
6236 isShared = theToFind.Contains( anExp.Current() );
6241 //-----------------------------------------------------------------------------
6242 //! check algorithms
6243 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6244 const SMESHDS_Hypothesis* theA2)
6246 if ( !theA1 || !theA2 ||
6247 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6248 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6249 return false; // one of the hypothesis is not algorithm
6250 // check algorithm names (should be equal)
6251 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6255 //-----------------------------------------------------------------------------
6256 //! Check if sub-shape hypotheses are concurrent
6257 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6259 if ( _subMesh == theOther->_subMesh )
6260 return false; // same sub-shape - should not be
6262 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6263 // any of the two submeshes is not on COMPOUND shape )
6264 // -> no concurrency
6265 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6266 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6267 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6268 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6269 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6272 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6273 if ( !checkSubShape )
6276 // check algorithms to be same
6277 const SMESH_Algo* a1 = this->GetAlgo();
6278 const SMESH_Algo* a2 = theOther->GetAlgo();
6279 bool isSame = checkAlgo( a1, a2 );
6283 return false; // pb?
6284 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6287 // check hypothesises for concurrence (skip first as algorithm)
6289 // pointers should be same, because it is referened from mesh hypothesis partition
6290 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6291 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6292 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6293 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6295 // the submeshes are concurrent if their algorithms has different parameters
6296 return nbSame != theOther->_hypotheses.size() - 1;
6299 // Return true if algorithm of this SMESH_DimHyp is used if no
6300 // sub-mesh order is imposed by the user
6301 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6303 // NeedDiscreteBoundary() algo has a higher priority
6304 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6305 theOther->GetAlgo()->NeedDiscreteBoundary() )
6306 return !this->GetAlgo()->NeedDiscreteBoundary();
6308 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6311 }; // end of SMESH_DimHyp
6312 //-----------------------------------------------------------------------------
6314 typedef list<const SMESH_DimHyp*> TDimHypList;
6316 //-----------------------------------------------------------------------------
6318 void addDimHypInstance(const int theDim,
6319 const TopoDS_Shape& theShape,
6320 const SMESH_Algo* theAlgo,
6321 const SMESH_subMesh* theSubMesh,
6322 const list <const SMESHDS_Hypothesis*>& theHypList,
6323 TDimHypList* theDimHypListArr )
6325 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6326 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6327 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6328 dimHyp->_hypotheses.push_front(theAlgo);
6329 listOfdimHyp.push_back( dimHyp );
6332 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6333 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6334 theHypList.begin(), theHypList.end() );
6337 //-----------------------------------------------------------------------------
6338 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6339 TDimHypList& theListOfConcurr)
6341 if ( theListOfConcurr.empty() )
6343 theListOfConcurr.push_back( theDimHyp );
6347 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6348 while ( hypIt != theListOfConcurr.end() &&
6349 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6351 theListOfConcurr.insert( hypIt, theDimHyp );
6355 //-----------------------------------------------------------------------------
6356 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6357 const TDimHypList& theListOfDimHyp,
6358 TDimHypList& theListOfConcurrHyp,
6359 set<int>& theSetOfConcurrId )
6361 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6362 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6364 const SMESH_DimHyp* curDimHyp = *rIt;
6365 if ( curDimHyp == theDimHyp )
6366 break; // meet own dimHyp pointer in same dimension
6368 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6369 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6371 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6376 //-----------------------------------------------------------------------------
6377 void unionLists(TListOfInt& theListOfId,
6378 TListOfListOfInt& theListOfListOfId,
6381 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6382 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6384 continue; //skip already treated lists
6385 // check if other list has any same submesh object
6386 TListOfInt& otherListOfId = *it;
6387 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6388 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6391 // union two lists (from source into target)
6392 TListOfInt::iterator it2 = otherListOfId.begin();
6393 for ( ; it2 != otherListOfId.end(); it2++ ) {
6394 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6395 theListOfId.push_back(*it2);
6397 // clear source list
6398 otherListOfId.clear();
6401 //-----------------------------------------------------------------------------
6403 //! free memory allocated for dimension-hypothesis objects
6404 void removeDimHyps( TDimHypList* theArrOfList )
6406 for (int i = 0; i < 4; i++ ) {
6407 TDimHypList& listOfdimHyp = theArrOfList[i];
6408 TDimHypList::const_iterator it = listOfdimHyp.begin();
6409 for ( ; it != listOfdimHyp.end(); it++ )
6414 //-----------------------------------------------------------------------------
6416 * \brief find common submeshes with given submesh
6417 * \param theSubMeshList list of already collected submesh to check
6418 * \param theSubMesh given submesh to intersect with other
6419 * \param theCommonSubMeshes collected common submeshes
6421 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6422 const SMESH_subMesh* theSubMesh,
6423 set<const SMESH_subMesh*>& theCommon )
6427 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6428 for ( ; it != theSubMeshList.end(); it++ )
6429 theSubMesh->FindIntersection( *it, theCommon );
6430 theSubMeshList.push_back( theSubMesh );
6431 //theCommon.insert( theSubMesh );
6434 //-----------------------------------------------------------------------------
6435 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6437 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6438 for ( ; listsIt != smLists.end(); ++listsIt )
6440 const TListOfInt& smIDs = *listsIt;
6441 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6449 //=============================================================================
6451 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6453 //=============================================================================
6455 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6457 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6458 if ( isSubMeshInList( submeshID, anOrder ))
6461 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6462 return isSubMeshInList( submeshID, allConurrent );
6465 //=============================================================================
6467 * \brief Return submesh objects list in meshing order
6469 //=============================================================================
6471 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6473 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6475 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6477 return aResult._retn();
6479 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6480 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6481 anOrder.splice( anOrder.end(), allConurrent );
6484 TListOfListOfInt::iterator listIt = anOrder.begin();
6485 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6486 unionLists( *listIt, anOrder, listIndx + 1 );
6488 // convert submesh ids into interface instances
6489 // and dump command into python
6490 convertMeshOrder( anOrder, aResult, false );
6492 return aResult._retn();
6495 //=============================================================================
6497 * \brief Finds concurrent sub-meshes
6499 //=============================================================================
6501 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6503 TListOfListOfInt anOrder;
6504 ::SMESH_Mesh& mesh = GetImpl();
6506 // collect submeshes and detect concurrent algorithms and hypothesises
6507 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6509 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6510 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6511 ::SMESH_subMesh* sm = (*i_sm).second;
6513 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6515 // list of assigned hypothesises
6516 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6517 // Find out dimensions where the submesh can be concurrent.
6518 // We define the dimensions by algo of each of hypotheses in hypList
6519 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6520 for( ; hypIt != hypList.end(); hypIt++ ) {
6521 SMESH_Algo* anAlgo = 0;
6522 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6523 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6524 // hyp it-self is algo
6525 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6527 // try to find algorithm with help of sub-shapes
6528 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6529 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6530 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6533 continue; // no algorithm assigned to a current submesh
6535 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6536 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6538 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6539 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6540 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6542 } // end iterations on submesh
6544 // iterate on created dimension-hypotheses and check for concurrents
6545 for ( int i = 0; i < 4; i++ ) {
6546 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6547 // check for concurrents in own and other dimensions (step-by-step)
6548 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6549 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6550 const SMESH_DimHyp* dimHyp = *dhIt;
6551 TDimHypList listOfConcurr;
6552 set<int> setOfConcurrIds;
6553 // looking for concurrents and collect into own list
6554 for ( int j = i; j < 4; j++ )
6555 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6556 // check if any concurrents found
6557 if ( listOfConcurr.size() > 0 ) {
6558 // add own submesh to list of concurrent
6559 addInOrderOfPriority( dimHyp, listOfConcurr );
6560 list<int> listOfConcurrIds;
6561 TDimHypList::iterator hypIt = listOfConcurr.begin();
6562 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6563 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6564 anOrder.push_back( listOfConcurrIds );
6569 removeDimHyps(dimHypListArr);
6571 // now, minimize the number of concurrent groups
6572 // Here we assume that lists of submeshes can have same submesh
6573 // in case of multi-dimension algorithms, as result
6574 // list with common submesh has to be united into one list
6576 TListOfListOfInt::iterator listIt = anOrder.begin();
6577 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6578 unionLists( *listIt, anOrder, listIndx + 1 );
6584 //=============================================================================
6586 * \brief Set submesh object order
6587 * \param theSubMeshArray submesh array order
6589 //=============================================================================
6591 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6594 _preMeshInfo->ForgetOrLoad();
6597 ::SMESH_Mesh& mesh = GetImpl();
6599 TPythonDump aPythonDump; // prevent dump of called methods
6600 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6602 TListOfListOfInt subMeshOrder;
6603 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6605 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6606 TListOfInt subMeshIds;
6608 aPythonDump << ", ";
6609 aPythonDump << "[ ";
6610 // Collect subMeshes which should be clear
6611 // do it list-by-list, because modification of submesh order
6612 // take effect between concurrent submeshes only
6613 set<const SMESH_subMesh*> subMeshToClear;
6614 list<const SMESH_subMesh*> subMeshList;
6615 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6617 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6619 aPythonDump << ", ";
6620 aPythonDump << subMesh;
6621 subMeshIds.push_back( subMesh->GetId() );
6622 // detect common parts of submeshes
6623 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6624 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6626 aPythonDump << " ]";
6627 subMeshOrder.push_back( subMeshIds );
6629 // clear collected sub-meshes
6630 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6631 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6632 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6634 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6635 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6636 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6639 aPythonDump << " ])";
6641 mesh.SetMeshOrder( subMeshOrder );
6644 SMESH::SMESH_Mesh_var me = _this();
6645 _gen_i->UpdateIcons( me );
6650 //=============================================================================
6652 * \brief Convert submesh ids into submesh interfaces
6654 //=============================================================================
6656 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6657 SMESH::submesh_array_array& theResOrder,
6658 const bool theIsDump)
6660 int nbSet = theIdsOrder.size();
6661 TPythonDump aPythonDump; // prevent dump of called methods
6663 aPythonDump << "[ ";
6664 theResOrder.length(nbSet);
6665 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6667 for( ; it != theIdsOrder.end(); it++ ) {
6668 // translate submesh identificators into submesh objects
6669 // takeing into account real number of concurrent lists
6670 const TListOfInt& aSubOrder = (*it);
6671 if (!aSubOrder.size())
6674 aPythonDump << "[ ";
6675 // convert shape indices into interfaces
6676 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6677 aResSubSet->length(aSubOrder.size());
6678 TListOfInt::const_iterator subIt = aSubOrder.begin();
6680 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6681 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6683 SMESH::SMESH_subMesh_var subMesh =
6684 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6687 aPythonDump << ", ";
6688 aPythonDump << subMesh;
6690 aResSubSet[ j++ ] = subMesh;
6693 aPythonDump << " ]";
6695 theResOrder[ listIndx++ ] = aResSubSet;
6697 // correct number of lists
6698 theResOrder.length( listIndx );
6701 // finilise python dump
6702 aPythonDump << " ]";
6703 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6707 namespace // utils used by SMESH_MeshPartDS
6710 * \brief Class used to access to protected data of SMDS_MeshInfo
6712 struct TMeshInfo : public SMDS_MeshInfo
6714 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6717 * \brief Element holing its ID only
6719 struct TElemID : public SMDS_LinearEdge
6721 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6725 //================================================================================
6727 // Implementation of SMESH_MeshPartDS
6729 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6730 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6732 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6733 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6736 _meshDS = mesh_i->GetImpl().GetMeshDS();
6738 SetPersistentId( _meshDS->GetPersistentId() );
6740 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6742 // <meshPart> is the whole mesh
6743 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6745 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6746 myGroupSet = _meshDS->GetGroups();
6751 SMESH::long_array_var anIDs = meshPart->GetIDs();
6752 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6753 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6755 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6756 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6757 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6762 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6763 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6764 if ( _elements[ e->GetType() ].insert( e ).second )
6767 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6768 while ( nIt->more() )
6770 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6771 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6778 ShapeToMesh( _meshDS->ShapeToMesh() );
6780 _meshDS = 0; // to enforce iteration on _elements and _nodes
6783 // -------------------------------------------------------------------------------------
6784 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6785 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6788 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6789 for ( ; partIt != meshPart.end(); ++partIt )
6790 if ( const SMDS_MeshElement * e = *partIt )
6791 if ( _elements[ e->GetType() ].insert( e ).second )
6794 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6795 while ( nIt->more() )
6797 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6798 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6804 // -------------------------------------------------------------------------------------
6805 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6807 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6809 TElemID elem( IDelem );
6810 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6811 if ( !_elements[ iType ].empty() )
6813 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6814 if ( it != _elements[ iType ].end() )
6819 // -------------------------------------------------------------------------------------
6820 bool SMESH_MeshPartDS::HasNumerationHoles()
6822 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6824 return ( MinNodeID() != 1 ||
6825 MaxNodeID() != NbNodes() ||
6826 MinElementID() != 1 ||
6827 MaxElementID() != NbElements() );
6829 // -------------------------------------------------------------------------------------
6830 int SMESH_MeshPartDS::MaxNodeID() const
6832 if ( _meshDS ) return _meshDS->MaxNodeID();
6833 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6835 // -------------------------------------------------------------------------------------
6836 int SMESH_MeshPartDS::MinNodeID() const
6838 if ( _meshDS ) return _meshDS->MinNodeID();
6839 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6841 // -------------------------------------------------------------------------------------
6842 int SMESH_MeshPartDS::MaxElementID() const
6844 if ( _meshDS ) return _meshDS->MaxElementID();
6846 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6847 if ( !_elements[ iType ].empty() )
6848 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6851 // -------------------------------------------------------------------------------------
6852 int SMESH_MeshPartDS::MinElementID() const
6854 if ( _meshDS ) return _meshDS->MinElementID();
6856 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6857 if ( !_elements[ iType ].empty() )
6858 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6861 // -------------------------------------------------------------------------------------
6862 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6864 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6866 typedef SMDS_SetIterator
6867 <const SMDS_MeshElement*,
6868 TIDSortedElemSet::const_iterator,
6869 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6870 SMDS_MeshElement::GeomFilter
6873 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6875 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6876 _elements[type].end(),
6877 SMDS_MeshElement::GeomFilter( geomType )));
6879 // -------------------------------------------------------------------------------------
6880 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6882 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6884 typedef SMDS_SetIterator
6885 <const SMDS_MeshElement*,
6886 TIDSortedElemSet::const_iterator,
6887 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6888 SMDS_MeshElement::EntityFilter
6891 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6893 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6894 _elements[type].end(),
6895 SMDS_MeshElement::EntityFilter( entity )));
6897 // -------------------------------------------------------------------------------------
6898 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6900 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6901 if ( type == SMDSAbs_All && !_meshDS )
6903 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6905 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6906 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6908 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6910 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6911 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6913 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6914 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6916 // -------------------------------------------------------------------------------------
6917 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6918 iterType SMESH_MeshPartDS::methName() const \
6920 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6921 return _meshDS ? _meshDS->methName() : iterType \
6922 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6924 // -------------------------------------------------------------------------------------
6925 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6926 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6927 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6928 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6929 #undef _GET_ITER_DEFINE
6931 // END Implementation of SMESH_MeshPartDS
6933 //================================================================================