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);
273 // clear buffer also for sub-groups
274 const std::set<SMESHDS_GroupBase*>& groups = _impl->GetMeshDS()->GetGroups();
275 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
276 for (; g != groups.end(); ++g)
277 if (const SMESHDS_GroupOnGeom* group = dynamic_cast<SMESHDS_GroupOnGeom*>(*g))
279 const TopoDS_Shape& s = group->GetShape();
280 if (geomClient->Find(s, aIOR))
281 geomClient->RemoveShapeFromBuffer(aIOR);
284 // update the reference to theNewGeom (needed for correct execution of a dumped python script)
285 SMESH::SMESH_Mesh_var me = _this();
286 SALOMEDS::SObject_wrap aSO = _gen_i->ObjectToSObject( me );
287 CORBA::String_var entry = theNewGeom->GetStudyEntry();
288 if ( !aSO->_is_nil() )
290 SALOMEDS::SObject_wrap aShapeRefSO;
291 if ( aSO->FindSubObject( _gen_i->GetRefOnShapeTag(), aShapeRefSO.inout() ))
293 SALOMEDS::SObject_wrap aShapeSO = _gen_i->getStudyServant()->FindObjectID( entry );
294 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
295 builder->Addreference( aShapeRefSO, aShapeSO );
299 // re-assign global hypotheses to the new shape
301 CheckGeomModif( true );
303 TPythonDump() << "SHAPERSTUDY.breakLinkForSubElements(salome.ObjectToSObject("
304 << me <<".GetMesh()), " << entry.in() << ")";
306 TPythonDump() << me << ".ReplaceShape( " << entry.in() << " )";
310 //================================================================================
312 * \brief Return false if the mesh is not yet fully loaded from the study file
314 //================================================================================
316 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
318 Unexpect aCatch(SALOME_SalomeException);
319 return !_preMeshInfo;
322 //================================================================================
324 * \brief Load full mesh data from the study file
326 //================================================================================
328 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
330 Unexpect aCatch(SALOME_SalomeException);
332 _preMeshInfo->FullLoadFromFile();
335 //================================================================================
337 * \brief Remove all nodes and elements
339 //================================================================================
341 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
343 Unexpect aCatch(SALOME_SalomeException);
345 _preMeshInfo->ForgetOrLoad(); // load in case if !HasShapeToMesh()
349 //CheckGeomGroupModif(); // issue 20145
351 catch(SALOME_Exception & S_ex) {
352 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
355 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
357 SMESH::SMESH_Mesh_var mesh = _this();
358 _gen_i->UpdateIcons( mesh );
361 //================================================================================
363 * \brief Remove all nodes and elements for indicated shape
365 //================================================================================
367 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
368 throw (SALOME::SALOME_Exception)
370 Unexpect aCatch(SALOME_SalomeException);
372 _preMeshInfo->FullLoadFromFile();
375 _impl->ClearSubMesh( ShapeID );
377 catch(SALOME_Exception & S_ex) {
378 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
380 _impl->GetMeshDS()->Modified();
382 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
385 //=============================================================================
387 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
389 //=============================================================================
391 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
393 SMESH::DriverMED_ReadStatus res;
396 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
397 res = SMESH::DRS_OK; break;
398 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
399 res = SMESH::DRS_EMPTY; break;
400 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
401 res = SMESH::DRS_WARN_RENUMBER; break;
402 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
403 res = SMESH::DRS_WARN_SKIP_ELEM; break;
404 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
405 res = SMESH::DRS_WARN_DESCENDING; break;
406 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
408 res = SMESH::DRS_FAIL; break;
413 //=============================================================================
415 * Convert ::SMESH_ComputeError to SMESH::ComputeError
417 //=============================================================================
419 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
421 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
422 errVar->subShapeID = -1;
423 errVar->hasBadMesh = false;
425 if ( !errorPtr || errorPtr->IsOK() )
427 errVar->code = SMESH::COMPERR_OK;
431 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
432 errVar->comment = errorPtr->myComment.c_str();
434 return errVar._retn();
437 //=============================================================================
441 * Imports mesh data from MED file
443 //=============================================================================
445 SMESH::DriverMED_ReadStatus
446 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
447 throw ( SALOME::SALOME_Exception )
449 Unexpect aCatch(SALOME_SalomeException);
452 status = _impl->MEDToMesh( theFileName, theMeshName );
454 catch( SALOME_Exception& S_ex ) {
455 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
458 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
461 CreateGroupServants();
463 int major, minor, release;
464 major = minor = release = 0;
465 MED::GetMEDVersion(theFileName, major, minor, release);
466 _medFileInfo = new SMESH::MedFileInfo();
467 _medFileInfo->fileName = theFileName;
468 _medFileInfo->fileSize = 0;
469 _medFileInfo->major = major;
470 _medFileInfo->minor = minor;
471 _medFileInfo->release = release;
472 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
474 return ConvertDriverMEDReadStatus(status);
477 //================================================================================
479 * \brief Imports mesh data from the CGNS file
481 //================================================================================
483 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
484 const int theMeshIndex,
485 std::string& theMeshName )
486 throw ( SALOME::SALOME_Exception )
488 Unexpect aCatch(SALOME_SalomeException);
491 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
493 catch( SALOME_Exception& S_ex ) {
494 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
497 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
500 CreateGroupServants();
502 _medFileInfo = new SMESH::MedFileInfo();
503 _medFileInfo->fileName = theFileName;
504 _medFileInfo->major = 0;
505 _medFileInfo->minor = 0;
506 _medFileInfo->release = 0;
507 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
509 return ConvertDriverMEDReadStatus(status);
512 //================================================================================
514 * \brief Return string representation of a MED file version comprising nbDigits
516 //================================================================================
518 char* SMESH_Mesh_i::GetVersionString(CORBA::Long minor, CORBA::Short nbDigits)
520 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(minor,
522 return CORBA::string_dup( ver.c_str() );
525 //================================================================================
527 * Return the list of med versions compatibles for write/append,
528 * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32)
530 //================================================================================
531 SMESH::long_array* SMESH_Mesh_i::GetMEDVersionsCompatibleForAppend()
533 SMESH::long_array_var aResult = new SMESH::long_array();
534 std::vector<int> mvok = MED::GetMEDVersionsAppendCompatible();
535 long nbver = mvok.size();
536 aResult->length( nbver );
537 for ( int i = 0; i < nbver; i++ )
538 aResult[i] = mvok[i];
539 return aResult._retn();
542 //=============================================================================
546 * Imports mesh data from MED file
548 //=============================================================================
550 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
551 throw ( SALOME::SALOME_Exception )
555 // Read mesh with name = <theMeshName> into SMESH_Mesh
556 _impl->UNVToMesh( theFileName );
558 CreateGroupServants();
560 _medFileInfo = new SMESH::MedFileInfo();
561 _medFileInfo->fileName = theFileName;
562 _medFileInfo->major = 0;
563 _medFileInfo->minor = 0;
564 _medFileInfo->release = 0;
565 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
567 SMESH_CATCH( SMESH::throwCorbaException );
572 //=============================================================================
576 * Imports mesh data from STL file
578 //=============================================================================
579 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
580 throw ( SALOME::SALOME_Exception )
584 // Read mesh with name = <theMeshName> into SMESH_Mesh
585 std::string name = _impl->STLToMesh( theFileName );
588 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( _this() );
589 _gen_i->SetName( meshSO, name.c_str() );
591 _medFileInfo = new SMESH::MedFileInfo();
592 _medFileInfo->fileName = theFileName;
593 _medFileInfo->major = 0;
594 _medFileInfo->minor = 0;
595 _medFileInfo->release = 0;
596 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
598 SMESH_CATCH( SMESH::throwCorbaException );
603 //================================================================================
605 * \brief Function used in SMESH_CATCH by ImportGMFFile()
607 //================================================================================
611 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
613 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
617 //================================================================================
619 * \brief Imports data from a GMF file and returns an error description
621 //================================================================================
623 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
624 bool theMakeRequiredGroups )
625 throw (SALOME::SALOME_Exception)
627 SMESH_ComputeErrorPtr error;
630 #define SMESH_CAUGHT error =
633 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
635 _medFileInfo = new SMESH::MedFileInfo();
636 _medFileInfo->fileName = theFileName;
637 _medFileInfo->major = 0;
638 _medFileInfo->minor = 0;
639 _medFileInfo->release = 0;
640 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
642 SMESH_CATCH( exceptionToComputeError );
646 CreateGroupServants();
648 return ConvertComputeError( error );
651 //=============================================================================
655 //=============================================================================
657 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
659 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
660 (SMESH_Hypothesis::Hypothesis_Status theStatus)
663 RETURNCASE( HYP_OK );
664 RETURNCASE( HYP_MISSING );
665 RETURNCASE( HYP_CONCURRENT );
666 RETURNCASE( HYP_BAD_PARAMETER );
667 RETURNCASE( HYP_HIDDEN_ALGO );
668 RETURNCASE( HYP_HIDING_ALGO );
669 RETURNCASE( HYP_UNKNOWN_FATAL );
670 RETURNCASE( HYP_INCOMPATIBLE );
671 RETURNCASE( HYP_NOTCONFORM );
672 RETURNCASE( HYP_ALREADY_EXIST );
673 RETURNCASE( HYP_BAD_DIM );
674 RETURNCASE( HYP_BAD_SUBSHAPE );
675 RETURNCASE( HYP_BAD_GEOMETRY );
676 RETURNCASE( HYP_NEED_SHAPE );
677 RETURNCASE( HYP_INCOMPAT_HYPS );
680 return SMESH::HYP_UNKNOWN_FATAL;
683 //=============================================================================
687 * calls internal addHypothesis() and then adds a reference to <anHyp> under
688 * the SObject actually having a reference to <aSubShape>.
689 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
691 //=============================================================================
693 SMESH::Hypothesis_Status
694 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
695 SMESH::SMESH_Hypothesis_ptr anHyp,
696 CORBA::String_out anErrorText)
697 throw(SALOME::SALOME_Exception)
699 Unexpect aCatch(SALOME_SalomeException);
701 _preMeshInfo->ForgetOrLoad();
703 const int prevNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
706 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
707 anErrorText = error.c_str();
709 SMESH::SMESH_Mesh_var mesh( _this() );
710 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
712 _gen_i->AddHypothesisToShape( mesh, aSubShape, anHyp );
714 int newNbMeshEnt = _impl->NbNodes() + _impl->GetMeshDS()->NbElements();
715 if ( newNbMeshEnt != prevNbMeshEnt )
716 _gen_i->UpdateIcons( mesh );
718 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
720 // Update Python script
721 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
722 << aSubShape << ", " << anHyp << " )";
724 return ConvertHypothesisStatus(status);
727 //=============================================================================
731 //=============================================================================
733 SMESH_Hypothesis::Hypothesis_Status
734 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
735 SMESH::SMESH_Hypothesis_ptr anHyp,
736 std::string* anErrorText)
738 if(MYDEBUG) MESSAGE("addHypothesis");
740 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
741 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
743 if (CORBA::is_nil( anHyp ))
744 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
746 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
749 TopoDS_Shape myLocSubShape;
750 //use PseudoShape in case if mesh has no shape
752 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
754 myLocSubShape = _impl->GetShapeToMesh();
756 const int hypId = anHyp->GetId();
758 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
759 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
761 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
763 // assure there is a corresponding submesh
764 if ( !_impl->IsMainShape( myLocSubShape )) {
765 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
766 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
767 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
770 else if ( anErrorText )
772 *anErrorText = error;
775 catch(SALOME_Exception & S_ex)
777 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
782 //=============================================================================
786 //=============================================================================
788 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
789 SMESH::SMESH_Hypothesis_ptr anHyp)
790 throw(SALOME::SALOME_Exception)
792 Unexpect aCatch(SALOME_SalomeException);
794 _preMeshInfo->ForgetOrLoad();
796 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
797 SMESH::SMESH_Mesh_var mesh = _this();
799 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
801 _gen_i->RemoveHypothesisFromShape( mesh, aSubShape, anHyp );
802 _gen_i->UpdateIcons( mesh );
804 // Update Python script
805 if(_impl->HasShapeToMesh())
806 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
807 << aSubShape << ", " << anHyp << " )";
809 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
812 return ConvertHypothesisStatus(status);
815 //=============================================================================
819 //=============================================================================
821 SMESH_Hypothesis::Hypothesis_Status
822 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
823 SMESH::SMESH_Hypothesis_ptr anHyp)
825 if(MYDEBUG) MESSAGE("removeHypothesis()");
827 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
828 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
830 if (CORBA::is_nil( anHyp ))
831 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
834 _preMeshInfo->ForgetOrLoad();
836 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
839 TopoDS_Shape myLocSubShape;
840 //use PseudoShape in case if mesh has no shape
841 if( _impl->HasShapeToMesh() )
842 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
844 myLocSubShape = _impl->GetShapeToMesh();
846 const int hypId = anHyp->GetId();
847 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
848 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
850 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
854 catch(SALOME_Exception & S_ex)
856 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
861 //=============================================================================
865 //=============================================================================
867 SMESH::ListOfHypothesis *
868 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
869 throw(SALOME::SALOME_Exception)
871 Unexpect aCatch(SALOME_SalomeException);
872 if (MYDEBUG) MESSAGE("GetHypothesisList");
873 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
874 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
876 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
879 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
880 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
881 myLocSubShape = _impl->GetShapeToMesh();
882 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
883 int i = 0, n = aLocalList.size();
886 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
887 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
888 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
890 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
891 if ( id_hypptr != _mapHypo.end() )
892 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
896 catch(SALOME_Exception & S_ex) {
897 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
900 return aList._retn();
903 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
905 Unexpect aCatch(SALOME_SalomeException);
906 if (MYDEBUG) MESSAGE("GetSubMeshes");
908 SMESH::submesh_array_var aList = new SMESH::submesh_array();
911 TPythonDump aPythonDump;
912 if ( !_mapSubMeshIor.empty() )
916 aList->length( _mapSubMeshIor.size() );
918 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
919 for ( ; it != _mapSubMeshIor.end(); it++ ) {
920 if ( CORBA::is_nil( it->second )) continue;
921 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
923 if (i > 1) aPythonDump << ", ";
924 aPythonDump << it->second;
928 catch(SALOME_Exception & S_ex) {
929 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
932 // Update Python script
933 if ( !_mapSubMeshIor.empty() )
934 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
936 return aList._retn();
939 //=============================================================================
943 //=============================================================================
945 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
946 const char* theName )
947 throw(SALOME::SALOME_Exception)
949 Unexpect aCatch(SALOME_SalomeException);
950 if (CORBA::is_nil(aSubShape))
951 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
953 SMESH::SMESH_subMesh_var subMesh;
954 SMESH::SMESH_Mesh_var aMesh = _this();
956 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
958 //Get or Create the SMESH_subMesh object implementation
960 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
962 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
964 TopoDS_Iterator it( myLocSubShape );
966 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
968 subMesh = getSubMesh( subMeshId );
970 // create a new subMesh object servant if there is none for the shape
971 if ( subMesh->_is_nil() )
972 subMesh = createSubMesh( aSubShape );
973 if ( _gen_i->CanPublishInStudy( subMesh ))
975 SALOMEDS::SObject_wrap aSO =
976 _gen_i->PublishSubMesh( aMesh, subMesh, aSubShape, theName );
977 if ( !aSO->_is_nil()) {
978 // Update Python script
979 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
980 << aSubShape << ", '" << theName << "' )";
984 catch(SALOME_Exception & S_ex) {
985 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
987 return subMesh._retn();
990 //=============================================================================
994 //=============================================================================
996 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
997 throw (SALOME::SALOME_Exception)
1001 if ( theSubMesh->_is_nil() )
1004 GEOM::GEOM_Object_var aSubShape;
1005 // Remove submesh's SObject
1006 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( theSubMesh );
1007 if ( !anSO->_is_nil() ) {
1008 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
1009 SALOMEDS::SObject_wrap anObj, aRef;
1010 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
1011 anObj->ReferencedObject( aRef.inout() ))
1013 CORBA::Object_var obj = aRef->GetObject();
1014 aSubShape = GEOM::GEOM_Object::_narrow( obj );
1016 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
1017 // aSubShape = theSubMesh->GetSubShape();
1019 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
1020 builder->RemoveObjectWithChildren( anSO );
1022 // Update Python script
1023 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
1026 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
1028 _preMeshInfo->ForgetOrLoad();
1030 SMESH_CATCH( SMESH::throwCorbaException );
1033 //=============================================================================
1037 //=============================================================================
1039 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
1040 const char* theName )
1041 throw(SALOME::SALOME_Exception)
1043 Unexpect aCatch(SALOME_SalomeException);
1045 _preMeshInfo->FullLoadFromFile();
1047 SMESH::SMESH_Group_var aNewGroup =
1048 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
1050 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1052 SMESH::SMESH_Mesh_var mesh = _this();
1053 SALOMEDS::SObject_wrap aSO =
1054 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
1055 if ( !aSO->_is_nil())
1056 // Update Python script
1057 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
1058 << theElemType << ", '" << theName << "' )";
1060 return aNewGroup._retn();
1063 //=============================================================================
1067 //=============================================================================
1068 SMESH::SMESH_GroupOnGeom_ptr
1069 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
1070 const char* theName,
1071 GEOM::GEOM_Object_ptr theGeomObj)
1072 throw(SALOME::SALOME_Exception)
1074 Unexpect aCatch(SALOME_SalomeException);
1076 _preMeshInfo->FullLoadFromFile();
1078 SMESH::SMESH_GroupOnGeom_var aNewGroup;
1080 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
1081 if ( !aShape.IsNull() )
1084 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, /*id=*/-1, aShape ));
1086 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1088 SMESH::SMESH_Mesh_var mesh = _this();
1089 SALOMEDS::SObject_wrap aSO =
1090 _gen_i->PublishGroup( mesh, aNewGroup, theGeomObj, theName );
1091 if ( !aSO->_is_nil())
1092 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
1093 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
1097 return aNewGroup._retn();
1100 //================================================================================
1102 * \brief Creates a group whose contents is defined by filter
1103 * \param theElemType - group type
1104 * \param theName - group name
1105 * \param theFilter - the filter
1106 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1108 //================================================================================
1110 SMESH::SMESH_GroupOnFilter_ptr
1111 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1112 const char* theName,
1113 SMESH::Filter_ptr theFilter )
1114 throw (SALOME::SALOME_Exception)
1116 Unexpect aCatch(SALOME_SalomeException);
1118 _preMeshInfo->FullLoadFromFile();
1120 if ( CORBA::is_nil( theFilter ))
1121 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1123 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1125 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1127 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1128 ( createGroup( theElemType, theName, /*id=*/-1, TopoDS_Shape(), predicate ));
1131 if ( !aNewGroup->_is_nil() )
1132 aNewGroup->SetFilter( theFilter );
1134 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1136 SMESH::SMESH_Mesh_var mesh = _this();
1137 SALOMEDS::SObject_wrap aSO =
1138 _gen_i->PublishGroup( mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1140 if ( !aSO->_is_nil())
1141 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1142 << theElemType << ", '" << theName << "', " << theFilter << " )";
1144 return aNewGroup._retn();
1147 //=============================================================================
1151 //=============================================================================
1153 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1154 throw (SALOME::SALOME_Exception)
1156 if ( theGroup->_is_nil() )
1161 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1165 if ( aGroup->GetMeshServant() != this )
1166 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroup(): group does not belong to this mesh",
1167 SALOME::BAD_PARAM );
1169 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( theGroup );
1170 if ( !aGroupSO->_is_nil() )
1172 // Update Python script
1173 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1175 // Remove group's SObject
1176 SALOMEDS::StudyBuilder_var builder = SMESH_Gen_i::getStudyServant()->NewBuilder();
1177 builder->RemoveObjectWithChildren( aGroupSO );
1179 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1181 // Remove the group from SMESH data structures
1182 removeGroup( aGroup->GetLocalID() );
1184 SMESH_CATCH( SMESH::throwCorbaException );
1187 //=============================================================================
1189 * Remove group with its contents
1191 //=============================================================================
1193 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1194 throw (SALOME::SALOME_Exception)
1198 _preMeshInfo->FullLoadFromFile();
1200 if ( theGroup->_is_nil() )
1203 SMESH_GroupBase_i* groupImpl = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup );
1204 if ( !groupImpl || groupImpl->GetMeshServant() != this )
1205 THROW_SALOME_CORBA_EXCEPTION( "RemoveGroupWithContents(): group does not belong to this mesh",
1208 vector<int> nodeIds; // to remove nodes becoming free
1209 bool isNodal = ( theGroup->GetType() == SMESH::NODE );
1210 if ( !isNodal && !theGroup->IsEmpty() )
1212 CORBA::Long elemID = theGroup->GetID( 1 );
1213 int nbElemNodes = GetElemNbNodes( elemID );
1214 if ( nbElemNodes > 0 )
1215 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1218 // Retrieve contents
1219 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1220 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1221 SMDS_StdIterator< const SMDS_MeshElement*, SMDS_ElemIteratorPtr > elemBeg( elemIt ), elemEnd;
1222 std::vector< const SMDS_MeshElement* > elems( theGroup->Size() );
1223 elems.assign( elemBeg, elemEnd );
1225 TPythonDump pyDump; // Suppress dump from RemoveGroup()
1228 RemoveGroup( theGroup );
1231 for ( size_t i = 0; i < elems.size(); ++i )
1233 // if ( !_impl->GetMeshDS()->Contains( elems[i] ))
1237 for ( SMDS_ElemIteratorPtr nIt = elems[i]->nodesIterator(); nIt->more(); )
1238 nodeIds.push_back( nIt->next()->GetID() );
1240 _impl->GetMeshDS()->RemoveFreeElement( elems[i], /*sm=*/0 );
1244 _impl->GetMeshDS()->RemoveElement( elems[i] );
1248 // Remove free nodes
1249 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1250 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1251 if ( n->NbInverseElements() == 0 )
1252 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1254 // Update Python script (theGroup must be alive for this)
1255 pyDump << SMESH::SMESH_Mesh_var(_this())
1256 << ".RemoveGroupWithContents( " << theGroup << " )";
1258 SMESH_CATCH( SMESH::throwCorbaException );
1261 //================================================================================
1263 * \brief Get the list of groups existing in the mesh
1264 * \retval SMESH::ListOfGroups * - list of groups
1266 //================================================================================
1268 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1270 Unexpect aCatch(SALOME_SalomeException);
1271 if (MYDEBUG) MESSAGE("GetGroups");
1273 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1276 TPythonDump aPythonDump;
1277 if ( !_mapGroups.empty() )
1279 aPythonDump << "[ ";
1281 aList->length( _mapGroups.size() );
1283 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1284 for ( ; it != _mapGroups.end(); it++ ) {
1285 if ( CORBA::is_nil( it->second )) continue;
1286 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1288 if (i > 1) aPythonDump << ", ";
1289 aPythonDump << it->second;
1293 catch(SALOME_Exception & S_ex) {
1294 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1296 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1298 return aList._retn();
1301 //=============================================================================
1303 * Get number of groups existing in the mesh
1305 //=============================================================================
1307 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1309 Unexpect aCatch(SALOME_SalomeException);
1310 return _mapGroups.size();
1313 //=============================================================================
1315 * New group including all mesh elements present in initial groups is created.
1317 //=============================================================================
1319 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1320 SMESH::SMESH_GroupBase_ptr theGroup2,
1321 const char* theName )
1322 throw (SALOME::SALOME_Exception)
1324 SMESH::SMESH_Group_var aResGrp;
1328 _preMeshInfo->FullLoadFromFile();
1330 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1331 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1333 if ( theGroup1->GetType() != theGroup2->GetType() )
1334 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1339 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1340 if ( aResGrp->_is_nil() )
1341 return SMESH::SMESH_Group::_nil();
1343 aResGrp->AddFrom( theGroup1 );
1344 aResGrp->AddFrom( theGroup2 );
1346 // Update Python script
1347 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1348 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1350 SMESH_CATCH( SMESH::throwCorbaException );
1352 return aResGrp._retn();
1355 //=============================================================================
1357 * \brief New group including all mesh elements present in initial groups is created.
1358 * \param theGroups list of groups
1359 * \param theName name of group to be created
1360 * \return pointer to the new group
1362 //=============================================================================
1364 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1365 const char* theName )
1366 throw (SALOME::SALOME_Exception)
1368 SMESH::SMESH_Group_var aResGrp;
1371 _preMeshInfo->FullLoadFromFile();
1374 return SMESH::SMESH_Group::_nil();
1379 SMESH::ElementType aType = SMESH::ALL;
1380 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1382 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1383 if ( CORBA::is_nil( aGrp ) )
1385 if ( aType == SMESH::ALL )
1386 aType = aGrp->GetType();
1387 else if ( aType != aGrp->GetType() )
1388 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1391 if ( aType == SMESH::ALL )
1392 return SMESH::SMESH_Group::_nil();
1397 aResGrp = CreateGroup( aType, theName );
1398 if ( aResGrp->_is_nil() )
1399 return SMESH::SMESH_Group::_nil();
1401 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1402 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1404 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1405 if ( !CORBA::is_nil( aGrp ) )
1407 aResGrp->AddFrom( aGrp );
1408 if ( g > 0 ) pyDump << ", ";
1412 pyDump << " ], '" << theName << "' )";
1414 SMESH_CATCH( SMESH::throwCorbaException );
1416 return aResGrp._retn();
1419 //=============================================================================
1421 * New group is created. All mesh elements that are
1422 * present in both initial groups are added to the new one.
1424 //=============================================================================
1426 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1427 SMESH::SMESH_GroupBase_ptr theGroup2,
1428 const char* theName )
1429 throw (SALOME::SALOME_Exception)
1431 SMESH::SMESH_Group_var aResGrp;
1436 _preMeshInfo->FullLoadFromFile();
1438 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1439 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1441 if ( theGroup1->GetType() != theGroup2->GetType() )
1442 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1446 // Create Intersection
1447 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1448 if ( aResGrp->_is_nil() )
1449 return aResGrp._retn();
1451 SMESHDS_GroupBase* groupDS1 = 0;
1452 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1453 groupDS1 = grp_i->GetGroupDS();
1455 SMESHDS_GroupBase* groupDS2 = 0;
1456 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1457 groupDS2 = grp_i->GetGroupDS();
1459 SMESHDS_Group* resGroupDS = 0;
1460 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1461 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1463 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1465 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1466 while ( elemIt1->more() )
1468 const SMDS_MeshElement* e = elemIt1->next();
1469 if ( groupDS2->Contains( e ))
1470 resGroupDS->SMDSGroup().Add( e );
1473 // Update Python script
1474 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1475 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1477 SMESH_CATCH( SMESH::throwCorbaException );
1479 return aResGrp._retn();
1482 //=============================================================================
1484 \brief Intersect list of groups. New group is created. All mesh elements that
1485 are present in all initial groups simultaneously are added to the new one.
1486 \param theGroups list of groups
1487 \param theName name of group to be created
1488 \return pointer on the group
1490 //=============================================================================
1491 SMESH::SMESH_Group_ptr
1492 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1493 const char* theName )
1494 throw (SALOME::SALOME_Exception)
1496 SMESH::SMESH_Group_var aResGrp;
1501 _preMeshInfo->FullLoadFromFile();
1504 return SMESH::SMESH_Group::_nil();
1506 // check types and get SMESHDS_GroupBase's
1507 SMESH::ElementType aType = SMESH::ALL;
1508 vector< SMESHDS_GroupBase* > groupVec;
1509 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1511 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1512 if ( CORBA::is_nil( aGrp ) )
1514 if ( aType == SMESH::ALL )
1515 aType = aGrp->GetType();
1516 else if ( aType != aGrp->GetType() )
1517 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1520 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1521 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1523 if ( grpDS->IsEmpty() )
1528 groupVec.push_back( grpDS );
1531 if ( aType == SMESH::ALL ) // all groups are nil
1532 return SMESH::SMESH_Group::_nil();
1537 aResGrp = CreateGroup( aType, theName );
1539 SMESHDS_Group* resGroupDS = 0;
1540 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1541 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1542 if ( !resGroupDS || groupVec.empty() )
1543 return aResGrp._retn();
1546 size_t i, nb = groupVec.size();
1547 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1548 while ( elemIt1->more() )
1550 const SMDS_MeshElement* e = elemIt1->next();
1552 for ( i = 1; ( i < nb && inAll ); ++i )
1553 inAll = groupVec[i]->Contains( e );
1556 resGroupDS->SMDSGroup().Add( e );
1559 // Update Python script
1560 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1561 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1563 SMESH_CATCH( SMESH::throwCorbaException );
1565 return aResGrp._retn();
1568 //=============================================================================
1570 * New group is created. All mesh elements that are present in
1571 * a main group but is not present in a tool group are added to the new one
1573 //=============================================================================
1575 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1576 SMESH::SMESH_GroupBase_ptr theGroup2,
1577 const char* theName )
1578 throw (SALOME::SALOME_Exception)
1580 SMESH::SMESH_Group_var aResGrp;
1585 _preMeshInfo->FullLoadFromFile();
1587 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1588 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1590 if ( theGroup1->GetType() != theGroup2->GetType() )
1591 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1595 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1596 if ( aResGrp->_is_nil() )
1597 return aResGrp._retn();
1599 SMESHDS_GroupBase* groupDS1 = 0;
1600 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1601 groupDS1 = grp_i->GetGroupDS();
1603 SMESHDS_GroupBase* groupDS2 = 0;
1604 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1605 groupDS2 = grp_i->GetGroupDS();
1607 SMESHDS_Group* resGroupDS = 0;
1608 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1609 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1611 if ( groupDS1 && groupDS2 && resGroupDS )
1613 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1614 while ( elemIt1->more() )
1616 const SMDS_MeshElement* e = elemIt1->next();
1617 if ( !groupDS2->Contains( e ))
1618 resGroupDS->SMDSGroup().Add( e );
1621 // Update Python script
1622 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1623 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1625 SMESH_CATCH( SMESH::throwCorbaException );
1627 return aResGrp._retn();
1630 //=============================================================================
1632 \brief Cut lists of groups. New group is created. All mesh elements that are
1633 present in main groups but do not present in tool groups are added to the new one
1634 \param theMainGroups list of main groups
1635 \param theToolGroups list of tool groups
1636 \param theName name of group to be created
1637 \return pointer on the group
1639 //=============================================================================
1640 SMESH::SMESH_Group_ptr
1641 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1642 const SMESH::ListOfGroups& theToolGroups,
1643 const char* theName )
1644 throw (SALOME::SALOME_Exception)
1646 SMESH::SMESH_Group_var aResGrp;
1651 _preMeshInfo->FullLoadFromFile();
1654 return SMESH::SMESH_Group::_nil();
1656 // check types and get SMESHDS_GroupBase's
1657 SMESH::ElementType aType = SMESH::ALL;
1658 vector< SMESHDS_GroupBase* > toolGroupVec;
1659 vector< SMDS_ElemIteratorPtr > mainIterVec;
1661 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1663 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1664 if ( CORBA::is_nil( aGrp ) )
1666 if ( aType == SMESH::ALL )
1667 aType = aGrp->GetType();
1668 else if ( aType != aGrp->GetType() )
1669 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1671 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1672 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1673 if ( !grpDS->IsEmpty() )
1674 mainIterVec.push_back( grpDS->GetElements() );
1676 if ( aType == SMESH::ALL ) // all main groups are nil
1677 return SMESH::SMESH_Group::_nil();
1678 if ( mainIterVec.empty() ) // all main groups are empty
1679 return aResGrp._retn();
1681 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1683 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1684 if ( CORBA::is_nil( aGrp ) )
1686 if ( aType != aGrp->GetType() )
1687 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1689 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1690 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1691 toolGroupVec.push_back( grpDS );
1697 aResGrp = CreateGroup( aType, theName );
1699 SMESHDS_Group* resGroupDS = 0;
1700 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1701 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1703 return aResGrp._retn();
1706 size_t i, nb = toolGroupVec.size();
1707 SMDS_ElemIteratorPtr mainElemIt
1708 ( new SMDS_IteratorOnIterators
1709 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1710 while ( mainElemIt->more() )
1712 const SMDS_MeshElement* e = mainElemIt->next();
1714 for ( i = 0; ( i < nb && !isIn ); ++i )
1715 isIn = toolGroupVec[i]->Contains( e );
1718 resGroupDS->SMDSGroup().Add( e );
1721 // Update Python script
1722 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1723 << ".CutListOfGroups( " << theMainGroups << ", "
1724 << theToolGroups << ", '" << theName << "' )";
1726 SMESH_CATCH( SMESH::throwCorbaException );
1728 return aResGrp._retn();
1731 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1733 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1734 bool & toStopChecking )
1736 toStopChecking = ( nbCommon < nbChecked );
1737 return nbCommon == nbNodes;
1739 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1740 bool & toStopChecking )
1742 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1743 return nbCommon == nbCorners;
1745 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1746 bool & toStopChecking )
1748 return nbCommon > 0;
1750 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1751 bool & toStopChecking )
1753 return nbCommon >= (nbNodes+1) / 2;
1757 //=============================================================================
1759 * Create a group of entities basing on nodes of other groups.
1760 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1761 * \param [in] anElemType - a type of elements to include to the new group.
1762 * \param [in] theName - a name of the new group.
1763 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1764 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1765 * new group provided that it is based on nodes of an element of \a aListOfGroups
1766 * \return SMESH_Group - the created group
1768 // IMP 19939, bug 22010, IMP 22635
1769 //=============================================================================
1771 SMESH::SMESH_Group_ptr
1772 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1773 SMESH::ElementType theElemType,
1774 const char* theName,
1775 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1776 CORBA::Boolean theUnderlyingOnly)
1777 throw (SALOME::SALOME_Exception)
1779 SMESH::SMESH_Group_var aResGrp;
1783 _preMeshInfo->FullLoadFromFile();
1785 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1787 if ( !theName || !aMeshDS )
1788 return SMESH::SMESH_Group::_nil();
1790 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1792 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1793 SMESH_Comment nbCoNoStr( "SMESH.");
1794 switch ( theNbCommonNodes ) {
1795 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1796 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1797 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1798 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1799 default: return aResGrp._retn();
1801 int nbChecked, nbCommon, nbNodes, nbCorners;
1807 aResGrp = CreateGroup( theElemType, theName );
1808 if ( aResGrp->_is_nil() )
1809 return SMESH::SMESH_Group::_nil();
1811 SMESHDS_GroupBase* groupBaseDS =
1812 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1813 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1815 vector<bool> isNodeInGroups;
1817 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1819 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1820 if ( CORBA::is_nil( aGrp ) )
1822 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1823 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1826 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1827 if ( !elIt ) continue;
1829 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1831 while ( elIt->more() ) {
1832 const SMDS_MeshElement* el = elIt->next();
1833 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1834 while ( nIt->more() )
1835 resGroupCore.Add( nIt->next() );
1838 // get elements of theElemType based on nodes of every element of group
1839 else if ( theUnderlyingOnly )
1841 while ( elIt->more() )
1843 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1844 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1845 TIDSortedElemSet checkedElems;
1846 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1847 while ( nIt->more() )
1849 const SMDS_MeshNode* n = nIt->next();
1850 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1851 // check nodes of elements of theElemType around el
1852 while ( elOfTypeIt->more() )
1854 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1855 if ( !checkedElems.insert( elOfType ).second ) continue;
1856 nbNodes = elOfType->NbNodes();
1857 nbCorners = elOfType->NbCornerNodes();
1859 bool toStopChecking = false;
1860 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1861 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1862 if ( elNodes.count( nIt2->next() ) &&
1863 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1865 resGroupCore.Add( elOfType );
1872 // get all nodes of elements of groups
1875 while ( elIt->more() )
1877 const SMDS_MeshElement* el = elIt->next(); // an element of group
1878 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1879 while ( nIt->more() )
1881 const SMDS_MeshNode* n = nIt->next();
1882 if ( n->GetID() >= (int) isNodeInGroups.size() )
1883 isNodeInGroups.resize( n->GetID() + 1, false );
1884 isNodeInGroups[ n->GetID() ] = true;
1890 // Get elements of theElemType based on a certain number of nodes of elements of groups
1891 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1893 const SMDS_MeshNode* n;
1894 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1895 const int isNodeInGroupsSize = isNodeInGroups.size();
1896 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1898 if ( !isNodeInGroups[ iN ] ||
1899 !( n = aMeshDS->FindNode( iN )))
1902 // check nodes of elements of theElemType around n
1903 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1904 while ( elOfTypeIt->more() )
1906 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1907 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1912 nbNodes = elOfType->NbNodes();
1913 nbCorners = elOfType->NbCornerNodes();
1915 bool toStopChecking = false;
1916 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1917 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1919 const int nID = nIt->next()->GetID();
1920 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1921 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1923 resGroupCore.Add( elOfType );
1931 // Update Python script
1932 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1933 << ".CreateDimGroup( "
1934 << theGroups << ", " << theElemType << ", '" << theName << "', "
1935 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1937 SMESH_CATCH( SMESH::throwCorbaException );
1939 return aResGrp._retn();
1942 //================================================================================
1944 * \brief Distribute all faces of the mesh between groups using sharp edges and optionally
1945 * existing 1D elements as group boundaries.
1946 * \param [in] theSharpAngle - edge is considered sharp if an angle between normals of
1947 * adjacent faces is more than \a sharpAngle in degrees.
1948 * \param [in] theCreateEdges - to create 1D elements for detected sharp edges.
1949 * \param [in] theUseExistingEdges - to use existing edges as group boundaries
1950 * \return ListOfGroups - the created groups
1952 //================================================================================
1954 SMESH::ListOfGroups*
1955 SMESH_Mesh_i::FaceGroupsSeparatedByEdges( CORBA::Double theSharpAngle,
1956 CORBA::Boolean theCreateEdges,
1957 CORBA::Boolean theUseExistingEdges )
1958 throw (SALOME::SALOME_Exception)
1960 if ( theSharpAngle < 0 || theSharpAngle > 180 )
1961 THROW_SALOME_CORBA_EXCEPTION("Invalid sharp angle, it must be between 0 and 180 degrees",
1964 SMESH::ListOfGroups_var resultGroups = new SMESH::ListOfGroups;
1970 _preMeshInfo->FullLoadFromFile();
1972 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
1974 std::vector< SMESH_MeshAlgos::Edge > edges =
1975 SMESH_MeshAlgos::FindSharpEdges( meshDS, theSharpAngle, theUseExistingEdges );
1977 if ( theCreateEdges )
1979 std::vector<const SMDS_MeshNode *> nodes(2);
1980 for ( size_t i = 0; i < edges.size(); ++i )
1982 nodes[0] = edges[i]._node1;
1983 nodes[1] = edges[i]._node2;
1984 if ( meshDS->FindElement( nodes, SMDSAbs_Edge ))
1986 if ( edges[i]._medium )
1987 meshDS->AddEdge( edges[i]._node1, edges[i]._node2, edges[i]._medium );
1989 meshDS->AddEdge( edges[i]._node1, edges[i]._node2 );
1993 std::vector< std::vector< const SMDS_MeshElement* > > faceGroups =
1994 SMESH_MeshAlgos::SeparateFacesByEdges( meshDS, edges );
1996 SMESH::SMESH_MeshEditor_var editor = GetMeshEditor(); // create _editor
1998 resultGroups->length( faceGroups.size() );
1999 for ( size_t iG = 0; iG < faceGroups.size(); ++iG )
2001 SMESH::SMESH_Group_var group = CreateGroup( SMESH::FACE,
2002 _editor->GenerateGroupName("Group").c_str());
2003 resultGroups[iG] = SMESH::SMESH_Group::_duplicate( group );
2005 SMESHDS_GroupBase* groupBaseDS =
2006 SMESH::DownCast<SMESH_GroupBase_i*>( group )->GetGroupDS();
2007 SMDS_MeshGroup& groupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
2009 std::vector< const SMDS_MeshElement* >& faces = faceGroups[ iG ];
2010 for ( size_t i = 0; i < faces.size(); ++i )
2011 groupCore.Add( faces[i] );
2014 pyDump << resultGroups << " = " << SMESH::SMESH_Mesh_var(_this())
2015 << ".FaceGroupsSeparatedByEdges( "
2016 << TVar( theSharpAngle ) << ", "
2017 << theCreateEdges << ", "
2018 << theUseExistingEdges << " )";
2020 SMESH_CATCH( SMESH::throwCorbaException );
2021 return resultGroups._retn();
2025 //================================================================================
2027 * \brief Remember GEOM group data
2029 //================================================================================
2031 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
2032 CORBA::Object_ptr theSmeshObj)
2034 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
2037 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( theGeomObj );
2038 if ( groupSO->_is_nil() )
2041 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( theGeomObj );
2042 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2043 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
2046 _geomGroupData.push_back( TGeomGroupData() );
2047 TGeomGroupData & groupData = _geomGroupData.back();
2049 CORBA::String_var entry = groupSO->GetID();
2050 groupData._groupEntry = entry.in();
2052 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2053 groupData._indices.insert( ids[i] );
2055 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
2056 // shape index in SMESHDS
2057 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
2058 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
2061 //================================================================================
2063 * Remove GEOM group data relating to removed smesh object
2065 //================================================================================
2067 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
2069 list<TGeomGroupData>::iterator
2070 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2071 for ( ; data != dataEnd; ++data ) {
2072 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
2073 _geomGroupData.erase( data );
2079 //================================================================================
2081 * \brief Return new group contents if it has been changed and update group data
2083 //================================================================================
2084 enum { ONLY_IF_CHANGED, IS_BREAK_LINK, MAIN_TRANSFORMED };
2086 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData, int how )
2088 TopoDS_Shape newShape;
2090 if ( how == IS_BREAK_LINK )
2092 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( groupData._smeshObject );
2093 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2094 if ( !meshSO->_is_nil() &&
2095 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2096 geomRefSO->ReferencedObject( geomSO.inout() ))
2098 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2099 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2100 newShape = _gen_i->GeomObjectToShape( geom );
2101 if ( !newShape.IsNull() )
2103 CORBA::String_var entry = geom->GetStudyEntry();
2104 groupData._groupEntry = entry.in();
2111 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2112 if ( !groupSO->_is_nil() )
2114 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2115 if ( CORBA::is_nil( groupObj )) return newShape;
2116 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2118 // get indices of group items
2119 set<int> curIndices;
2120 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2121 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2122 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2123 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2124 curIndices.insert( ids[i] );
2126 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2127 return newShape; // group not changed
2130 groupData._indices = curIndices;
2132 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2133 if ( !geomClient ) return newShape;
2134 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2135 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2136 newShape = _gen_i->GeomObjectToShape( geomGroup );
2139 if ( newShape.IsNull() ) {
2140 // geom group becomes empty - return empty compound
2141 TopoDS_Compound compound;
2142 BRep_Builder().MakeCompound(compound);
2143 newShape = compound;
2150 //-----------------------------------------------------------------------------
2152 * \brief Storage of shape and index used in CheckGeomGroupModif()
2154 struct TIndexedShape
2157 TopoDS_Shape _shape;
2158 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2160 //-----------------------------------------------------------------------------
2162 * \brief Data to re-create a group on geometry
2164 struct TGroupOnGeomData
2167 TopoDS_Shape _shape;
2168 SMDSAbs_ElementType _type;
2170 Quantity_Color _color;
2172 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2174 _oldID = group->GetID();
2175 _type = group->GetType();
2176 _name = group->GetStoreName();
2177 _color = group->GetColor();
2181 //-----------------------------------------------------------------------------
2183 * \brief Check if a filter is still valid after geometry removal
2185 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2187 if ( theFilter->_is_nil() )
2189 SMESH::Filter::Criteria_var criteria;
2190 theFilter->GetCriteria( criteria.out() );
2192 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2194 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2196 switch ( criteria[ iCr ].Type )
2198 case SMESH::FT_BelongToGeom:
2199 case SMESH::FT_BelongToPlane:
2200 case SMESH::FT_BelongToCylinder:
2201 case SMESH::FT_BelongToGenSurface:
2202 case SMESH::FT_LyingOnGeom:
2203 entry = thresholdID;
2205 case SMESH::FT_ConnectedElements:
2208 entry = thresholdID;
2214 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2215 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2216 if ( so->_is_nil() )
2218 CORBA::Object_var obj = so->GetObject();
2219 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2220 if ( gen->GeomObjectToShape( geom ).IsNull() )
2223 } // loop on criteria
2229 //=============================================================================
2231 * \brief Update data if geometry changes
2235 //=============================================================================
2237 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2239 SMESH::SMESH_Mesh_var me = _this();
2240 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2242 TPythonDump dumpNothing; // prevent any dump
2244 //bool removedFromClient = false;
2246 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2248 //removedFromClient = _impl->HasShapeToMesh();
2250 // try to find geometry by study reference
2251 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2252 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2253 if ( !meshSO->_is_nil() &&
2254 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2255 geomRefSO->ReferencedObject( geomSO.inout() ))
2257 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2258 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2261 if ( mainGO->_is_nil() && // geometry removed ==>
2262 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2264 // convert geom dependent groups into standalone ones
2265 CheckGeomGroupModif();
2267 _impl->ShapeToMesh( TopoDS_Shape() );
2269 // remove sub-meshes
2270 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2271 while ( i_sm != _mapSubMeshIor.end() )
2273 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2275 RemoveSubMesh( sm );
2277 // remove all children except groups in the study
2278 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2279 SALOMEDS::SObject_wrap so;
2280 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2281 if ( meshSO->FindSubObject( tag, so.inout() ))
2282 builder->RemoveObjectWithChildren( so );
2284 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2290 if ( !_impl->HasShapeToMesh() ) return;
2293 // Update after group modification
2295 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2296 mainGO->GetTick() == _mainShapeTick )
2298 int nb = NbNodes() + NbElements();
2299 CheckGeomGroupModif();
2300 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2301 _gen_i->UpdateIcons( me );
2305 // Update after shape modification
2307 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2308 if ( !geomClient ) return;
2309 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2310 if ( geomGen->_is_nil() ) return;
2311 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2312 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2314 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2315 geomClient->RemoveShapeFromBuffer( ior.in() );
2317 // Update data taking into account that if topology doesn't change
2318 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2321 _preMeshInfo->ForgetAllData();
2324 if ( isBreakLink || !isShaper )
2326 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2327 if ( newShape.IsNull() )
2330 _mainShapeTick = mainGO->GetTick();
2332 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2334 // store data of groups on geometry
2335 std::vector< TGroupOnGeomData > groupsData;
2336 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2337 groupsData.reserve( groups.size() );
2338 TopTools_DataMapOfShapeShape old2newShapeMap;
2339 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2340 for ( ; g != groups.end(); ++g )
2342 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2344 groupsData.push_back( TGroupOnGeomData( group ));
2347 SMESH::SMESH_GroupOnGeom_var gog;
2348 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2349 if ( i_grp != _mapGroups.end() )
2350 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2352 GEOM::GEOM_Object_var geom;
2353 if ( !gog->_is_nil() )
2357 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2358 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2359 if ( !grpSO->_is_nil() &&
2360 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2361 geomRefSO->ReferencedObject( geomSO.inout() ))
2363 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2364 geom = GEOM::GEOM_Object::_narrow( geomObj );
2369 geom = gog->GetShape();
2372 if ( !geom->_is_nil() )
2374 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2375 geomClient->RemoveShapeFromBuffer( ior.in() );
2376 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2377 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2379 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2381 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2385 // store assigned hypotheses
2386 std::vector< pair< int, THypList > > ids2Hyps;
2387 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2388 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2390 const TopoDS_Shape& s = s2hyps.Key();
2391 const THypList& hyps = s2hyps.ChangeValue();
2392 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2395 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2397 // count shapes excluding compounds corresponding to geom groups
2398 int oldNbSubShapes = meshDS->MaxShapeIndex();
2399 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2401 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2402 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2405 std::set<int> subIds;
2406 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2407 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2408 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2411 // check if shape topology changes - save shape type per shape ID
2412 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2413 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2414 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2416 // change shape to mesh
2417 _impl->ShapeToMesh( TopoDS_Shape() );
2418 _impl->ShapeToMesh( newShape );
2420 // check if shape topology changes - check new shape types
2421 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2422 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2424 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2425 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2428 // re-add shapes (compounds) of geom groups
2429 std::map< int, int > old2newIDs; // group IDs
2430 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2431 for ( ; data != _geomGroupData.end(); ++data )
2434 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2435 if ( ii2i != ii2iMap.end() )
2436 oldID = ii2i->second;
2437 if ( old2newIDs.count( oldID ))
2440 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2441 newShape = newGroupShape( *data, how );
2442 if ( !newShape.IsNull() )
2444 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2446 TopoDS_Compound compound;
2447 BRep_Builder().MakeCompound( compound );
2448 BRep_Builder().Add( compound, newShape );
2449 newShape = compound;
2451 int newID = _impl->GetSubMesh( newShape )->GetId();
2452 if ( oldID /*&& oldID != newID*/ )
2453 old2newIDs.insert( std::make_pair( oldID, newID ));
2454 if ( data->_indices.size() == 1 )
2456 oldID = *data->_indices.begin();
2457 old2newIDs.insert( std::make_pair( oldID, newID ));
2462 // re-assign hypotheses
2463 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2465 int sID = ids2Hyps[i].first;
2466 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2467 if ( o2n != old2newIDs.end() )
2469 else if ( !sameTopology && sID != 1 )
2471 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2474 const THypList& hyps = ids2Hyps[i].second;
2475 THypList::const_iterator h = hyps.begin();
2476 for ( ; h != hyps.end(); ++h )
2477 _impl->AddHypothesis( s, (*h)->GetID() );
2481 // restore groups on geometry
2482 for ( size_t i = 0; i < groupsData.size(); ++i )
2484 const TGroupOnGeomData& data = groupsData[i];
2485 if ( data._shape.IsNull() )
2488 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2489 if ( i2g == _mapGroups.end() ) continue;
2491 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2492 if ( !gr_i ) continue;
2494 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2496 _mapGroups.erase( i2g );
2498 g->GetGroupDS()->SetColor( data._color );
2501 std::map< int, int >::iterator o2n = old2newIDs.begin();
2502 for ( ; o2n != old2newIDs.end(); ++o2n )
2504 int newID = o2n->second, oldID = o2n->first;
2505 if ( newID == oldID || !_mapSubMesh.count( oldID ))
2509 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2510 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2511 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2513 _mapSubMesh. erase(oldID);
2514 _mapSubMesh_i. erase(oldID);
2515 _mapSubMeshIor.erase(oldID);
2517 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2520 // update _mapSubMesh
2521 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2522 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2523 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2526 if ( !sameTopology )
2528 // remove invalid study sub-objects
2529 CheckGeomGroupModif();
2532 _gen_i->UpdateIcons( me );
2534 if ( !isBreakLink && isShaper )
2536 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2537 if ( !meshSO->_is_nil() )
2538 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2542 //=============================================================================
2544 * \brief Update objects depending on changed geom groups
2546 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2547 * issue 0020210: Update of a smesh group after modification of the associated geom group
2549 //=============================================================================
2551 void SMESH_Mesh_i::CheckGeomGroupModif()
2553 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2554 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2555 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2556 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2557 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2559 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2560 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2561 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2563 int nbValid = 0, nbRemoved = 0;
2564 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2565 for ( ; chItr->More(); chItr->Next() )
2567 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2568 if ( !smSO->_is_nil() &&
2569 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2570 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2572 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2573 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2574 if ( !geom->_non_existent() )
2577 continue; // keep the sub-mesh
2580 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2581 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2582 if ( !sm->_is_nil() && !sm->_non_existent() )
2584 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2585 if ( smGeom->_is_nil() )
2587 RemoveSubMesh( sm );
2594 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2595 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2599 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2600 builder->RemoveObjectWithChildren( rootSO );
2604 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2605 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2606 while ( i_gr != _mapGroups.end())
2608 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2610 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2611 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2612 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2613 bool isValidGeom = false;
2614 if ( !onGeom->_is_nil() )
2616 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2618 else if ( !onFilt->_is_nil() )
2620 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2624 isValidGeom = ( !groupSO->_is_nil() &&
2625 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2629 if ( !IsLoaded() || group->IsEmpty() )
2631 RemoveGroup( group );
2633 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2635 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2637 else // is it possible?
2639 builder->RemoveObjectWithChildren( refSO );
2645 if ( !_impl->HasShapeToMesh() ) return;
2647 CORBA::Long nbEntities = NbNodes() + NbElements();
2649 // Check if group contents changed
2651 typedef map< string, TopoDS_Shape > TEntry2Geom;
2652 TEntry2Geom newGroupContents;
2654 list<TGeomGroupData>::iterator
2655 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2656 for ( ; data != dataEnd; ++data )
2658 pair< TEntry2Geom::iterator, bool > it_new =
2659 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2660 bool processedGroup = !it_new.second;
2661 TopoDS_Shape& newShape = it_new.first->second;
2662 if ( !processedGroup )
2663 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2664 if ( newShape.IsNull() )
2665 continue; // no changes
2668 _preMeshInfo->ForgetOrLoad();
2670 if ( processedGroup ) { // update group indices
2671 list<TGeomGroupData>::iterator data2 = data;
2672 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2673 data->_indices = data2->_indices;
2676 // Update SMESH objects according to new GEOM group contents
2678 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2679 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2681 int oldID = submesh->GetId();
2682 if ( !_mapSubMeshIor.count( oldID ))
2684 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2686 // update hypotheses
2687 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2688 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2689 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2691 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2692 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2694 // care of submeshes
2695 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2696 int newID = newSubmesh->GetId();
2697 if ( newID != oldID ) {
2698 _mapSubMesh [ newID ] = newSubmesh;
2699 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2700 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2701 _mapSubMesh. erase(oldID);
2702 _mapSubMesh_i. erase(oldID);
2703 _mapSubMeshIor.erase(oldID);
2704 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2709 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2710 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2711 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2713 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2715 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2716 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2717 ds->SetShape( newShape );
2722 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2723 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2725 // Remove groups and submeshes basing on removed sub-shapes
2727 TopTools_MapOfShape newShapeMap;
2728 TopoDS_Iterator shapeIt( newShape );
2729 for ( ; shapeIt.More(); shapeIt.Next() )
2730 newShapeMap.Add( shapeIt.Value() );
2732 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2733 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2735 if ( newShapeMap.Contains( shapeIt.Value() ))
2737 TopTools_IndexedMapOfShape oldShapeMap;
2738 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2739 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2741 const TopoDS_Shape& oldShape = oldShapeMap(i);
2742 int oldInd = meshDS->ShapeToIndex( oldShape );
2744 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2745 if ( i_smIor != _mapSubMeshIor.end() ) {
2746 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2749 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2750 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2752 // check if a group bases on oldInd shape
2753 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2754 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2755 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2756 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2758 RemoveGroup( i_grp->second ); // several groups can base on same shape
2759 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2764 // Reassign hypotheses and update groups after setting the new shape to mesh
2766 // collect anassigned hypotheses
2767 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2768 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2769 TShapeHypList assignedHyps;
2770 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2772 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2773 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2774 if ( !hyps.empty() ) {
2775 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2776 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2777 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2780 // collect shapes supporting groups
2781 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2782 TShapeTypeList groupData;
2783 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2784 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2785 for ( ; grIt != groups.end(); ++grIt )
2787 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2789 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2791 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2793 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2794 _impl->ShapeToMesh( newShape );
2796 // reassign hypotheses
2797 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2798 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2800 TIndexedShape& geom = indS_hyps->first;
2801 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2802 int oldID = geom._index;
2803 int newID = meshDS->ShapeToIndex( geom._shape );
2804 if ( oldID == 1 ) { // main shape
2806 geom._shape = newShape;
2810 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2811 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2812 // care of sub-meshes
2813 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2814 if ( newID != oldID ) {
2815 _mapSubMesh [ newID ] = newSubmesh;
2816 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2817 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2818 _mapSubMesh. erase(oldID);
2819 _mapSubMesh_i. erase(oldID);
2820 _mapSubMeshIor.erase(oldID);
2821 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2825 TShapeTypeList::iterator geomType = groupData.begin();
2826 for ( ; geomType != groupData.end(); ++geomType )
2828 const TIndexedShape& geom = geomType->first;
2829 int oldID = geom._index;
2830 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2833 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2834 CORBA::String_var name = groupSO->GetName();
2836 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2837 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2838 /*id=*/-1, geom._shape ))
2839 group_i->changeLocalId( group->GetID() );
2842 break; // everything has been updated
2845 } // loop on group data
2849 CORBA::Long newNbEntities = NbNodes() + NbElements();
2850 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2851 if ( newNbEntities != nbEntities )
2853 // Add all SObjects with icons to soToUpdateIcons
2854 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2856 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2857 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2858 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2860 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2861 i_gr != _mapGroups.end(); ++i_gr ) // groups
2862 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2865 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2866 for ( ; so != soToUpdateIcons.end(); ++so )
2867 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2870 //=============================================================================
2872 * \brief Create standalone group from a group on geometry or filter
2874 //=============================================================================
2876 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2877 throw (SALOME::SALOME_Exception)
2879 SMESH::SMESH_Group_var aGroup;
2884 _preMeshInfo->FullLoadFromFile();
2886 if ( theGroup->_is_nil() )
2887 return aGroup._retn();
2889 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2891 return aGroup._retn();
2893 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2895 const int anId = aGroupToRem->GetLocalID();
2896 if ( !_impl->ConvertToStandalone( anId ) )
2897 return aGroup._retn();
2898 removeGeomGroupData( theGroup );
2900 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2902 // remove old instance of group from own map
2903 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2904 _mapGroups.erase( anId );
2906 SALOMEDS::StudyBuilder_var builder;
2907 SALOMEDS::SObject_wrap aGroupSO;
2908 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2909 if ( !aStudy->_is_nil() ) {
2910 builder = aStudy->NewBuilder();
2911 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2912 if ( !aGroupSO->_is_nil() )
2914 // remove reference to geometry
2915 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2916 for ( ; chItr->More(); chItr->Next() )
2918 // Remove group's child SObject
2919 SALOMEDS::SObject_wrap so = chItr->Value();
2920 builder->RemoveObject( so );
2922 // Update Python script
2923 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2924 << ".ConvertToStandalone( " << aGroupSO << " )";
2926 // change icon of Group on Filter
2929 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2930 // const int isEmpty = ( elemTypes->length() == 0 );
2933 SALOMEDS::GenericAttribute_wrap anAttr =
2934 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2935 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2936 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2942 // remember new group in own map
2943 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2944 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2946 // register CORBA object for persistence
2947 _gen_i->RegisterObject( aGroup );
2949 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2950 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2951 //aGroup->Register();
2952 aGroupToRem->UnRegister();
2954 SMESH_CATCH( SMESH::throwCorbaException );
2956 return aGroup._retn();
2959 //=============================================================================
2963 //=============================================================================
2965 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2967 if(MYDEBUG) MESSAGE( "createSubMesh" );
2968 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2969 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2972 SMESH_subMesh_i * subMeshServant;
2975 subMeshId = mySubMesh->GetId();
2976 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2978 else // "invalid sub-mesh"
2980 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2981 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2982 if ( _mapSubMesh.empty() )
2985 subMeshId = _mapSubMesh.begin()->first - 1;
2986 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2989 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2991 _mapSubMesh [subMeshId] = mySubMesh;
2992 _mapSubMesh_i [subMeshId] = subMeshServant;
2993 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2995 subMeshServant->Register();
2997 // register CORBA object for persistence
2998 int nextId = _gen_i->RegisterObject( subMesh );
2999 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
3000 else { nextId = 0; } // avoid "unused variable" warning
3002 // to track changes of GEOM groups
3003 if ( subMeshId > 0 )
3004 addGeomGroupData( theSubShapeObject, subMesh );
3006 return subMesh._retn();
3009 //=======================================================================
3010 //function : getSubMesh
3012 //=======================================================================
3014 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3016 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3017 if ( it == _mapSubMeshIor.end() )
3018 return SMESH::SMESH_subMesh::_nil();
3020 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3023 //=============================================================================
3027 //=============================================================================
3029 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3030 GEOM::GEOM_Object_ptr theSubShapeObject )
3032 bool isHypChanged = false;
3033 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3034 return isHypChanged;
3036 const int subMeshId = theSubMesh->GetId();
3038 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3041 if (( _mapSubMesh.count( subMeshId )) &&
3042 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3044 TopoDS_Shape S = sm->GetSubShape();
3047 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3048 isHypChanged = !hyps.empty();
3049 if ( isHypChanged && _preMeshInfo )
3050 _preMeshInfo->ForgetOrLoad();
3051 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3052 for ( ; hyp != hyps.end(); ++hyp )
3053 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3060 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3061 isHypChanged = ( aHypList->length() > 0 );
3062 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3063 removeHypothesis( theSubShapeObject, aHypList[i] );
3066 catch( const SALOME::SALOME_Exception& ) {
3067 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3069 removeGeomGroupData( theSubShapeObject );
3073 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3074 if ( id_smi != _mapSubMesh_i.end() )
3075 id_smi->second->UnRegister();
3077 // remove a CORBA object
3078 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3079 if ( id_smptr != _mapSubMeshIor.end() )
3080 SMESH::SMESH_subMesh_var( id_smptr->second );
3082 _mapSubMesh.erase(subMeshId);
3083 _mapSubMesh_i.erase(subMeshId);
3084 _mapSubMeshIor.erase(subMeshId);
3086 return isHypChanged;
3089 //=============================================================================
3093 //=============================================================================
3095 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3096 const char* theName,
3098 const TopoDS_Shape& theShape,
3099 const SMESH_PredicatePtr& thePredicate )
3101 std::string newName;
3102 if ( !theName || !theName[0] )
3104 std::set< std::string > presentNames;
3105 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3106 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3108 CORBA::String_var name = i_gr->second->GetName();
3109 presentNames.insert( name.in() );
3112 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3113 } while ( !presentNames.insert( newName ).second );
3114 theName = newName.c_str();
3116 SMESH::SMESH_GroupBase_var aGroup;
3117 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3118 theID, theShape, thePredicate ))
3120 int anId = g->GetID();
3121 SMESH_GroupBase_i* aGroupImpl;
3122 if ( !theShape.IsNull() )
3123 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3124 else if ( thePredicate )
3125 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3127 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3129 aGroup = aGroupImpl->_this();
3130 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3131 aGroupImpl->Register();
3133 // register CORBA object for persistence
3134 int nextId = _gen_i->RegisterObject( aGroup );
3135 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3136 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3138 // to track changes of GEOM groups
3139 if ( !theShape.IsNull() ) {
3140 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3141 addGeomGroupData( geom, aGroup );
3144 return aGroup._retn();
3147 //=============================================================================
3149 * SMESH_Mesh_i::removeGroup
3151 * Should be called by ~SMESH_Group_i()
3153 //=============================================================================
3155 void SMESH_Mesh_i::removeGroup( const int theId )
3157 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3158 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3159 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3160 _mapGroups.erase( theId );
3161 removeGeomGroupData( group );
3162 if ( !_impl->RemoveGroup( theId ))
3164 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3165 RemoveGroup( group );
3167 group->UnRegister();
3171 //=============================================================================
3175 //=============================================================================
3177 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3178 throw(SALOME::SALOME_Exception)
3180 SMESH::log_array_var aLog;
3184 _preMeshInfo->FullLoadFromFile();
3186 list < SMESHDS_Command * >logDS = _impl->GetLog();
3187 aLog = new SMESH::log_array;
3189 int lg = logDS.size();
3192 list < SMESHDS_Command * >::iterator its = logDS.begin();
3193 while(its != logDS.end()){
3194 SMESHDS_Command *com = *its;
3195 int comType = com->GetType();
3197 int lgcom = com->GetNumber();
3199 const list < int >&intList = com->GetIndexes();
3200 int inum = intList.size();
3202 list < int >::const_iterator ii = intList.begin();
3203 const list < double >&coordList = com->GetCoords();
3204 int rnum = coordList.size();
3206 list < double >::const_iterator ir = coordList.begin();
3207 aLog[indexLog].commandType = comType;
3208 aLog[indexLog].number = lgcom;
3209 aLog[indexLog].coords.length(rnum);
3210 aLog[indexLog].indexes.length(inum);
3211 for(int i = 0; i < rnum; i++){
3212 aLog[indexLog].coords[i] = *ir;
3213 //MESSAGE(" "<<i<<" "<<ir.Value());
3216 for(int i = 0; i < inum; i++){
3217 aLog[indexLog].indexes[i] = *ii;
3218 //MESSAGE(" "<<i<<" "<<ii.Value());
3227 SMESH_CATCH( SMESH::throwCorbaException );
3229 return aLog._retn();
3233 //=============================================================================
3237 //=============================================================================
3239 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3243 SMESH_CATCH( SMESH::throwCorbaException );
3246 //=============================================================================
3250 //=============================================================================
3252 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3257 //=============================================================================
3260 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3261 // issue 0020918: groups removal is caused by hyp modification
3262 // issue 0021208: to forget not loaded mesh data at hyp modification
3263 struct TCallUp_i : public SMESH_Mesh::TCallUp
3265 SMESH_Mesh_i* _mesh;
3266 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3267 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3268 virtual void HypothesisModified( int hypID,
3269 bool updIcons) { _mesh->onHypothesisModified( hypID,
3271 virtual void Load () { _mesh->Load(); }
3272 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3276 //================================================================================
3278 * \brief callback from _impl to
3279 * 1) forget not loaded mesh data (issue 0021208)
3280 * 2) mark hypothesis as valid
3282 //================================================================================
3284 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3287 _preMeshInfo->ForgetOrLoad();
3289 if ( theUpdateIcons )
3291 SMESH::SMESH_Mesh_var mesh = _this();
3292 _gen_i->UpdateIcons( mesh );
3295 if ( _nbInvalidHypos != 0 )
3297 // mark a hypothesis as valid after edition
3299 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3300 SALOMEDS::SObject_wrap hypRoot;
3301 if ( !smeshComp->_is_nil() &&
3302 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3304 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3305 for ( ; anIter->More(); anIter->Next() )
3307 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3308 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3309 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3310 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3311 _gen_i->HighLightInvalid( hyp, false );
3313 nbInvalid += _gen_i->IsInvalid( hypSO );
3316 _nbInvalidHypos = nbInvalid;
3320 //=============================================================================
3324 //=============================================================================
3326 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3328 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3331 _impl->SetCallUp( new TCallUp_i(this));
3334 //=============================================================================
3338 //=============================================================================
3340 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3342 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3346 //=============================================================================
3348 * Return mesh editor
3350 //=============================================================================
3352 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3353 throw (SALOME::SALOME_Exception)
3355 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3359 _preMeshInfo->FullLoadFromFile();
3361 // Create MeshEditor
3363 _editor = new SMESH_MeshEditor_i( this, false );
3364 aMeshEdVar = _editor->_this();
3366 // Update Python script
3367 TPythonDump() << _editor << " = "
3368 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3370 SMESH_CATCH( SMESH::throwCorbaException );
3372 return aMeshEdVar._retn();
3375 //=============================================================================
3377 * Return mesh edition previewer
3379 //=============================================================================
3381 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3382 throw (SALOME::SALOME_Exception)
3384 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3388 _preMeshInfo->FullLoadFromFile();
3390 if ( !_previewEditor )
3391 _previewEditor = new SMESH_MeshEditor_i( this, true );
3392 aMeshEdVar = _previewEditor->_this();
3394 SMESH_CATCH( SMESH::throwCorbaException );
3396 return aMeshEdVar._retn();
3399 //================================================================================
3401 * \brief Return true if the mesh has been edited since a last total re-compute
3402 * and those modifications may prevent successful partial re-compute
3404 //================================================================================
3406 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3408 Unexpect aCatch(SALOME_SalomeException);
3409 return _impl->HasModificationsToDiscard();
3412 //================================================================================
3414 * \brief Returns a random unique color
3416 //================================================================================
3418 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3420 const int MAX_ATTEMPTS = 100;
3422 double tolerance = 0.5;
3423 SALOMEDS::Color col;
3427 // generate random color
3428 double red = (double)rand() / RAND_MAX;
3429 double green = (double)rand() / RAND_MAX;
3430 double blue = (double)rand() / RAND_MAX;
3431 // check existence in the list of the existing colors
3432 bool matched = false;
3433 std::list<SALOMEDS::Color>::const_iterator it;
3434 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3435 SALOMEDS::Color color = *it;
3436 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3437 matched = tol < tolerance;
3439 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3440 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3448 //=============================================================================
3450 * Sets auto-color mode. If it is on, groups get unique random colors
3452 //=============================================================================
3454 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3456 Unexpect aCatch(SALOME_SalomeException);
3457 _impl->SetAutoColor(theAutoColor);
3459 TPythonDump pyDump; // not to dump group->SetColor() from below code
3460 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3462 std::list<SALOMEDS::Color> aReservedColors;
3463 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3464 for ( ; it != _mapGroups.end(); it++ ) {
3465 if ( CORBA::is_nil( it->second )) continue;
3466 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3467 it->second->SetColor( aColor );
3468 aReservedColors.push_back( aColor );
3472 //=============================================================================
3474 * Returns true if auto-color mode is on
3476 //=============================================================================
3478 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3480 Unexpect aCatch(SALOME_SalomeException);
3481 return _impl->GetAutoColor();
3484 //=============================================================================
3486 * Checks if there are groups with equal names
3488 //=============================================================================
3490 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3492 return _impl->HasDuplicatedGroupNamesMED();
3495 //================================================================================
3497 * \brief Care of a file before exporting mesh into it
3499 //================================================================================
3501 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3503 SMESH_File aFile( file, false );
3505 if ( aFile.exists() ) {
3506 // existing filesystem node
3507 if ( !aFile.isDirectory() ) {
3508 if ( aFile.openForWriting() ) {
3509 if ( overwrite && ! aFile.remove()) {
3510 msg << "Can't replace " << aFile.getName();
3513 msg << "Can't write into " << aFile.getName();
3516 msg << "Location " << aFile.getName() << " is not a file";
3520 // nonexisting file; check if it can be created
3521 if ( !aFile.openForWriting() ) {
3522 msg << "You cannot create the file "
3524 << ". Check the directory existence and access rights";
3532 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3536 //================================================================================
3538 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3539 * \param file - file name
3540 * \param overwrite - to erase the file or not
3541 * \retval string - mesh name
3543 //================================================================================
3545 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3546 CORBA::Boolean overwrite)
3549 PrepareForWriting(file, overwrite);
3550 string aMeshName = "Mesh";
3551 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3552 if ( !aStudy->_is_nil() ) {
3553 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3554 if ( !aMeshSO->_is_nil() ) {
3555 CORBA::String_var name = aMeshSO->GetName();
3557 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3558 if ( !aStudy->GetProperties()->IsLocked() )
3560 SALOMEDS::GenericAttribute_wrap anAttr;
3561 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3562 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3563 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3564 ASSERT(!aFileName->_is_nil());
3565 aFileName->SetValue(file);
3566 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3567 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3568 ASSERT(!aFileType->_is_nil());
3569 aFileType->SetValue("FICHIERMED");
3573 // Update Python script
3574 // set name of mesh before export
3575 TPythonDump() << _gen_i << ".SetName("
3576 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3578 // check names of groups
3584 //================================================================================
3586 * \brief Export to MED file
3588 //================================================================================
3590 void SMESH_Mesh_i::ExportMED(const char* file,
3591 CORBA::Boolean auto_groups,
3592 CORBA::Long version,
3593 CORBA::Boolean overwrite,
3594 CORBA::Boolean autoDimension)
3595 throw(SALOME::SALOME_Exception)
3597 //MESSAGE("MED minor version: "<< minor);
3600 _preMeshInfo->FullLoadFromFile();
3602 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3603 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3605 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3607 << "auto_groups=" <<auto_groups << ", "
3608 << "minor=" << version << ", "
3609 << "overwrite=" << overwrite << ", "
3610 << "meshPart=None, "
3611 << "autoDimension=" << autoDimension << " )";
3613 SMESH_CATCH( SMESH::throwCorbaException );
3616 //================================================================================
3618 * \brief Export a mesh to a SAUV file
3620 //================================================================================
3622 void SMESH_Mesh_i::ExportSAUV (const char* file,
3623 CORBA::Boolean auto_groups)
3624 throw(SALOME::SALOME_Exception)
3626 Unexpect aCatch(SALOME_SalomeException);
3628 _preMeshInfo->FullLoadFromFile();
3630 string aMeshName = prepareMeshNameAndGroups(file, true);
3631 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3632 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3633 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3637 //================================================================================
3639 * \brief Export a mesh to a DAT file
3641 //================================================================================
3643 void SMESH_Mesh_i::ExportDAT (const char *file)
3644 throw(SALOME::SALOME_Exception)
3646 Unexpect aCatch(SALOME_SalomeException);
3648 _preMeshInfo->FullLoadFromFile();
3650 // Update Python script
3651 // check names of groups
3653 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3656 PrepareForWriting(file);
3657 _impl->ExportDAT(file);
3660 //================================================================================
3662 * \brief Export a mesh to an UNV file
3664 //================================================================================
3666 void SMESH_Mesh_i::ExportUNV (const char *file)
3667 throw(SALOME::SALOME_Exception)
3669 Unexpect aCatch(SALOME_SalomeException);
3671 _preMeshInfo->FullLoadFromFile();
3673 // Update Python script
3674 // check names of groups
3676 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3679 PrepareForWriting(file);
3680 _impl->ExportUNV(file);
3683 //================================================================================
3685 * \brief Export a mesh to an STL file
3687 //================================================================================
3689 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3690 throw(SALOME::SALOME_Exception)
3692 Unexpect aCatch(SALOME_SalomeException);
3694 _preMeshInfo->FullLoadFromFile();
3696 // Update Python script
3697 // check names of groups
3699 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3700 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3702 CORBA::String_var name;
3703 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3704 if ( !so->_is_nil() )
3705 name = so->GetName();
3708 PrepareForWriting( file );
3709 _impl->ExportSTL( file, isascii, name.in() );
3712 //================================================================================
3714 * \brief Export a part of mesh to a med file
3716 //================================================================================
3718 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3720 CORBA::Boolean auto_groups,
3721 CORBA::Long version,
3722 CORBA::Boolean overwrite,
3723 CORBA::Boolean autoDimension,
3724 const GEOM::ListOfFields& fields,
3725 const char* geomAssocFields,
3726 CORBA::Double ZTolerance)
3727 throw (SALOME::SALOME_Exception)
3729 MESSAGE("MED version: "<< version);
3732 _preMeshInfo->FullLoadFromFile();
3735 bool have0dField = false;
3736 if ( fields.length() > 0 )
3738 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3739 if ( shapeToMesh->_is_nil() )
3740 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3742 for ( size_t i = 0; i < fields.length(); ++i )
3744 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3745 THROW_SALOME_CORBA_EXCEPTION
3746 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3747 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3748 if ( fieldShape->_is_nil() )
3749 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3750 if ( !fieldShape->IsSame( shapeToMesh ) )
3751 THROW_SALOME_CORBA_EXCEPTION
3752 ( "Field defined not on shape", SALOME::BAD_PARAM);
3753 if ( fields[i]->GetDimension() == 0 )
3756 if ( geomAssocFields )
3757 for ( int i = 0; geomAssocFields[i]; ++i )
3758 switch ( geomAssocFields[i] ) {
3759 case 'v':case 'e':case 'f':case 's': break;
3760 case 'V':case 'E':case 'F':case 'S': break;
3761 default: THROW_SALOME_CORBA_EXCEPTION
3762 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3766 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3770 string aMeshName = "Mesh";
3771 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3772 if ( CORBA::is_nil( meshPart ) ||
3773 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3775 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3776 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3777 0, autoDimension, /*addODOnVertices=*/have0dField,
3779 meshDS = _impl->GetMeshDS();
3784 _preMeshInfo->FullLoadFromFile();
3786 PrepareForWriting(file, overwrite);
3788 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3789 if ( !SO->_is_nil() ) {
3790 CORBA::String_var name = SO->GetName();
3794 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3795 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3796 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3797 meshDS = tmpDSDeleter._obj = partDS;
3802 if ( _impl->HasShapeToMesh() )
3804 DriverMED_W_Field fieldWriter;
3805 fieldWriter.SetFile( file );
3806 fieldWriter.SetMeshName( aMeshName );
3807 fieldWriter.AddODOnVertices( have0dField );
3809 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3813 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3814 goList->length( fields.length() );
3815 for ( size_t i = 0; i < fields.length(); ++i )
3817 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3820 TPythonDump() << _this() << ".ExportPartToMED( "
3821 << meshPart << ", r'"
3823 << auto_groups << ", "
3825 << overwrite << ", "
3826 << autoDimension << ", "
3828 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3829 << TVar( ZTolerance )
3832 SMESH_CATCH( SMESH::throwCorbaException );
3835 //================================================================================
3837 * Write GEOM fields to MED file
3839 //================================================================================
3841 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3842 SMESHDS_Mesh* meshDS,
3843 const GEOM::ListOfFields& fields,
3844 const char* geomAssocFields)
3846 #define METH "SMESH_Mesh_i::exportMEDFields() "
3848 if (( fields.length() < 1 ) &&
3849 ( !geomAssocFields || !geomAssocFields[0] ))
3852 std::vector< std::vector< double > > dblVals;
3853 std::vector< std::vector< int > > intVals;
3854 std::vector< int > subIdsByDim[ 4 ];
3855 const double noneDblValue = 0.;
3856 const double noneIntValue = 0;
3858 for ( size_t iF = 0; iF < fields.length(); ++iF )
3862 int dim = fields[ iF ]->GetDimension();
3863 SMDSAbs_ElementType elemType;
3864 TopAbs_ShapeEnum shapeType;
3866 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3867 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3868 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3869 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3871 continue; // skip fields on whole shape
3873 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3874 if ( dataType == GEOM::FDT_String )
3876 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3877 if ( stepIDs->length() < 1 )
3879 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3880 if ( comps->length() < 1 )
3882 CORBA::String_var name = fields[ iF ]->GetName();
3884 if ( !fieldWriter.Set( meshDS,
3888 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3891 for ( size_t iC = 0; iC < comps->length(); ++iC )
3892 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3894 dblVals.resize( comps->length() );
3895 intVals.resize( comps->length() );
3897 // find sub-shape IDs
3899 std::vector< int >& subIds = subIdsByDim[ dim ];
3900 if ( subIds.empty() )
3901 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3902 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3903 subIds.push_back( id );
3907 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3911 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3913 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3914 if ( step->_is_nil() )
3917 CORBA::Long stamp = step->GetStamp();
3918 CORBA::Long id = step->GetID();
3919 fieldWriter.SetDtIt( int( stamp ), int( id ));
3921 // fill dblVals or intVals
3922 for ( size_t iC = 0; iC < comps->length(); ++iC )
3923 if ( dataType == GEOM::FDT_Double )
3925 dblVals[ iC ].clear();
3926 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3930 intVals[ iC ].clear();
3931 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3935 case GEOM::FDT_Double:
3937 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3938 if ( dblStep->_is_nil() ) continue;
3939 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3940 if ( vv->length() != subIds.size() * comps->length() )
3941 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3942 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3943 for ( size_t iC = 0; iC < comps->length(); ++iC )
3944 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3949 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3950 if ( intStep->_is_nil() ) continue;
3951 GEOM::ListOfLong_var vv = intStep->GetValues();
3952 if ( vv->length() != subIds.size() * comps->length() )
3953 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3954 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3955 for ( size_t iC = 0; iC < comps->length(); ++iC )
3956 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3959 case GEOM::FDT_Bool:
3961 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3962 if ( boolStep->_is_nil() ) continue;
3963 GEOM::short_array_var vv = boolStep->GetValues();
3964 if ( vv->length() != subIds.size() * comps->length() )
3965 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3966 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3967 for ( size_t iC = 0; iC < comps->length(); ++iC )
3968 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3974 // pass values to fieldWriter
3975 elemIt = fieldWriter.GetOrderedElems();
3976 if ( dataType == GEOM::FDT_Double )
3977 while ( elemIt->more() )
3979 const SMDS_MeshElement* e = elemIt->next();
3980 const int shapeID = e->getshapeId();
3981 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3982 for ( size_t iC = 0; iC < comps->length(); ++iC )
3983 fieldWriter.AddValue( noneDblValue );
3985 for ( size_t iC = 0; iC < comps->length(); ++iC )
3986 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3989 while ( elemIt->more() )
3991 const SMDS_MeshElement* e = elemIt->next();
3992 const int shapeID = e->getshapeId();
3993 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3994 for ( size_t iC = 0; iC < comps->length(); ++iC )
3995 fieldWriter.AddValue( (double) noneIntValue );
3997 for ( size_t iC = 0; iC < comps->length(); ++iC )
3998 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
4002 fieldWriter.Perform();
4003 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4004 if ( res && res->IsKO() )
4006 if ( res->myComment.empty() )
4007 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4009 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4015 if ( !geomAssocFields || !geomAssocFields[0] )
4018 // write geomAssocFields
4020 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4021 shapeDim[ TopAbs_COMPOUND ] = 3;
4022 shapeDim[ TopAbs_COMPSOLID ] = 3;
4023 shapeDim[ TopAbs_SOLID ] = 3;
4024 shapeDim[ TopAbs_SHELL ] = 2;
4025 shapeDim[ TopAbs_FACE ] = 2;
4026 shapeDim[ TopAbs_WIRE ] = 1;
4027 shapeDim[ TopAbs_EDGE ] = 1;
4028 shapeDim[ TopAbs_VERTEX ] = 0;
4029 shapeDim[ TopAbs_SHAPE ] = 3;
4031 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4033 std::vector< std::string > compNames;
4034 switch ( geomAssocFields[ iF ]) {
4036 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4037 compNames.push_back( "dim" );
4040 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4043 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4046 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4050 compNames.push_back( "id" );
4051 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4052 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4054 fieldWriter.SetDtIt( -1, -1 );
4056 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4060 if ( compNames.size() == 2 ) // _vertices_
4061 while ( elemIt->more() )
4063 const SMDS_MeshElement* e = elemIt->next();
4064 const int shapeID = e->getshapeId();
4067 fieldWriter.AddValue( (double) -1 );
4068 fieldWriter.AddValue( (double) -1 );
4072 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4073 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4074 fieldWriter.AddValue( (double) shapeID );
4078 while ( elemIt->more() )
4080 const SMDS_MeshElement* e = elemIt->next();
4081 const int shapeID = e->getshapeId();
4083 fieldWriter.AddValue( (double) -1 );
4085 fieldWriter.AddValue( (double) shapeID );
4089 fieldWriter.Perform();
4090 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4091 if ( res && res->IsKO() )
4093 if ( res->myComment.empty() )
4094 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4096 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4099 } // loop on geomAssocFields
4104 //================================================================================
4106 * \brief Export a part of mesh to a DAT file
4108 //================================================================================
4110 void SMESH_Mesh_i::ExportPartToDAT(::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->ExportDAT(file,&partDS);
4123 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4124 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4126 //================================================================================
4128 * \brief Export a part of mesh to an UNV file
4130 //================================================================================
4132 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4134 throw (SALOME::SALOME_Exception)
4136 Unexpect aCatch(SALOME_SalomeException);
4138 _preMeshInfo->FullLoadFromFile();
4140 PrepareForWriting(file);
4142 SMESH_MeshPartDS partDS( meshPart );
4143 _impl->ExportUNV(file, &partDS);
4145 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4146 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4148 //================================================================================
4150 * \brief Export a part of mesh to an STL file
4152 //================================================================================
4154 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4156 ::CORBA::Boolean isascii)
4157 throw (SALOME::SALOME_Exception)
4159 Unexpect aCatch(SALOME_SalomeException);
4161 _preMeshInfo->FullLoadFromFile();
4163 PrepareForWriting(file);
4165 CORBA::String_var name;
4166 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4167 if ( !so->_is_nil() )
4168 name = so->GetName();
4170 SMESH_MeshPartDS partDS( meshPart );
4171 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4173 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4174 << meshPart<< ", r'" << file << "', " << isascii << ")";
4177 //================================================================================
4179 * \brief Export a part of mesh to an STL file
4181 //================================================================================
4183 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4185 CORBA::Boolean overwrite,
4186 CORBA::Boolean groupElemsByType)
4187 throw (SALOME::SALOME_Exception)
4190 Unexpect aCatch(SALOME_SalomeException);
4192 _preMeshInfo->FullLoadFromFile();
4194 PrepareForWriting(file,overwrite);
4196 std::string meshName("");
4197 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4198 if ( !so->_is_nil() )
4200 CORBA::String_var name = so->GetName();
4201 meshName = name.in();
4205 SMESH_MeshPartDS partDS( meshPart );
4206 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4208 SMESH_CATCH( SMESH::throwCorbaException );
4210 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4211 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4213 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4217 //================================================================================
4219 * \brief Export a part of mesh to a GMF file
4221 //================================================================================
4223 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4225 bool withRequiredGroups)
4226 throw (SALOME::SALOME_Exception)
4228 Unexpect aCatch(SALOME_SalomeException);
4230 _preMeshInfo->FullLoadFromFile();
4232 PrepareForWriting(file,/*overwrite=*/true);
4234 SMESH_MeshPartDS partDS( meshPart );
4235 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4237 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4238 << meshPart<< ", r'"
4240 << withRequiredGroups << ")";
4243 //=============================================================================
4245 * Return computation progress [0.,1]
4247 //=============================================================================
4249 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4253 return _impl->GetComputeProgress();
4255 SMESH_CATCH( SMESH::doNothing );
4259 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4261 Unexpect aCatch(SALOME_SalomeException);
4263 return _preMeshInfo->NbNodes();
4265 return _impl->NbNodes();
4268 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4270 Unexpect aCatch(SALOME_SalomeException);
4272 return _preMeshInfo->NbElements();
4274 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4277 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4279 Unexpect aCatch(SALOME_SalomeException);
4281 return _preMeshInfo->Nb0DElements();
4283 return _impl->Nb0DElements();
4286 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4288 Unexpect aCatch(SALOME_SalomeException);
4290 return _preMeshInfo->NbBalls();
4292 return _impl->NbBalls();
4295 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4297 Unexpect aCatch(SALOME_SalomeException);
4299 return _preMeshInfo->NbEdges();
4301 return _impl->NbEdges();
4304 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4305 throw(SALOME::SALOME_Exception)
4307 Unexpect aCatch(SALOME_SalomeException);
4309 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4311 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4314 //=============================================================================
4316 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4318 Unexpect aCatch(SALOME_SalomeException);
4320 return _preMeshInfo->NbFaces();
4322 return _impl->NbFaces();
4325 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4327 Unexpect aCatch(SALOME_SalomeException);
4329 return _preMeshInfo->NbTriangles();
4331 return _impl->NbTriangles();
4334 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4336 Unexpect aCatch(SALOME_SalomeException);
4338 return _preMeshInfo->NbBiQuadTriangles();
4340 return _impl->NbBiQuadTriangles();
4343 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4345 Unexpect aCatch(SALOME_SalomeException);
4347 return _preMeshInfo->NbQuadrangles();
4349 return _impl->NbQuadrangles();
4352 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4354 Unexpect aCatch(SALOME_SalomeException);
4356 return _preMeshInfo->NbBiQuadQuadrangles();
4358 return _impl->NbBiQuadQuadrangles();
4361 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4363 Unexpect aCatch(SALOME_SalomeException);
4365 return _preMeshInfo->NbPolygons();
4367 return _impl->NbPolygons();
4370 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4372 Unexpect aCatch(SALOME_SalomeException);
4374 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4376 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4379 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4380 throw(SALOME::SALOME_Exception)
4382 Unexpect aCatch(SALOME_SalomeException);
4384 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4386 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4389 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4390 throw(SALOME::SALOME_Exception)
4392 Unexpect aCatch(SALOME_SalomeException);
4394 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4396 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4399 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4400 throw(SALOME::SALOME_Exception)
4402 Unexpect aCatch(SALOME_SalomeException);
4404 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4406 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4409 //=============================================================================
4411 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4413 Unexpect aCatch(SALOME_SalomeException);
4415 return _preMeshInfo->NbVolumes();
4417 return _impl->NbVolumes();
4420 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4422 Unexpect aCatch(SALOME_SalomeException);
4424 return _preMeshInfo->NbTetras();
4426 return _impl->NbTetras();
4429 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4431 Unexpect aCatch(SALOME_SalomeException);
4433 return _preMeshInfo->NbHexas();
4435 return _impl->NbHexas();
4438 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4440 Unexpect aCatch(SALOME_SalomeException);
4442 return _preMeshInfo->NbTriQuadHexas();
4444 return _impl->NbTriQuadraticHexas();
4447 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4449 Unexpect aCatch(SALOME_SalomeException);
4451 return _preMeshInfo->NbPyramids();
4453 return _impl->NbPyramids();
4456 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4458 Unexpect aCatch(SALOME_SalomeException);
4460 return _preMeshInfo->NbPrisms();
4462 return _impl->NbPrisms();
4465 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4467 Unexpect aCatch(SALOME_SalomeException);
4469 return _preMeshInfo->NbHexPrisms();
4471 return _impl->NbHexagonalPrisms();
4474 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4476 Unexpect aCatch(SALOME_SalomeException);
4478 return _preMeshInfo->NbPolyhedrons();
4480 return _impl->NbPolyhedrons();
4483 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4484 throw(SALOME::SALOME_Exception)
4486 Unexpect aCatch(SALOME_SalomeException);
4488 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4490 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4493 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4494 throw(SALOME::SALOME_Exception)
4496 Unexpect aCatch(SALOME_SalomeException);
4498 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4500 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4503 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4504 throw(SALOME::SALOME_Exception)
4506 Unexpect aCatch(SALOME_SalomeException);
4508 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4510 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4513 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4514 throw(SALOME::SALOME_Exception)
4516 Unexpect aCatch(SALOME_SalomeException);
4518 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4520 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4523 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4524 throw(SALOME::SALOME_Exception)
4526 Unexpect aCatch(SALOME_SalomeException);
4528 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4530 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4533 //=============================================================================
4535 * Returns nb of published sub-meshes
4537 //=============================================================================
4539 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4541 Unexpect aCatch(SALOME_SalomeException);
4542 return _mapSubMesh_i.size();
4545 //=============================================================================
4547 * Dumps mesh into a string
4549 //=============================================================================
4551 char* SMESH_Mesh_i::Dump()
4555 return CORBA::string_dup( os.str().c_str() );
4558 //=============================================================================
4560 * Method of SMESH_IDSource interface
4562 //=============================================================================
4564 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4566 return GetElementsId();
4569 //=============================================================================
4571 * Returns ids of all elements
4573 //=============================================================================
4575 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4576 throw (SALOME::SALOME_Exception)
4578 Unexpect aCatch(SALOME_SalomeException);
4580 _preMeshInfo->FullLoadFromFile();
4582 SMESH::long_array_var aResult = new SMESH::long_array();
4583 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4585 if ( aSMESHDS_Mesh == NULL )
4586 return aResult._retn();
4588 long nbElements = NbElements();
4589 aResult->length( nbElements );
4590 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4591 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4592 aResult[i] = anIt->next()->GetID();
4594 return aResult._retn();
4598 //=============================================================================
4600 * Returns ids of all elements of given type
4602 //=============================================================================
4604 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4605 throw (SALOME::SALOME_Exception)
4607 Unexpect aCatch(SALOME_SalomeException);
4609 _preMeshInfo->FullLoadFromFile();
4611 SMESH::long_array_var aResult = new SMESH::long_array();
4612 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4614 if ( aSMESHDS_Mesh == NULL )
4615 return aResult._retn();
4617 long nbElements = NbElements();
4619 // No sense in returning ids of elements along with ids of nodes:
4620 // when theElemType == SMESH::ALL, return node ids only if
4621 // there are no elements
4622 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4623 return GetNodesId();
4625 aResult->length( nbElements );
4629 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4630 while ( i < nbElements && anIt->more() )
4631 aResult[i++] = anIt->next()->GetID();
4633 aResult->length( i );
4635 return aResult._retn();
4638 //=============================================================================
4640 * Returns ids of all nodes
4642 //=============================================================================
4644 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4645 throw (SALOME::SALOME_Exception)
4647 Unexpect aCatch(SALOME_SalomeException);
4649 _preMeshInfo->FullLoadFromFile();
4651 SMESH::long_array_var aResult = new SMESH::long_array();
4652 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4654 if ( aMeshDS == NULL )
4655 return aResult._retn();
4657 long nbNodes = NbNodes();
4658 aResult->length( nbNodes );
4659 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4660 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4661 aResult[i] = anIt->next()->GetID();
4663 return aResult._retn();
4666 //=============================================================================
4670 //=============================================================================
4672 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4673 throw (SALOME::SALOME_Exception)
4675 SMESH::ElementType type = SMESH::ALL;
4679 _preMeshInfo->FullLoadFromFile();
4681 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4683 SMESH_CATCH( SMESH::throwCorbaException );
4688 //=============================================================================
4692 //=============================================================================
4694 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4695 throw (SALOME::SALOME_Exception)
4698 _preMeshInfo->FullLoadFromFile();
4700 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4702 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4704 return ( SMESH::EntityType ) e->GetEntityType();
4707 //=============================================================================
4711 //=============================================================================
4713 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4714 throw (SALOME::SALOME_Exception)
4717 _preMeshInfo->FullLoadFromFile();
4719 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4721 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4723 return ( SMESH::GeometryType ) e->GetGeomType();
4726 //=============================================================================
4728 * Returns ID of elements for given submesh
4730 //=============================================================================
4731 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4732 throw (SALOME::SALOME_Exception)
4734 SMESH::long_array_var aResult = new SMESH::long_array();
4738 _preMeshInfo->FullLoadFromFile();
4740 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4741 if(!SM) return aResult._retn();
4743 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4744 if(!SDSM) return aResult._retn();
4746 aResult->length(SDSM->NbElements());
4748 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4750 while ( eIt->more() ) {
4751 aResult[i++] = eIt->next()->GetID();
4754 SMESH_CATCH( SMESH::throwCorbaException );
4756 return aResult._retn();
4759 //=============================================================================
4761 * Returns ID of nodes for given submesh
4762 * If param all==true - returns all nodes, else -
4763 * returns only nodes on shapes.
4765 //=============================================================================
4767 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4769 throw (SALOME::SALOME_Exception)
4771 SMESH::long_array_var aResult = new SMESH::long_array();
4775 _preMeshInfo->FullLoadFromFile();
4777 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4778 if(!SM) return aResult._retn();
4780 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4781 if(!SDSM) return aResult._retn();
4784 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4785 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4786 while ( nIt->more() ) {
4787 const SMDS_MeshNode* elem = nIt->next();
4788 theElems.insert( elem->GetID() );
4791 else { // all nodes of submesh elements
4792 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4793 while ( eIt->more() ) {
4794 const SMDS_MeshElement* anElem = eIt->next();
4795 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4796 while ( nIt->more() ) {
4797 const SMDS_MeshElement* elem = nIt->next();
4798 theElems.insert( elem->GetID() );
4803 aResult->length(theElems.size());
4804 set<int>::iterator itElem;
4806 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4807 aResult[i++] = *itElem;
4809 SMESH_CATCH( SMESH::throwCorbaException );
4811 return aResult._retn();
4814 //=============================================================================
4816 * Returns type of elements for given submesh
4818 //=============================================================================
4820 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4821 throw (SALOME::SALOME_Exception)
4823 SMESH::ElementType type = SMESH::ALL;
4827 _preMeshInfo->FullLoadFromFile();
4829 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4830 if(!SM) return SMESH::ALL;
4832 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4833 if(!SDSM) return SMESH::ALL;
4835 if(SDSM->NbElements()==0)
4836 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4838 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4839 const SMDS_MeshElement* anElem = eIt->next();
4841 type = ( SMESH::ElementType ) anElem->GetType();
4843 SMESH_CATCH( SMESH::throwCorbaException );
4849 //=============================================================================
4851 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4853 //=============================================================================
4855 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4858 _preMeshInfo->FullLoadFromFile();
4860 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4861 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4866 //=============================================================================
4868 * Get XYZ coordinates of node as list of double
4869 * If there is not node for given ID - returns empty list
4871 //=============================================================================
4873 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4876 _preMeshInfo->FullLoadFromFile();
4878 SMESH::double_array_var aResult = new SMESH::double_array();
4879 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4880 if ( aMeshDS == NULL )
4881 return aResult._retn();
4884 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4886 return aResult._retn();
4890 aResult[0] = aNode->X();
4891 aResult[1] = aNode->Y();
4892 aResult[2] = aNode->Z();
4893 return aResult._retn();
4897 //=============================================================================
4899 * For given node returns list of IDs of inverse elements
4900 * If there is not node for given ID - returns empty list
4902 //=============================================================================
4904 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4905 SMESH::ElementType elemType)
4908 _preMeshInfo->FullLoadFromFile();
4910 SMESH::long_array_var aResult = new SMESH::long_array();
4911 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4912 if ( aMeshDS == NULL )
4913 return aResult._retn();
4916 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4918 return aResult._retn();
4920 // find inverse elements
4921 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4922 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4923 aResult->length( aNode->NbInverseElements( type ));
4924 for( int i = 0; eIt->more(); ++i )
4926 const SMDS_MeshElement* elem = eIt->next();
4927 aResult[ i ] = elem->GetID();
4929 return aResult._retn();
4932 //=============================================================================
4934 * \brief Return position of a node on shape
4936 //=============================================================================
4938 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4941 _preMeshInfo->FullLoadFromFile();
4943 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4944 aNodePosition->shapeID = 0;
4945 aNodePosition->shapeType = GEOM::SHAPE;
4947 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4948 if ( !mesh ) return aNodePosition;
4950 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4952 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4954 aNodePosition->shapeID = aNode->getshapeId();
4955 switch ( pos->GetTypeOfPosition() ) {
4957 aNodePosition->shapeType = GEOM::EDGE;
4958 aNodePosition->params.length(1);
4959 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4961 case SMDS_TOP_FACE: {
4962 SMDS_FacePositionPtr fPos = pos;
4963 aNodePosition->shapeType = GEOM::FACE;
4964 aNodePosition->params.length(2);
4965 aNodePosition->params[0] = fPos->GetUParameter();
4966 aNodePosition->params[1] = fPos->GetVParameter();
4969 case SMDS_TOP_VERTEX:
4970 aNodePosition->shapeType = GEOM::VERTEX;
4972 case SMDS_TOP_3DSPACE:
4973 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4974 aNodePosition->shapeType = GEOM::SOLID;
4975 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4976 aNodePosition->shapeType = GEOM::SHELL;
4982 return aNodePosition;
4985 //=============================================================================
4987 * \brief Return position of an element on shape
4989 //=============================================================================
4991 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4994 _preMeshInfo->FullLoadFromFile();
4996 SMESH::ElementPosition anElementPosition;
4997 anElementPosition.shapeID = 0;
4998 anElementPosition.shapeType = GEOM::SHAPE;
5000 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
5001 if ( !mesh ) return anElementPosition;
5003 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
5005 anElementPosition.shapeID = anElem->getshapeId();
5006 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
5007 if ( !aSp.IsNull() ) {
5008 switch ( aSp.ShapeType() ) {
5010 anElementPosition.shapeType = GEOM::EDGE;
5013 anElementPosition.shapeType = GEOM::FACE;
5016 anElementPosition.shapeType = GEOM::VERTEX;
5019 anElementPosition.shapeType = GEOM::SOLID;
5022 anElementPosition.shapeType = GEOM::SHELL;
5028 return anElementPosition;
5031 //=============================================================================
5033 * If given element is node returns IDs of shape from position
5034 * If there is not node for given ID - returns -1
5036 //=============================================================================
5038 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5041 _preMeshInfo->FullLoadFromFile();
5043 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5044 if ( aMeshDS == NULL )
5048 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5050 return aNode->getshapeId();
5057 //=============================================================================
5059 * For given element returns ID of result shape after
5060 * ::FindShape() from SMESH_MeshEditor
5061 * If there is not element for given ID - returns -1
5063 //=============================================================================
5065 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5068 _preMeshInfo->FullLoadFromFile();
5070 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5071 if ( aMeshDS == NULL )
5074 // try to find element
5075 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5079 ::SMESH_MeshEditor aMeshEditor(_impl);
5080 int index = aMeshEditor.FindShape( elem );
5088 //=============================================================================
5090 * Returns number of nodes for given element
5091 * If there is not element for given ID - returns -1
5093 //=============================================================================
5095 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5098 _preMeshInfo->FullLoadFromFile();
5100 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5101 if ( aMeshDS == NULL ) return -1;
5102 // try to find element
5103 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5104 if(!elem) return -1;
5105 return elem->NbNodes();
5109 //=============================================================================
5111 * Returns ID of node by given index for given element
5112 * If there is not element for given ID - returns -1
5113 * If there is not node for given index - returns -2
5115 //=============================================================================
5117 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5120 _preMeshInfo->FullLoadFromFile();
5122 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5123 if ( aMeshDS == NULL ) return -1;
5124 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5125 if(!elem) return -1;
5126 if( index>=elem->NbNodes() || index<0 ) return -1;
5127 return elem->GetNode(index)->GetID();
5130 //=============================================================================
5132 * Returns IDs of nodes of given element
5134 //=============================================================================
5136 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5139 _preMeshInfo->FullLoadFromFile();
5141 SMESH::long_array_var aResult = new SMESH::long_array();
5142 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5144 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5146 aResult->length( elem->NbNodes() );
5147 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5148 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5149 aResult[ i ] = n->GetID();
5152 return aResult._retn();
5155 //=============================================================================
5157 * Returns true if given node is medium node
5158 * in given quadratic element
5160 //=============================================================================
5162 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5165 _preMeshInfo->FullLoadFromFile();
5167 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5168 if ( aMeshDS == NULL ) return false;
5170 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5171 if(!aNode) return false;
5172 // try to find element
5173 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5174 if(!elem) return false;
5176 return elem->IsMediumNode(aNode);
5180 //=============================================================================
5182 * Returns true if given node is medium node
5183 * in one of quadratic elements
5185 //=============================================================================
5187 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5188 SMESH::ElementType theElemType)
5191 _preMeshInfo->FullLoadFromFile();
5193 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5194 if ( aMeshDS == NULL ) return false;
5197 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5198 if(!aNode) return false;
5200 SMESH_MesherHelper aHelper( *(_impl) );
5202 SMDSAbs_ElementType aType;
5203 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5204 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5205 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5206 else aType = SMDSAbs_All;
5208 return aHelper.IsMedium(aNode,aType);
5212 //=============================================================================
5214 * Returns number of edges for given element
5216 //=============================================================================
5218 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5221 _preMeshInfo->FullLoadFromFile();
5223 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5224 if ( aMeshDS == NULL ) return -1;
5225 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5226 if(!elem) return -1;
5227 return elem->NbEdges();
5231 //=============================================================================
5233 * Returns number of faces for given element
5235 //=============================================================================
5237 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5240 _preMeshInfo->FullLoadFromFile();
5242 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5243 if ( aMeshDS == NULL ) return -1;
5244 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5245 if(!elem) return -1;
5246 return elem->NbFaces();
5249 //=======================================================================
5250 //function : GetElemFaceNodes
5251 //purpose : Returns nodes of given face (counted from zero) for given element.
5252 //=======================================================================
5254 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5255 CORBA::Short faceIndex)
5258 _preMeshInfo->FullLoadFromFile();
5260 SMESH::long_array_var aResult = new SMESH::long_array();
5261 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5263 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5265 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5266 if ( faceIndex < vtool.NbFaces() )
5268 aResult->length( vtool.NbFaceNodes( faceIndex ));
5269 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5270 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5271 aResult[ i ] = nn[ i ]->GetID();
5275 return aResult._retn();
5278 //=======================================================================
5279 //function : GetFaceNormal
5280 //purpose : Returns three components of normal of given mesh face.
5281 //=======================================================================
5283 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5284 CORBA::Boolean normalized)
5287 _preMeshInfo->FullLoadFromFile();
5289 SMESH::double_array_var aResult = new SMESH::double_array();
5291 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5294 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5296 aResult->length( 3 );
5297 aResult[ 0 ] = normal.X();
5298 aResult[ 1 ] = normal.Y();
5299 aResult[ 2 ] = normal.Z();
5302 return aResult._retn();
5305 //=======================================================================
5306 //function : FindElementByNodes
5307 //purpose : Returns an element based on all given nodes.
5308 //=======================================================================
5310 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5313 _preMeshInfo->FullLoadFromFile();
5315 CORBA::Long elemID(0);
5316 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5318 vector< const SMDS_MeshNode * > nn( nodes.length() );
5319 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5320 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5323 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5324 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5325 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5326 _impl->NbVolumes( ORDER_QUADRATIC )))
5327 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5329 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5334 //================================================================================
5336 * \brief Return elements including all given nodes.
5338 //================================================================================
5340 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5341 SMESH::ElementType elemType)
5344 _preMeshInfo->FullLoadFromFile();
5346 SMESH::long_array_var result = new SMESH::long_array();
5348 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5350 vector< const SMDS_MeshNode * > nn( nodes.length() );
5351 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5352 nn[i] = mesh->FindNode( nodes[i] );
5354 std::vector<const SMDS_MeshElement *> elems;
5355 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5356 result->length( elems.size() );
5357 for ( size_t i = 0; i < elems.size(); ++i )
5358 result[i] = elems[i]->GetID();
5360 return result._retn();
5363 //=============================================================================
5365 * Returns true if given element is polygon
5367 //=============================================================================
5369 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5372 _preMeshInfo->FullLoadFromFile();
5374 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5375 if ( aMeshDS == NULL ) return false;
5376 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5377 if(!elem) return false;
5378 return elem->IsPoly();
5382 //=============================================================================
5384 * Returns true if given element is quadratic
5386 //=============================================================================
5388 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5391 _preMeshInfo->FullLoadFromFile();
5393 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5394 if ( aMeshDS == NULL ) return false;
5395 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5396 if(!elem) return false;
5397 return elem->IsQuadratic();
5400 //=============================================================================
5402 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5404 //=============================================================================
5406 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5409 _preMeshInfo->FullLoadFromFile();
5411 if ( const SMDS_BallElement* ball =
5412 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5413 return ball->GetDiameter();
5418 //=============================================================================
5420 * Returns bary center for given element
5422 //=============================================================================
5424 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5427 _preMeshInfo->FullLoadFromFile();
5429 SMESH::double_array_var aResult = new SMESH::double_array();
5430 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5431 if ( aMeshDS == NULL )
5432 return aResult._retn();
5434 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5436 return aResult._retn();
5438 if(elem->GetType()==SMDSAbs_Volume) {
5439 SMDS_VolumeTool aTool;
5440 if(aTool.Set(elem)) {
5442 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5447 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5449 double x=0., y=0., z=0.;
5450 for(; anIt->more(); ) {
5452 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5466 return aResult._retn();
5469 //================================================================================
5471 * \brief Create a group of elements preventing computation of a sub-shape
5473 //================================================================================
5475 SMESH::ListOfGroups*
5476 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5477 const char* theGroupName )
5478 throw ( SALOME::SALOME_Exception )
5480 Unexpect aCatch(SALOME_SalomeException);
5482 if ( !theGroupName || strlen( theGroupName) == 0 )
5483 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5485 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5486 ::SMESH_MeshEditor::ElemFeatures elemType;
5488 // submesh by subshape id
5489 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5490 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5493 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5494 if ( error && error->HasBadElems() )
5496 // sort bad elements by type
5497 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5498 const list<const SMDS_MeshElement*>& badElems =
5499 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5500 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5501 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5502 for ( ; elemIt != elemEnd; ++elemIt )
5504 const SMDS_MeshElement* elem = *elemIt;
5505 if ( !elem ) continue;
5507 if ( elem->GetID() < 1 )
5509 // elem is a temporary element, make a real element
5510 vector< const SMDS_MeshNode* > nodes;
5511 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5512 while ( nIt->more() && elem )
5514 nodes.push_back( nIt->next() );
5515 if ( nodes.back()->GetID() < 1 )
5516 elem = 0; // a temporary element on temporary nodes
5520 ::SMESH_MeshEditor editor( _impl );
5521 elem = editor.AddElement( nodes, elemType.Init( elem ));
5525 elemsByType[ elem->GetType() ].push_back( elem );
5528 // how many groups to create?
5530 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5531 nbTypes += int( !elemsByType[ i ].empty() );
5532 groups->length( nbTypes );
5535 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5537 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5538 if ( elems.empty() ) continue;
5540 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5541 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5543 SMESH::SMESH_Mesh_var mesh = _this();
5544 SALOMEDS::SObject_wrap aSO =
5545 _gen_i->PublishGroup( mesh, groups[ iG ],
5546 GEOM::GEOM_Object::_nil(), theGroupName);
5548 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5549 if ( !grp_i ) continue;
5551 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5552 for ( size_t iE = 0; iE < elems.size(); ++iE )
5553 grpDS->SMDSGroup().Add( elems[ iE ]);
5558 return groups._retn();
5561 //=============================================================================
5563 * Create and publish group servants if any groups were imported or created anyhow
5565 //=============================================================================
5567 void SMESH_Mesh_i::CreateGroupServants()
5569 SMESH::SMESH_Mesh_var aMesh = _this();
5572 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5573 while ( groupIt->more() )
5575 ::SMESH_Group* group = groupIt->next();
5576 int anId = group->GetID();
5578 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5579 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5581 addedIDs.insert( anId );
5583 SMESH_GroupBase_i* aGroupImpl;
5585 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5586 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5588 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5589 shape = groupOnGeom->GetShape();
5592 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5595 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5596 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5597 aGroupImpl->Register();
5599 // register CORBA object for persistence
5600 int nextId = _gen_i->RegisterObject( groupVar );
5601 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5602 else { nextId = 0; } // avoid "unused variable" warning in release mode
5604 // publishing the groups in the study
5605 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5606 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5608 if ( !addedIDs.empty() )
5611 set<int>::iterator id = addedIDs.begin();
5612 for ( ; id != addedIDs.end(); ++id )
5614 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5615 int i = std::distance( _mapGroups.begin(), it );
5616 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5621 //=============================================================================
5623 * \brief Return true if all sub-meshes are computed OK - to update an icon
5625 //=============================================================================
5627 bool SMESH_Mesh_i::IsComputedOK()
5629 return _impl->IsComputedOK();
5632 //=============================================================================
5634 * \brief Return groups cantained in _mapGroups by their IDs
5636 //=============================================================================
5638 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5640 int nbGroups = groupIDs.size();
5641 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5642 aList->length( nbGroups );
5644 list<int>::const_iterator ids = groupIDs.begin();
5645 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5647 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5648 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5649 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5651 aList->length( nbGroups );
5652 return aList._retn();
5655 //=============================================================================
5657 * \brief Return information about imported file
5659 //=============================================================================
5661 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5663 SMESH::MedFileInfo_var res( _medFileInfo );
5664 if ( !res.operator->() ) {
5665 res = new SMESH::MedFileInfo;
5667 res->fileSize = res->major = res->minor = res->release = -1;
5672 //=======================================================================
5673 //function : FileInfoToString
5674 //purpose : Persistence of file info
5675 //=======================================================================
5677 std::string SMESH_Mesh_i::FileInfoToString()
5680 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5682 s = SMESH_Comment( _medFileInfo->fileSize )
5683 << " " << _medFileInfo->major
5684 << " " << _medFileInfo->minor
5685 << " " << _medFileInfo->release
5686 << " " << _medFileInfo->fileName;
5691 //=======================================================================
5692 //function : FileInfoFromString
5693 //purpose : Persistence of file info
5694 //=======================================================================
5696 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5698 std::string size, major, minor, release, fileName;
5699 std::istringstream is(info);
5700 is >> size >> major >> minor >> release;
5701 fileName = info.data() + ( size.size() + 1 +
5704 release.size()+ 1 );
5706 _medFileInfo = new SMESH::MedFileInfo();
5707 _medFileInfo->fileName = fileName.c_str();
5708 _medFileInfo->fileSize = atoi( size.c_str() );
5709 _medFileInfo->major = atoi( major.c_str() );
5710 _medFileInfo->minor = atoi( minor.c_str() );
5711 _medFileInfo->release = atoi( release.c_str() );
5714 //=============================================================================
5716 * \brief Pass names of mesh groups from study to mesh DS
5718 //=============================================================================
5720 void SMESH_Mesh_i::checkGroupNames()
5722 int nbGrp = NbGroups();
5726 SMESH::ListOfGroups* grpList = 0;
5727 // avoid dump of "GetGroups"
5729 // store python dump into a local variable inside local scope
5730 SMESH::TPythonDump pDump; // do not delete this line of code
5731 grpList = GetGroups();
5734 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5735 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5738 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5739 if ( aGrpSO->_is_nil() )
5741 // correct name of the mesh group if necessary
5742 const char* guiName = aGrpSO->GetName();
5743 if ( strcmp(guiName, aGrp->GetName()) )
5744 aGrp->SetName( guiName );
5748 //=============================================================================
5750 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5752 //=============================================================================
5753 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5755 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5759 //=============================================================================
5761 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5763 //=============================================================================
5765 char* SMESH_Mesh_i::GetParameters()
5767 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5770 //=============================================================================
5772 * \brief Returns list of notebook variables used for last Mesh operation
5774 //=============================================================================
5775 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5777 SMESH::string_array_var aResult = new SMESH::string_array();
5778 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5780 CORBA::String_var aParameters = GetParameters();
5781 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5782 if ( aSections->length() > 0 ) {
5783 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5784 aResult->length( aVars.length() );
5785 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5786 aResult[i] = CORBA::string_dup( aVars[i] );
5789 return aResult._retn();
5792 //=======================================================================
5793 //function : GetTypes
5794 //purpose : Returns types of elements it contains
5795 //=======================================================================
5797 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5800 return _preMeshInfo->GetTypes();
5802 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5806 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5807 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5808 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5809 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5810 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5811 if (_impl->NbNodes() &&
5812 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5813 types->length( nbTypes );
5815 return types._retn();
5818 //=======================================================================
5819 //function : GetMesh
5820 //purpose : Returns self
5821 //=======================================================================
5823 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5825 return SMESH::SMESH_Mesh::_duplicate( _this() );
5828 //=======================================================================
5829 //function : IsMeshInfoCorrect
5830 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5831 // * happen if mesh data is not yet fully loaded from the file of study.
5832 //=======================================================================
5834 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5836 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5839 //=============================================================================
5841 * \brief Returns number of mesh elements per each \a EntityType
5843 //=============================================================================
5845 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5848 return _preMeshInfo->GetMeshInfo();
5850 SMESH::long_array_var aRes = new SMESH::long_array();
5851 aRes->length(SMESH::Entity_Last);
5852 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5854 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5856 return aRes._retn();
5857 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5858 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5859 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5860 return aRes._retn();
5863 //=============================================================================
5865 * \brief Returns number of mesh elements per each \a ElementType
5867 //=============================================================================
5869 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5871 SMESH::long_array_var aRes = new SMESH::long_array();
5872 aRes->length(SMESH::NB_ELEMENT_TYPES);
5873 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5876 const SMDS_MeshInfo* meshInfo = 0;
5878 meshInfo = _preMeshInfo;
5879 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5880 meshInfo = & meshDS->GetMeshInfo();
5883 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5884 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5886 return aRes._retn();
5889 //=============================================================================
5891 * Collect statistic of mesh elements given by iterator
5893 //=============================================================================
5895 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5896 SMESH::long_array& theInfo)
5898 if (!theItr) return;
5899 while (theItr->more())
5900 theInfo[ theItr->next()->GetEntityType() ]++;
5902 //=============================================================================
5904 * Returns mesh unstructed grid information.
5906 //=============================================================================
5908 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5910 SALOMEDS::TMPFile_var SeqFile;
5911 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5912 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5914 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5915 aWriter->WriteToOutputStringOn();
5916 aWriter->SetInputData(aGrid);
5917 aWriter->SetFileTypeToBinary();
5919 char* str = aWriter->GetOutputString();
5920 int size = aWriter->GetOutputStringLength();
5922 //Allocate octet buffer of required size
5923 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5924 //Copy ostrstream content to the octet buffer
5925 memcpy(OctetBuf, str, size);
5926 //Create and return TMPFile
5927 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5931 return SeqFile._retn();
5934 //=============================================================================
5935 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5936 * SMESH::ElementType type) */
5938 using namespace SMESH::Controls;
5939 //-----------------------------------------------------------------------------
5940 struct PredicateIterator : public SMDS_ElemIterator
5942 SMDS_ElemIteratorPtr _elemIter;
5943 PredicatePtr _predicate;
5944 const SMDS_MeshElement* _elem;
5945 SMDSAbs_ElementType _type;
5947 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5948 PredicatePtr predicate,
5949 SMDSAbs_ElementType type):
5950 _elemIter(iterator), _predicate(predicate), _type(type)
5958 virtual const SMDS_MeshElement* next()
5960 const SMDS_MeshElement* res = _elem;
5962 while ( _elemIter->more() && !_elem )
5964 if ((_elem = _elemIter->next()) &&
5965 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5966 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5973 //-----------------------------------------------------------------------------
5974 struct IDSourceIterator : public SMDS_ElemIterator
5976 const CORBA::Long* _idPtr;
5977 const CORBA::Long* _idEndPtr;
5978 SMESH::long_array_var _idArray;
5979 const SMDS_Mesh* _mesh;
5980 const SMDSAbs_ElementType _type;
5981 const SMDS_MeshElement* _elem;
5983 IDSourceIterator( const SMDS_Mesh* mesh,
5984 const CORBA::Long* ids,
5986 SMDSAbs_ElementType type):
5987 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5989 if ( _idPtr && nbIds && _mesh )
5992 IDSourceIterator( const SMDS_Mesh* mesh,
5993 SMESH::long_array* idArray,
5994 SMDSAbs_ElementType type):
5995 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5997 if ( idArray && _mesh )
5999 _idPtr = &_idArray[0];
6000 _idEndPtr = _idPtr + _idArray->length();
6008 virtual const SMDS_MeshElement* next()
6010 const SMDS_MeshElement* res = _elem;
6012 while ( _idPtr < _idEndPtr && !_elem )
6014 if ( _type == SMDSAbs_Node )
6016 _elem = _mesh->FindNode( *_idPtr++ );
6018 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6019 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6027 //-----------------------------------------------------------------------------
6029 struct NodeOfElemIterator : public SMDS_ElemIterator
6031 TColStd_MapOfInteger _checkedNodeIDs;
6032 SMDS_ElemIteratorPtr _elemIter;
6033 SMDS_ElemIteratorPtr _nodeIter;
6034 const SMDS_MeshElement* _node;
6036 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6038 if ( _elemIter && _elemIter->more() )
6040 _nodeIter = _elemIter->next()->nodesIterator();
6048 virtual const SMDS_MeshElement* next()
6050 const SMDS_MeshElement* res = _node;
6052 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6054 if ( _nodeIter->more() )
6056 _node = _nodeIter->next();
6057 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6062 _nodeIter = _elemIter->next()->nodesIterator();
6070 //=============================================================================
6072 * Return iterator on elements of given type in given object
6074 //=============================================================================
6076 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6077 SMESH::ElementType theType)
6079 SMDS_ElemIteratorPtr elemIt;
6080 bool typeOK = ( theType == SMESH::ALL );
6081 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6083 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6084 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6085 if ( !mesh_i ) return elemIt;
6086 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6088 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6090 elemIt = meshDS->elementsIterator( elemType );
6093 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6095 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6098 elemIt = sm->GetElements();
6099 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6101 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6102 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6106 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6108 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6109 if ( groupDS && ( elemType == groupDS->GetType() ||
6110 elemType == SMDSAbs_Node ||
6111 elemType == SMDSAbs_All ))
6113 elemIt = groupDS->GetElements();
6114 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6117 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6119 if ( filter_i->GetElementType() == theType ||
6120 filter_i->GetElementType() == SMESH::ALL ||
6121 elemType == SMDSAbs_Node ||
6122 elemType == SMDSAbs_All)
6124 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6125 if ( pred_i && pred_i->GetPredicate() )
6127 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6128 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6129 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6130 elemIt = SMDS_ElemIteratorPtr
6131 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6132 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6138 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6139 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6140 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6142 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6143 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6146 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6147 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6151 SMESH::long_array_var ids = theObject->GetIDs();
6152 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6154 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6157 if ( elemIt && elemIt->more() && !typeOK )
6159 if ( elemType == SMDSAbs_Node )
6161 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6165 elemIt = SMDS_ElemIteratorPtr();
6171 //=============================================================================
6172 namespace // Finding concurrent hypotheses
6173 //=============================================================================
6177 * \brief mapping of mesh dimension into shape type
6179 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6181 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6183 case 0: aType = TopAbs_VERTEX; break;
6184 case 1: aType = TopAbs_EDGE; break;
6185 case 2: aType = TopAbs_FACE; break;
6187 default:aType = TopAbs_SOLID; break;
6192 //-----------------------------------------------------------------------------
6194 * \brief Internal structure used to find concurrent submeshes
6196 * It represents a pair < submesh, concurrent dimension >, where
6197 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6198 * with another submesh. In other words, it is dimension of a hypothesis assigned
6205 int _dim; //!< a dimension the algo can build (concurrent dimension)
6206 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6207 TopTools_MapOfShape _shapeMap;
6208 SMESH_subMesh* _subMesh;
6209 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6211 //-----------------------------------------------------------------------------
6212 // Return the algorithm
6213 const SMESH_Algo* GetAlgo() const
6214 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6216 //-----------------------------------------------------------------------------
6218 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6220 const TopoDS_Shape& theShape)
6222 _subMesh = (SMESH_subMesh*)theSubMesh;
6223 SetShape( theDim, theShape );
6226 //-----------------------------------------------------------------------------
6228 void SetShape(const int theDim,
6229 const TopoDS_Shape& theShape)
6232 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6233 if (_dim >= _ownDim)
6234 _shapeMap.Add( theShape );
6236 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6237 for( ; anExp.More(); anExp.Next() )
6238 _shapeMap.Add( anExp.Current() );
6242 //-----------------------------------------------------------------------------
6243 //! Check sharing of sub-shapes
6244 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6245 const TopTools_MapOfShape& theToFind,
6246 const TopAbs_ShapeEnum theType)
6248 bool isShared = false;
6249 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6250 for (; !isShared && anItr.More(); anItr.Next() )
6252 const TopoDS_Shape aSubSh = anItr.Key();
6253 // check for case when concurrent dimensions are same
6254 isShared = theToFind.Contains( aSubSh );
6255 // check for sub-shape with concurrent dimension
6256 TopExp_Explorer anExp( aSubSh, theType );
6257 for ( ; !isShared && anExp.More(); anExp.Next() )
6258 isShared = theToFind.Contains( anExp.Current() );
6263 //-----------------------------------------------------------------------------
6264 //! check algorithms
6265 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6266 const SMESHDS_Hypothesis* theA2)
6268 if ( !theA1 || !theA2 ||
6269 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6270 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6271 return false; // one of the hypothesis is not algorithm
6272 // check algorithm names (should be equal)
6273 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6277 //-----------------------------------------------------------------------------
6278 //! Check if sub-shape hypotheses are concurrent
6279 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6281 if ( _subMesh == theOther->_subMesh )
6282 return false; // same sub-shape - should not be
6284 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6285 // any of the two submeshes is not on COMPOUND shape )
6286 // -> no concurrency
6287 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6288 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6289 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6290 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6291 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6294 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6295 if ( !checkSubShape )
6298 // check algorithms to be same
6299 const SMESH_Algo* a1 = this->GetAlgo();
6300 const SMESH_Algo* a2 = theOther->GetAlgo();
6301 bool isSame = checkAlgo( a1, a2 );
6305 return false; // pb?
6306 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6309 // check hypothesises for concurrence (skip first as algorithm)
6311 // pointers should be same, because it is referened from mesh hypothesis partition
6312 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6313 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6314 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6315 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6317 // the submeshes are concurrent if their algorithms has different parameters
6318 return nbSame != theOther->_hypotheses.size() - 1;
6321 // Return true if algorithm of this SMESH_DimHyp is used if no
6322 // sub-mesh order is imposed by the user
6323 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6325 // NeedDiscreteBoundary() algo has a higher priority
6326 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6327 theOther->GetAlgo()->NeedDiscreteBoundary() )
6328 return !this->GetAlgo()->NeedDiscreteBoundary();
6330 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6333 }; // end of SMESH_DimHyp
6334 //-----------------------------------------------------------------------------
6336 typedef list<const SMESH_DimHyp*> TDimHypList;
6338 //-----------------------------------------------------------------------------
6340 void addDimHypInstance(const int theDim,
6341 const TopoDS_Shape& theShape,
6342 const SMESH_Algo* theAlgo,
6343 const SMESH_subMesh* theSubMesh,
6344 const list <const SMESHDS_Hypothesis*>& theHypList,
6345 TDimHypList* theDimHypListArr )
6347 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6348 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6349 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6350 dimHyp->_hypotheses.push_front(theAlgo);
6351 listOfdimHyp.push_back( dimHyp );
6354 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6355 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6356 theHypList.begin(), theHypList.end() );
6359 //-----------------------------------------------------------------------------
6360 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6361 TDimHypList& theListOfConcurr)
6363 if ( theListOfConcurr.empty() )
6365 theListOfConcurr.push_back( theDimHyp );
6369 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6370 while ( hypIt != theListOfConcurr.end() &&
6371 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6373 theListOfConcurr.insert( hypIt, theDimHyp );
6377 //-----------------------------------------------------------------------------
6378 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6379 const TDimHypList& theListOfDimHyp,
6380 TDimHypList& theListOfConcurrHyp,
6381 set<int>& theSetOfConcurrId )
6383 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6384 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6386 const SMESH_DimHyp* curDimHyp = *rIt;
6387 if ( curDimHyp == theDimHyp )
6388 break; // meet own dimHyp pointer in same dimension
6390 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6391 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6393 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6398 //-----------------------------------------------------------------------------
6399 void unionLists(TListOfInt& theListOfId,
6400 TListOfListOfInt& theListOfListOfId,
6403 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6404 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6406 continue; //skip already treated lists
6407 // check if other list has any same submesh object
6408 TListOfInt& otherListOfId = *it;
6409 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6410 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6413 // union two lists (from source into target)
6414 TListOfInt::iterator it2 = otherListOfId.begin();
6415 for ( ; it2 != otherListOfId.end(); it2++ ) {
6416 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6417 theListOfId.push_back(*it2);
6419 // clear source list
6420 otherListOfId.clear();
6423 //-----------------------------------------------------------------------------
6425 //! free memory allocated for dimension-hypothesis objects
6426 void removeDimHyps( TDimHypList* theArrOfList )
6428 for (int i = 0; i < 4; i++ ) {
6429 TDimHypList& listOfdimHyp = theArrOfList[i];
6430 TDimHypList::const_iterator it = listOfdimHyp.begin();
6431 for ( ; it != listOfdimHyp.end(); it++ )
6436 //-----------------------------------------------------------------------------
6438 * \brief find common submeshes with given submesh
6439 * \param theSubMeshList list of already collected submesh to check
6440 * \param theSubMesh given submesh to intersect with other
6441 * \param theCommonSubMeshes collected common submeshes
6443 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6444 const SMESH_subMesh* theSubMesh,
6445 set<const SMESH_subMesh*>& theCommon )
6449 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6450 for ( ; it != theSubMeshList.end(); it++ )
6451 theSubMesh->FindIntersection( *it, theCommon );
6452 theSubMeshList.push_back( theSubMesh );
6453 //theCommon.insert( theSubMesh );
6456 //-----------------------------------------------------------------------------
6457 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6459 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6460 for ( ; listsIt != smLists.end(); ++listsIt )
6462 const TListOfInt& smIDs = *listsIt;
6463 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6471 //=============================================================================
6473 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6475 //=============================================================================
6477 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6479 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6480 if ( isSubMeshInList( submeshID, anOrder ))
6483 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6484 return isSubMeshInList( submeshID, allConurrent );
6487 //=============================================================================
6489 * \brief Return submesh objects list in meshing order
6491 //=============================================================================
6493 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6495 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6497 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6499 return aResult._retn();
6501 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6502 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6503 anOrder.splice( anOrder.end(), allConurrent );
6506 TListOfListOfInt::iterator listIt = anOrder.begin();
6507 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6508 unionLists( *listIt, anOrder, listIndx + 1 );
6510 // convert submesh ids into interface instances
6511 // and dump command into python
6512 convertMeshOrder( anOrder, aResult, false );
6514 return aResult._retn();
6517 //=============================================================================
6519 * \brief Finds concurrent sub-meshes
6521 //=============================================================================
6523 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6525 TListOfListOfInt anOrder;
6526 ::SMESH_Mesh& mesh = GetImpl();
6528 // collect submeshes and detect concurrent algorithms and hypothesises
6529 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6531 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6532 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6533 ::SMESH_subMesh* sm = (*i_sm).second;
6535 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6537 // list of assigned hypothesises
6538 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6539 // Find out dimensions where the submesh can be concurrent.
6540 // We define the dimensions by algo of each of hypotheses in hypList
6541 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6542 for( ; hypIt != hypList.end(); hypIt++ ) {
6543 SMESH_Algo* anAlgo = 0;
6544 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6545 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6546 // hyp it-self is algo
6547 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6549 // try to find algorithm with help of sub-shapes
6550 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6551 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6552 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6555 continue; // no algorithm assigned to a current submesh
6557 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6558 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6560 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6561 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6562 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6564 } // end iterations on submesh
6566 // iterate on created dimension-hypotheses and check for concurrents
6567 for ( int i = 0; i < 4; i++ ) {
6568 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6569 // check for concurrents in own and other dimensions (step-by-step)
6570 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6571 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6572 const SMESH_DimHyp* dimHyp = *dhIt;
6573 TDimHypList listOfConcurr;
6574 set<int> setOfConcurrIds;
6575 // looking for concurrents and collect into own list
6576 for ( int j = i; j < 4; j++ )
6577 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6578 // check if any concurrents found
6579 if ( listOfConcurr.size() > 0 ) {
6580 // add own submesh to list of concurrent
6581 addInOrderOfPriority( dimHyp, listOfConcurr );
6582 list<int> listOfConcurrIds;
6583 TDimHypList::iterator hypIt = listOfConcurr.begin();
6584 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6585 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6586 anOrder.push_back( listOfConcurrIds );
6591 removeDimHyps(dimHypListArr);
6593 // now, minimize the number of concurrent groups
6594 // Here we assume that lists of submeshes can have same submesh
6595 // in case of multi-dimension algorithms, as result
6596 // list with common submesh has to be united into one list
6598 TListOfListOfInt::iterator listIt = anOrder.begin();
6599 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6600 unionLists( *listIt, anOrder, listIndx + 1 );
6606 //=============================================================================
6608 * \brief Set submesh object order
6609 * \param theSubMeshArray submesh array order
6611 //=============================================================================
6613 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6616 _preMeshInfo->ForgetOrLoad();
6619 ::SMESH_Mesh& mesh = GetImpl();
6621 TPythonDump aPythonDump; // prevent dump of called methods
6622 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6624 TListOfListOfInt subMeshOrder;
6625 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6627 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6628 TListOfInt subMeshIds;
6630 aPythonDump << ", ";
6631 aPythonDump << "[ ";
6632 // Collect subMeshes which should be clear
6633 // do it list-by-list, because modification of submesh order
6634 // take effect between concurrent submeshes only
6635 set<const SMESH_subMesh*> subMeshToClear;
6636 list<const SMESH_subMesh*> subMeshList;
6637 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6639 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6641 aPythonDump << ", ";
6642 aPythonDump << subMesh;
6643 subMeshIds.push_back( subMesh->GetId() );
6644 // detect common parts of submeshes
6645 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6646 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6648 aPythonDump << " ]";
6649 subMeshOrder.push_back( subMeshIds );
6651 // clear collected sub-meshes
6652 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6653 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6654 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6656 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6657 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6658 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6661 aPythonDump << " ])";
6663 mesh.SetMeshOrder( subMeshOrder );
6666 SMESH::SMESH_Mesh_var me = _this();
6667 _gen_i->UpdateIcons( me );
6672 //=============================================================================
6674 * \brief Convert submesh ids into submesh interfaces
6676 //=============================================================================
6678 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6679 SMESH::submesh_array_array& theResOrder,
6680 const bool theIsDump)
6682 int nbSet = theIdsOrder.size();
6683 TPythonDump aPythonDump; // prevent dump of called methods
6685 aPythonDump << "[ ";
6686 theResOrder.length(nbSet);
6687 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6689 for( ; it != theIdsOrder.end(); it++ ) {
6690 // translate submesh identificators into submesh objects
6691 // takeing into account real number of concurrent lists
6692 const TListOfInt& aSubOrder = (*it);
6693 if (!aSubOrder.size())
6696 aPythonDump << "[ ";
6697 // convert shape indices into interfaces
6698 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6699 aResSubSet->length(aSubOrder.size());
6700 TListOfInt::const_iterator subIt = aSubOrder.begin();
6702 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6703 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6705 SMESH::SMESH_subMesh_var subMesh =
6706 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6709 aPythonDump << ", ";
6710 aPythonDump << subMesh;
6712 aResSubSet[ j++ ] = subMesh;
6715 aPythonDump << " ]";
6717 theResOrder[ listIndx++ ] = aResSubSet;
6719 // correct number of lists
6720 theResOrder.length( listIndx );
6723 // finilise python dump
6724 aPythonDump << " ]";
6725 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6729 namespace // utils used by SMESH_MeshPartDS
6732 * \brief Class used to access to protected data of SMDS_MeshInfo
6734 struct TMeshInfo : public SMDS_MeshInfo
6736 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6739 * \brief Element holing its ID only
6741 struct TElemID : public SMDS_LinearEdge
6743 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6747 //================================================================================
6749 // Implementation of SMESH_MeshPartDS
6751 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6752 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6754 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6755 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6758 _meshDS = mesh_i->GetImpl().GetMeshDS();
6760 SetPersistentId( _meshDS->GetPersistentId() );
6762 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6764 // <meshPart> is the whole mesh
6765 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6767 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6768 myGroupSet = _meshDS->GetGroups();
6773 SMESH::long_array_var anIDs = meshPart->GetIDs();
6774 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6775 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6777 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6778 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6779 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6784 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6785 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6786 if ( _elements[ e->GetType() ].insert( e ).second )
6789 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6790 while ( nIt->more() )
6792 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6793 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6800 ShapeToMesh( _meshDS->ShapeToMesh() );
6802 _meshDS = 0; // to enforce iteration on _elements and _nodes
6805 // -------------------------------------------------------------------------------------
6806 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6807 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6810 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6811 for ( ; partIt != meshPart.end(); ++partIt )
6812 if ( const SMDS_MeshElement * e = *partIt )
6813 if ( _elements[ e->GetType() ].insert( e ).second )
6816 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6817 while ( nIt->more() )
6819 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6820 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6826 // -------------------------------------------------------------------------------------
6827 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6829 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6831 TElemID elem( IDelem );
6832 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6833 if ( !_elements[ iType ].empty() )
6835 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6836 if ( it != _elements[ iType ].end() )
6841 // -------------------------------------------------------------------------------------
6842 bool SMESH_MeshPartDS::HasNumerationHoles()
6844 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6846 return ( MinNodeID() != 1 ||
6847 MaxNodeID() != NbNodes() ||
6848 MinElementID() != 1 ||
6849 MaxElementID() != NbElements() );
6851 // -------------------------------------------------------------------------------------
6852 int SMESH_MeshPartDS::MaxNodeID() const
6854 if ( _meshDS ) return _meshDS->MaxNodeID();
6855 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6857 // -------------------------------------------------------------------------------------
6858 int SMESH_MeshPartDS::MinNodeID() const
6860 if ( _meshDS ) return _meshDS->MinNodeID();
6861 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6863 // -------------------------------------------------------------------------------------
6864 int SMESH_MeshPartDS::MaxElementID() const
6866 if ( _meshDS ) return _meshDS->MaxElementID();
6868 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6869 if ( !_elements[ iType ].empty() )
6870 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6873 // -------------------------------------------------------------------------------------
6874 int SMESH_MeshPartDS::MinElementID() const
6876 if ( _meshDS ) return _meshDS->MinElementID();
6878 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6879 if ( !_elements[ iType ].empty() )
6880 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6883 // -------------------------------------------------------------------------------------
6884 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6886 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6888 typedef SMDS_SetIterator
6889 <const SMDS_MeshElement*,
6890 TIDSortedElemSet::const_iterator,
6891 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6892 SMDS_MeshElement::GeomFilter
6895 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6897 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6898 _elements[type].end(),
6899 SMDS_MeshElement::GeomFilter( geomType )));
6901 // -------------------------------------------------------------------------------------
6902 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6904 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6906 typedef SMDS_SetIterator
6907 <const SMDS_MeshElement*,
6908 TIDSortedElemSet::const_iterator,
6909 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6910 SMDS_MeshElement::EntityFilter
6913 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6915 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6916 _elements[type].end(),
6917 SMDS_MeshElement::EntityFilter( entity )));
6919 // -------------------------------------------------------------------------------------
6920 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6922 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6923 if ( type == SMDSAbs_All && !_meshDS )
6925 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6927 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6928 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6930 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6932 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6933 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6935 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6936 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6938 // -------------------------------------------------------------------------------------
6939 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6940 iterType SMESH_MeshPartDS::methName() const \
6942 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6943 return _meshDS ? _meshDS->methName() : iterType \
6944 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6946 // -------------------------------------------------------------------------------------
6947 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6948 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6949 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6950 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6951 #undef _GET_ITER_DEFINE
6953 // END Implementation of SMESH_MeshPartDS
6955 //================================================================================