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 CORBA::String_var entry = geom->GetStudyEntry();
2102 groupData._groupEntry = entry.in();
2108 SALOMEDS::SObject_wrap groupSO = SMESH_Gen_i::getStudyServant()->FindObjectID( groupData._groupEntry.c_str() );
2109 if ( !groupSO->_is_nil() )
2111 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
2112 if ( CORBA::is_nil( groupObj )) return newShape;
2113 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
2115 // get indices of group items
2116 set<int> curIndices;
2117 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( geomGroup );
2118 GEOM::GEOM_IGroupOperations_wrap groupOp = geomGen->GetIGroupOperations();
2119 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
2120 for ( CORBA::ULong i = 0; i < ids->length(); ++i )
2121 curIndices.insert( ids[i] );
2123 if ( how == ONLY_IF_CHANGED && groupData._indices == curIndices )
2124 return newShape; // group not changed
2127 groupData._indices = curIndices;
2129 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2130 if ( !geomClient ) return newShape;
2131 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
2132 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
2133 newShape = _gen_i->GeomObjectToShape( geomGroup );
2136 if ( newShape.IsNull() ) {
2137 // geom group becomes empty - return empty compound
2138 TopoDS_Compound compound;
2139 BRep_Builder().MakeCompound(compound);
2140 newShape = compound;
2147 //-----------------------------------------------------------------------------
2149 * \brief Storage of shape and index used in CheckGeomGroupModif()
2151 struct TIndexedShape
2154 TopoDS_Shape _shape;
2155 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
2157 //-----------------------------------------------------------------------------
2159 * \brief Data to re-create a group on geometry
2161 struct TGroupOnGeomData
2164 TopoDS_Shape _shape;
2165 SMDSAbs_ElementType _type;
2167 Quantity_Color _color;
2169 TGroupOnGeomData( const SMESHDS_GroupOnGeom* group )
2171 _oldID = group->GetID();
2172 _type = group->GetType();
2173 _name = group->GetStoreName();
2174 _color = group->GetColor();
2178 //-----------------------------------------------------------------------------
2180 * \brief Check if a filter is still valid after geometry removal
2182 bool isValidGeomFilter( SMESH::Filter_var theFilter )
2184 if ( theFilter->_is_nil() )
2186 SMESH::Filter::Criteria_var criteria;
2187 theFilter->GetCriteria( criteria.out() );
2189 for ( CORBA::ULong iCr = 0; iCr < criteria->length(); ++iCr )
2191 const char* thresholdID = criteria[ iCr ].ThresholdID.in();
2193 switch ( criteria[ iCr ].Type )
2195 case SMESH::FT_BelongToGeom:
2196 case SMESH::FT_BelongToPlane:
2197 case SMESH::FT_BelongToCylinder:
2198 case SMESH::FT_BelongToGenSurface:
2199 case SMESH::FT_LyingOnGeom:
2200 entry = thresholdID;
2202 case SMESH::FT_ConnectedElements:
2205 entry = thresholdID;
2211 SMESH_Gen_i* gen = SMESH_Gen_i::GetSMESHGen();
2212 SALOMEDS::SObject_wrap so = gen->getStudyServant()->FindObjectID( entry.c_str() );
2213 if ( so->_is_nil() )
2215 CORBA::Object_var obj = so->GetObject();
2216 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( obj );
2217 if ( gen->GeomObjectToShape( geom ).IsNull() )
2220 } // loop on criteria
2226 //=============================================================================
2228 * \brief Update data if geometry changes
2232 //=============================================================================
2234 void SMESH_Mesh_i::CheckGeomModif( bool isBreakLink )
2236 SMESH::SMESH_Mesh_var me = _this();
2237 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2239 TPythonDump dumpNothing; // prevent any dump
2241 //bool removedFromClient = false;
2243 if ( mainGO->_is_nil() ) // GEOM_Client cleared or geometry removed? (IPAL52735, PAL23636)
2245 //removedFromClient = _impl->HasShapeToMesh();
2247 // try to find geometry by study reference
2248 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2249 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2250 if ( !meshSO->_is_nil() &&
2251 meshSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2252 geomRefSO->ReferencedObject( geomSO.inout() ))
2254 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2255 mainGO = GEOM::GEOM_Object::_narrow( geomObj );
2258 if ( mainGO->_is_nil() && // geometry removed ==>
2259 !geomRefSO->_is_nil() ) // remove geom dependent data: sub-meshes etc.
2261 // convert geom dependent groups into standalone ones
2262 CheckGeomGroupModif();
2264 _impl->ShapeToMesh( TopoDS_Shape() );
2266 // remove sub-meshes
2267 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2268 while ( i_sm != _mapSubMeshIor.end() )
2270 SMESH::SMESH_subMesh_ptr sm = i_sm->second;
2272 RemoveSubMesh( sm );
2274 // remove all children except groups in the study
2275 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2276 SALOMEDS::SObject_wrap so;
2277 for ( CORBA::Long tag = SMESH::Tag_RefOnShape; tag <= SMESH::Tag_LastSubMesh; ++tag )
2278 if ( meshSO->FindSubObject( tag, so.inout() ))
2279 builder->RemoveObjectWithChildren( so );
2281 _gen_i->SetPixMap( meshSO, "ICON_SMESH_TREE_MESH_IMPORTED" );
2287 if ( !_impl->HasShapeToMesh() ) return;
2290 // Update after group modification
2292 if ( mainGO->GetType() == GEOM_GROUP || // is group or not modified
2293 mainGO->GetTick() == _mainShapeTick )
2295 int nb = NbNodes() + NbElements();
2296 CheckGeomGroupModif();
2297 if ( nb != NbNodes() + NbElements() ) // something removed due to hypotheses change
2298 _gen_i->UpdateIcons( me );
2302 // Update after shape modification
2304 GEOM_Client* geomClient = _gen_i->GetShapeReader();
2305 if ( !geomClient ) return;
2306 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine( mainGO );
2307 if ( geomGen->_is_nil() ) return;
2308 CORBA::String_var geomComponentType = geomGen->ComponentDataType();
2309 bool isShaper = ( strcmp( geomComponentType.in(), "SHAPERSTUDY" ) == 0 );
2311 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
2312 geomClient->RemoveShapeFromBuffer( ior.in() );
2314 // Update data taking into account that if topology doesn't change
2315 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2318 _preMeshInfo->ForgetAllData();
2321 if ( isBreakLink || !isShaper )
2323 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2324 if ( newShape.IsNull() )
2327 _mainShapeTick = mainGO->GetTick();
2329 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2331 // store data of groups on geometry
2332 std::vector< TGroupOnGeomData > groupsData;
2333 const std::set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2334 groupsData.reserve( groups.size() );
2335 TopTools_DataMapOfShapeShape old2newShapeMap;
2336 std::set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2337 for ( ; g != groups.end(); ++g )
2339 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2341 groupsData.push_back( TGroupOnGeomData( group ));
2344 SMESH::SMESH_GroupOnGeom_var gog;
2345 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.find( group->GetID() );
2346 if ( i_grp != _mapGroups.end() )
2347 gog = SMESH::SMESH_GroupOnGeom::_narrow( i_grp->second );
2349 GEOM::GEOM_Object_var geom;
2350 if ( !gog->_is_nil() )
2354 SALOMEDS::SObject_wrap grpSO = _gen_i->ObjectToSObject( gog );
2355 SALOMEDS::SObject_wrap geomRefSO, geomSO;
2356 if ( !grpSO->_is_nil() &&
2357 grpSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2358 geomRefSO->ReferencedObject( geomSO.inout() ))
2360 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2361 geom = GEOM::GEOM_Object::_narrow( geomObj );
2366 geom = gog->GetShape();
2369 if ( !geom->_is_nil() )
2371 CORBA::String_var ior = geomGen->GetStringFromIOR( geom );
2372 geomClient->RemoveShapeFromBuffer( ior.in() );
2373 groupsData.back()._shape = _gen_i->GeomObjectToShape( geom );
2374 old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape );
2376 else if ( old2newShapeMap.IsBound( group->GetShape() ))
2378 groupsData.back()._shape = old2newShapeMap( group->GetShape() );
2382 // store assigned hypotheses
2383 std::vector< pair< int, THypList > > ids2Hyps;
2384 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2385 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2387 const TopoDS_Shape& s = s2hyps.Key();
2388 const THypList& hyps = s2hyps.ChangeValue();
2389 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2392 std::map< std::set<int>, int > ii2iMap; // group sub-ids to group id in SMESHDS
2394 // count shapes excluding compounds corresponding to geom groups
2395 int oldNbSubShapes = meshDS->MaxShapeIndex();
2396 for ( ; oldNbSubShapes > 0; --oldNbSubShapes )
2398 const TopoDS_Shape& s = meshDS->IndexToShape( oldNbSubShapes );
2399 if ( s.IsNull() || s.ShapeType() != TopAbs_COMPOUND )
2402 std::set<int> subIds;
2403 for ( TopoDS_Iterator it( s ); it.More(); it.Next() )
2404 subIds.insert( meshDS->ShapeToIndex( it.Value() ));
2405 ii2iMap.insert( std::make_pair( subIds, oldNbSubShapes ));
2408 // check if shape topology changes - save shape type per shape ID
2409 std::vector< TopAbs_ShapeEnum > shapeTypes( Max( oldNbSubShapes + 1, 1 ));
2410 for ( int shapeID = oldNbSubShapes; shapeID > 0; --shapeID )
2411 shapeTypes[ shapeID ] = meshDS->IndexToShape( shapeID ).ShapeType();
2413 // change shape to mesh
2414 _impl->ShapeToMesh( TopoDS_Shape() );
2415 _impl->ShapeToMesh( newShape );
2417 // check if shape topology changes - check new shape types
2418 bool sameTopology = ( oldNbSubShapes == meshDS->MaxShapeIndex() );
2419 for ( int shapeID = oldNbSubShapes; shapeID > 0 && sameTopology; --shapeID )
2421 const TopoDS_Shape& s = meshDS->IndexToShape( shapeID );
2422 sameTopology = ( !s.IsNull() && s.ShapeType() == shapeTypes[ shapeID ]);
2425 // re-add shapes (compounds) of geom groups
2426 std::map< int, int > old2newIDs; // group IDs
2427 std::list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2428 for ( ; data != _geomGroupData.end(); ++data )
2431 std::map< std::set<int>, int >::iterator ii2i = ii2iMap.find( data->_indices );
2432 if ( ii2i != ii2iMap.end() )
2433 oldID = ii2i->second;
2435 int how = ( isBreakLink || !sameTopology ) ? IS_BREAK_LINK : MAIN_TRANSFORMED;
2436 TopoDS_Shape newShape = newGroupShape( *data, how );
2437 if ( !newShape.IsNull() )
2439 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2441 TopoDS_Compound compound;
2442 BRep_Builder().MakeCompound( compound );
2443 BRep_Builder().Add( compound, newShape );
2444 newShape = compound;
2446 int newID = _impl->GetSubMesh( newShape )->GetId();
2447 if ( oldID && oldID != newID )
2448 old2newIDs.insert( std::make_pair( oldID, newID ));
2452 // re-assign hypotheses
2453 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2455 int sID = ids2Hyps[i].first;
2456 std::map< int, int >::iterator o2n = old2newIDs.find( sID );
2457 if ( o2n != old2newIDs.end() )
2459 else if ( sID != 1 )
2461 const TopoDS_Shape& s = meshDS->IndexToShape( sID );
2462 const THypList& hyps = ids2Hyps[i].second;
2463 THypList::const_iterator h = hyps.begin();
2464 for ( ; h != hyps.end(); ++h )
2465 _impl->AddHypothesis( s, (*h)->GetID() );
2469 // restore groups on geometry
2470 for ( size_t i = 0; i < groupsData.size(); ++i )
2472 const TGroupOnGeomData& data = groupsData[i];
2473 if ( data._shape.IsNull() )
2476 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2477 if ( i2g == _mapGroups.end() ) continue;
2479 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2480 if ( !gr_i ) continue;
2482 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), data._oldID, data._shape );
2484 _mapGroups.erase( i2g );
2486 g->GetGroupDS()->SetColor( data._color );
2489 std::map< int, int >::iterator o2n = old2newIDs.begin();
2490 for ( ; o2n != old2newIDs.end(); ++o2n )
2492 int newID = o2n->second, oldID = o2n->first;
2493 if ( !_mapSubMesh.count( oldID ))
2497 _mapSubMesh [ newID ] = _impl->GetSubMeshContaining( newID );
2498 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2499 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2501 _mapSubMesh. erase(oldID);
2502 _mapSubMesh_i. erase(oldID);
2503 _mapSubMeshIor.erase(oldID);
2505 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2508 // update _mapSubMesh
2509 std::map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2510 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2511 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2514 if ( !sameTopology )
2516 // remove invalid study sub-objects
2517 CheckGeomGroupModif();
2520 _gen_i->UpdateIcons( me );
2522 if ( !isBreakLink && isShaper )
2524 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( me );
2525 if ( !meshSO->_is_nil() )
2526 _gen_i->SetPixMap(meshSO, "ICON_SMESH_TREE_GEOM_MODIF");
2530 //=============================================================================
2532 * \brief Update objects depending on changed geom groups
2534 * NPAL16168: geometrical group edition from a submesh don't modify mesh computation
2535 * issue 0020210: Update of a smesh group after modification of the associated geom group
2537 //=============================================================================
2539 void SMESH_Mesh_i::CheckGeomGroupModif()
2541 // remove sub-meshes referring a removed sub-shapes (if main shape still exists)
2542 SALOMEDS::StudyBuilder_var builder = _gen_i->getStudyServant()->NewBuilder();
2543 GEOM::GEOM_Object_var mainGO = GetShapeToMesh();
2544 SALOMEDS::SObject_wrap meshSO = _gen_i->ObjectToSObject( SMESH::SMESH_Mesh_var( _this() ));
2545 if ( !mainGO->_is_nil() && !meshSO->_is_nil() )
2547 SALOMEDS::SObject_wrap rootSO, geomRefSO, geomSO;
2548 for ( CORBA::Long tag = SMESH::Tag_FirstSubMesh; tag <= SMESH::Tag_LastSubMesh; ++tag )
2549 if ( meshSO->FindSubObject( tag, rootSO.inout() ))
2551 int nbValid = 0, nbRemoved = 0;
2552 SALOMEDS::ChildIterator_wrap chItr = _gen_i->getStudyServant()->NewChildIterator( rootSO );
2553 for ( ; chItr->More(); chItr->Next() )
2555 SALOMEDS::SObject_wrap smSO = chItr->Value(); // sub-mesh SO
2556 if ( !smSO->_is_nil() &&
2557 smSO->FindSubObject( SMESH::Tag_RefOnShape, geomRefSO.inout() ) &&
2558 geomRefSO->ReferencedObject( geomSO.inout() )) // find geometry by reference
2560 CORBA::Object_var geomObj = _gen_i->SObjectToObject( geomSO );
2561 GEOM::GEOM_Object_var geom = GEOM::GEOM_Object::_narrow( geomObj );
2562 if ( !geom->_non_existent() )
2565 continue; // keep the sub-mesh
2568 CORBA::Object_var smObj = _gen_i->SObjectToObject( smSO );
2569 SMESH::SMESH_subMesh_var sm = SMESH::SMESH_subMesh::_narrow( smObj );
2570 if ( !sm->_is_nil() && !sm->_non_existent() )
2572 GEOM::GEOM_Object_var smGeom = sm->GetSubShape();
2573 if ( smGeom->_is_nil() )
2575 RemoveSubMesh( sm );
2582 _preMeshInfo->ForgetAllData(); // unknown hypothesis modified
2583 builder->RemoveObjectWithChildren( smSO ); // sub-shape removed before loading SMESH
2587 if ( /*nbRemoved > 0 &&*/ nbValid == 0 )
2588 builder->RemoveObjectWithChildren( rootSO );
2592 // check for removed sub-shapes and convert geom dependent groups into standalone ones
2593 std::map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2594 while ( i_gr != _mapGroups.end())
2596 SMESH::SMESH_GroupBase_ptr group = i_gr->second;
2598 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( group ), refSO;
2599 SMESH::SMESH_GroupOnGeom_var onGeom = SMESH::SMESH_GroupOnGeom::_narrow ( group );
2600 SMESH::SMESH_GroupOnFilter_var onFilt = SMESH::SMESH_GroupOnFilter::_narrow( group );
2601 bool isValidGeom = false;
2602 if ( !onGeom->_is_nil() )
2604 isValidGeom = ( ! GEOM::GEOM_Object_var( onGeom->GetShape() )->_is_nil() );
2606 else if ( !onFilt->_is_nil() )
2608 isValidGeom = isValidGeomFilter( onFilt->GetFilter() );
2612 isValidGeom = ( !groupSO->_is_nil() &&
2613 !groupSO->FindSubObject( SMESH::Tag_RefOnShape, refSO.inout() ));
2617 if ( !IsLoaded() || group->IsEmpty() )
2619 RemoveGroup( group );
2621 else if ( !onGeom->_is_nil() || !onFilt->_is_nil() )
2623 SMESH::SMESH_Group_var ( ConvertToStandalone( group ));
2625 else // is it possible?
2627 builder->RemoveObjectWithChildren( refSO );
2633 if ( !_impl->HasShapeToMesh() ) return;
2635 CORBA::Long nbEntities = NbNodes() + NbElements();
2637 // Check if group contents changed
2639 typedef map< string, TopoDS_Shape > TEntry2Geom;
2640 TEntry2Geom newGroupContents;
2642 list<TGeomGroupData>::iterator
2643 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2644 for ( ; data != dataEnd; ++data )
2646 pair< TEntry2Geom::iterator, bool > it_new =
2647 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2648 bool processedGroup = !it_new.second;
2649 TopoDS_Shape& newShape = it_new.first->second;
2650 if ( !processedGroup )
2651 newShape = newGroupShape( *data, ONLY_IF_CHANGED );
2652 if ( newShape.IsNull() )
2653 continue; // no changes
2656 _preMeshInfo->ForgetOrLoad();
2658 if ( processedGroup ) { // update group indices
2659 list<TGeomGroupData>::iterator data2 = data;
2660 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2661 data->_indices = data2->_indices;
2664 // Update SMESH objects according to new GEOM group contents
2666 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2667 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2669 int oldID = submesh->GetId();
2670 if ( !_mapSubMeshIor.count( oldID ))
2672 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2674 // update hypotheses
2675 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2676 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2677 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2679 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2680 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2682 // care of submeshes
2683 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2684 int newID = newSubmesh->GetId();
2685 if ( newID != oldID ) {
2686 _mapSubMesh [ newID ] = newSubmesh;
2687 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2688 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2689 _mapSubMesh. erase(oldID);
2690 _mapSubMesh_i. erase(oldID);
2691 _mapSubMeshIor.erase(oldID);
2692 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2697 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2698 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2699 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2701 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2703 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2704 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2705 ds->SetShape( newShape );
2710 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2711 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2713 // Remove groups and submeshes basing on removed sub-shapes
2715 TopTools_MapOfShape newShapeMap;
2716 TopoDS_Iterator shapeIt( newShape );
2717 for ( ; shapeIt.More(); shapeIt.Next() )
2718 newShapeMap.Add( shapeIt.Value() );
2720 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2721 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2723 if ( newShapeMap.Contains( shapeIt.Value() ))
2725 TopTools_IndexedMapOfShape oldShapeMap;
2726 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2727 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2729 const TopoDS_Shape& oldShape = oldShapeMap(i);
2730 int oldInd = meshDS->ShapeToIndex( oldShape );
2732 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2733 if ( i_smIor != _mapSubMeshIor.end() ) {
2734 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2737 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2738 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2740 // check if a group bases on oldInd shape
2741 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2742 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2743 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2744 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2746 RemoveGroup( i_grp->second ); // several groups can base on same shape
2747 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2752 // Reassign hypotheses and update groups after setting the new shape to mesh
2754 // collect anassigned hypotheses
2755 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2756 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2757 TShapeHypList assignedHyps;
2758 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2760 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2761 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2762 if ( !hyps.empty() ) {
2763 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2764 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2765 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2768 // collect shapes supporting groups
2769 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2770 TShapeTypeList groupData;
2771 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2772 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2773 for ( ; grIt != groups.end(); ++grIt )
2775 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2777 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2779 // set new shape to mesh -> DS of sub-meshes and geom groups is deleted
2781 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2782 _impl->ShapeToMesh( newShape );
2784 // reassign hypotheses
2785 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2786 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2788 TIndexedShape& geom = indS_hyps->first;
2789 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2790 int oldID = geom._index;
2791 int newID = meshDS->ShapeToIndex( geom._shape );
2792 if ( oldID == 1 ) { // main shape
2794 geom._shape = newShape;
2798 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2799 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2800 // care of sub-meshes
2801 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2802 if ( newID != oldID ) {
2803 _mapSubMesh [ newID ] = newSubmesh;
2804 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2805 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2806 _mapSubMesh. erase(oldID);
2807 _mapSubMesh_i. erase(oldID);
2808 _mapSubMeshIor.erase(oldID);
2809 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2813 TShapeTypeList::iterator geomType = groupData.begin();
2814 for ( ; geomType != groupData.end(); ++geomType )
2816 const TIndexedShape& geom = geomType->first;
2817 int oldID = geom._index;
2818 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2821 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( _mapGroups[oldID] );
2822 CORBA::String_var name = groupSO->GetName();
2824 if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID]))
2825 if ( SMESH_Group* group = _impl->AddGroup( geomType->second, name.in(),
2826 /*id=*/-1, geom._shape ))
2827 group_i->changeLocalId( group->GetID() );
2830 break; // everything has been updated
2833 } // loop on group data
2837 CORBA::Long newNbEntities = NbNodes() + NbElements();
2838 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2839 if ( newNbEntities != nbEntities )
2841 // Add all SObjects with icons to soToUpdateIcons
2842 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( _this() )); // mesh
2844 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2845 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2846 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_sm->second ));
2848 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2849 i_gr != _mapGroups.end(); ++i_gr ) // groups
2850 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( i_gr->second ));
2853 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2854 for ( ; so != soToUpdateIcons.end(); ++so )
2855 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2858 //=============================================================================
2860 * \brief Create standalone group from a group on geometry or filter
2862 //=============================================================================
2864 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2865 throw (SALOME::SALOME_Exception)
2867 SMESH::SMESH_Group_var aGroup;
2872 _preMeshInfo->FullLoadFromFile();
2874 if ( theGroup->_is_nil() )
2875 return aGroup._retn();
2877 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2879 return aGroup._retn();
2881 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2883 const int anId = aGroupToRem->GetLocalID();
2884 if ( !_impl->ConvertToStandalone( anId ) )
2885 return aGroup._retn();
2886 removeGeomGroupData( theGroup );
2888 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2890 // remove old instance of group from own map
2891 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2892 _mapGroups.erase( anId );
2894 SALOMEDS::StudyBuilder_var builder;
2895 SALOMEDS::SObject_wrap aGroupSO;
2896 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
2897 if ( !aStudy->_is_nil() ) {
2898 builder = aStudy->NewBuilder();
2899 aGroupSO = _gen_i->ObjectToSObject( theGroup );
2900 if ( !aGroupSO->_is_nil() )
2902 // remove reference to geometry
2903 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2904 for ( ; chItr->More(); chItr->Next() )
2906 // Remove group's child SObject
2907 SALOMEDS::SObject_wrap so = chItr->Value();
2908 builder->RemoveObject( so );
2910 // Update Python script
2911 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2912 << ".ConvertToStandalone( " << aGroupSO << " )";
2914 // change icon of Group on Filter
2917 // SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2918 // const int isEmpty = ( elemTypes->length() == 0 );
2921 SALOMEDS::GenericAttribute_wrap anAttr =
2922 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2923 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2924 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2930 // remember new group in own map
2931 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2932 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2934 // register CORBA object for persistence
2935 _gen_i->RegisterObject( aGroup );
2937 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2938 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2939 //aGroup->Register();
2940 aGroupToRem->UnRegister();
2942 SMESH_CATCH( SMESH::throwCorbaException );
2944 return aGroup._retn();
2947 //=============================================================================
2951 //=============================================================================
2953 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2955 if(MYDEBUG) MESSAGE( "createSubMesh" );
2956 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2957 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2960 SMESH_subMesh_i * subMeshServant;
2963 subMeshId = mySubMesh->GetId();
2964 subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2966 else // "invalid sub-mesh"
2968 // The invalid sub-mesh is created for the case where a valid sub-shape not found
2969 // by SMESH_Gen_i::CopyMeshWithGeom(). The invalid sub-mesh has GetId() < 0.
2970 if ( _mapSubMesh.empty() )
2973 subMeshId = _mapSubMesh.begin()->first - 1;
2974 subMeshServant = new SMESH_Invalid_subMesh_i(myPOA, _gen_i, this, subMeshId, theSubShapeObject);
2977 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2979 _mapSubMesh [subMeshId] = mySubMesh;
2980 _mapSubMesh_i [subMeshId] = subMeshServant;
2981 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2983 subMeshServant->Register();
2985 // register CORBA object for persistence
2986 int nextId = _gen_i->RegisterObject( subMesh );
2987 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2988 else { nextId = 0; } // avoid "unused variable" warning
2990 // to track changes of GEOM groups
2991 if ( subMeshId > 0 )
2992 addGeomGroupData( theSubShapeObject, subMesh );
2994 return subMesh._retn();
2997 //=======================================================================
2998 //function : getSubMesh
3000 //=======================================================================
3002 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
3004 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
3005 if ( it == _mapSubMeshIor.end() )
3006 return SMESH::SMESH_subMesh::_nil();
3008 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
3011 //=============================================================================
3015 //=============================================================================
3017 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
3018 GEOM::GEOM_Object_ptr theSubShapeObject )
3020 bool isHypChanged = false;
3021 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
3022 return isHypChanged;
3024 const int subMeshId = theSubMesh->GetId();
3026 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
3029 if (( _mapSubMesh.count( subMeshId )) &&
3030 ( sm = _impl->GetSubMeshContaining( subMeshId )))
3032 TopoDS_Shape S = sm->GetSubShape();
3035 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
3036 isHypChanged = !hyps.empty();
3037 if ( isHypChanged && _preMeshInfo )
3038 _preMeshInfo->ForgetOrLoad();
3039 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
3040 for ( ; hyp != hyps.end(); ++hyp )
3041 _impl->RemoveHypothesis(S, (*hyp)->GetID());
3048 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
3049 isHypChanged = ( aHypList->length() > 0 );
3050 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
3051 removeHypothesis( theSubShapeObject, aHypList[i] );
3054 catch( const SALOME::SALOME_Exception& ) {
3055 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
3057 removeGeomGroupData( theSubShapeObject );
3061 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
3062 if ( id_smi != _mapSubMesh_i.end() )
3063 id_smi->second->UnRegister();
3065 // remove a CORBA object
3066 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
3067 if ( id_smptr != _mapSubMeshIor.end() )
3068 SMESH::SMESH_subMesh_var( id_smptr->second );
3070 _mapSubMesh.erase(subMeshId);
3071 _mapSubMesh_i.erase(subMeshId);
3072 _mapSubMeshIor.erase(subMeshId);
3074 return isHypChanged;
3077 //=============================================================================
3081 //=============================================================================
3083 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
3084 const char* theName,
3086 const TopoDS_Shape& theShape,
3087 const SMESH_PredicatePtr& thePredicate )
3089 std::string newName;
3090 if ( !theName || !theName[0] )
3092 std::set< std::string > presentNames;
3093 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
3094 for ( ; i_gr != _mapGroups.end(); ++i_gr )
3096 CORBA::String_var name = i_gr->second->GetName();
3097 presentNames.insert( name.in() );
3100 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
3101 } while ( !presentNames.insert( newName ).second );
3102 theName = newName.c_str();
3104 SMESH::SMESH_GroupBase_var aGroup;
3105 if ( SMESH_Group* g = _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName,
3106 theID, theShape, thePredicate ))
3108 int anId = g->GetID();
3109 SMESH_GroupBase_i* aGroupImpl;
3110 if ( !theShape.IsNull() )
3111 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
3112 else if ( thePredicate )
3113 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
3115 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
3117 aGroup = aGroupImpl->_this();
3118 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
3119 aGroupImpl->Register();
3121 // register CORBA object for persistence
3122 int nextId = _gen_i->RegisterObject( aGroup );
3123 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
3124 else { nextId = ( nextId > 0 ); } // avoid "unused variable" warning in release mode
3126 // to track changes of GEOM groups
3127 if ( !theShape.IsNull() ) {
3128 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
3129 addGeomGroupData( geom, aGroup );
3132 return aGroup._retn();
3135 //=============================================================================
3137 * SMESH_Mesh_i::removeGroup
3139 * Should be called by ~SMESH_Group_i()
3141 //=============================================================================
3143 void SMESH_Mesh_i::removeGroup( const int theId )
3145 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
3146 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
3147 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
3148 _mapGroups.erase( theId );
3149 removeGeomGroupData( group );
3150 if ( !_impl->RemoveGroup( theId ))
3152 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
3153 RemoveGroup( group );
3155 group->UnRegister();
3159 //=============================================================================
3163 //=============================================================================
3165 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
3166 throw(SALOME::SALOME_Exception)
3168 SMESH::log_array_var aLog;
3172 _preMeshInfo->FullLoadFromFile();
3174 list < SMESHDS_Command * >logDS = _impl->GetLog();
3175 aLog = new SMESH::log_array;
3177 int lg = logDS.size();
3180 list < SMESHDS_Command * >::iterator its = logDS.begin();
3181 while(its != logDS.end()){
3182 SMESHDS_Command *com = *its;
3183 int comType = com->GetType();
3185 int lgcom = com->GetNumber();
3187 const list < int >&intList = com->GetIndexes();
3188 int inum = intList.size();
3190 list < int >::const_iterator ii = intList.begin();
3191 const list < double >&coordList = com->GetCoords();
3192 int rnum = coordList.size();
3194 list < double >::const_iterator ir = coordList.begin();
3195 aLog[indexLog].commandType = comType;
3196 aLog[indexLog].number = lgcom;
3197 aLog[indexLog].coords.length(rnum);
3198 aLog[indexLog].indexes.length(inum);
3199 for(int i = 0; i < rnum; i++){
3200 aLog[indexLog].coords[i] = *ir;
3201 //MESSAGE(" "<<i<<" "<<ir.Value());
3204 for(int i = 0; i < inum; i++){
3205 aLog[indexLog].indexes[i] = *ii;
3206 //MESSAGE(" "<<i<<" "<<ii.Value());
3215 SMESH_CATCH( SMESH::throwCorbaException );
3217 return aLog._retn();
3221 //=============================================================================
3225 //=============================================================================
3227 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
3231 SMESH_CATCH( SMESH::throwCorbaException );
3234 //=============================================================================
3238 //=============================================================================
3240 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
3245 //=============================================================================
3248 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
3249 // issue 0020918: groups removal is caused by hyp modification
3250 // issue 0021208: to forget not loaded mesh data at hyp modification
3251 struct TCallUp_i : public SMESH_Mesh::TCallUp
3253 SMESH_Mesh_i* _mesh;
3254 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
3255 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
3256 virtual void HypothesisModified( int hypID,
3257 bool updIcons) { _mesh->onHypothesisModified( hypID,
3259 virtual void Load () { _mesh->Load(); }
3260 virtual bool IsLoaded() { return _mesh->IsLoaded(); }
3264 //================================================================================
3266 * \brief callback from _impl to
3267 * 1) forget not loaded mesh data (issue 0021208)
3268 * 2) mark hypothesis as valid
3270 //================================================================================
3272 void SMESH_Mesh_i::onHypothesisModified(int theHypID, bool theUpdateIcons)
3275 _preMeshInfo->ForgetOrLoad();
3277 if ( theUpdateIcons )
3279 SMESH::SMESH_Mesh_var mesh = _this();
3280 _gen_i->UpdateIcons( mesh );
3283 if ( _nbInvalidHypos != 0 )
3285 // mark a hypothesis as valid after edition
3287 SALOMEDS::SComponent_wrap smeshComp = _gen_i->PublishComponent();
3288 SALOMEDS::SObject_wrap hypRoot;
3289 if ( !smeshComp->_is_nil() &&
3290 smeshComp->FindSubObject( _gen_i->GetHypothesisRootTag(), hypRoot.inout() ))
3292 SALOMEDS::ChildIterator_wrap anIter = _gen_i->getStudyServant()->NewChildIterator( hypRoot );
3293 for ( ; anIter->More(); anIter->Next() )
3295 SALOMEDS::SObject_wrap hypSO = anIter->Value();
3296 CORBA::Object_var obj = _gen_i->SObjectToObject( hypSO );
3297 SMESH::SMESH_Hypothesis_var hyp = SMESH::SMESH_Hypothesis::_narrow( obj );
3298 if ( !hyp->_is_nil() && hyp->GetId() == theHypID )
3299 _gen_i->HighLightInvalid( hyp, false );
3301 nbInvalid += _gen_i->IsInvalid( hypSO );
3304 _nbInvalidHypos = nbInvalid;
3308 //=============================================================================
3312 //=============================================================================
3314 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
3316 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
3319 _impl->SetCallUp( new TCallUp_i(this));
3322 //=============================================================================
3326 //=============================================================================
3328 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
3330 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
3334 //=============================================================================
3336 * Return mesh editor
3338 //=============================================================================
3340 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
3341 throw (SALOME::SALOME_Exception)
3343 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3347 _preMeshInfo->FullLoadFromFile();
3349 // Create MeshEditor
3351 _editor = new SMESH_MeshEditor_i( this, false );
3352 aMeshEdVar = _editor->_this();
3354 // Update Python script
3355 TPythonDump() << _editor << " = "
3356 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
3358 SMESH_CATCH( SMESH::throwCorbaException );
3360 return aMeshEdVar._retn();
3363 //=============================================================================
3365 * Return mesh edition previewer
3367 //=============================================================================
3369 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
3370 throw (SALOME::SALOME_Exception)
3372 SMESH::SMESH_MeshEditor_var aMeshEdVar;
3376 _preMeshInfo->FullLoadFromFile();
3378 if ( !_previewEditor )
3379 _previewEditor = new SMESH_MeshEditor_i( this, true );
3380 aMeshEdVar = _previewEditor->_this();
3382 SMESH_CATCH( SMESH::throwCorbaException );
3384 return aMeshEdVar._retn();
3387 //================================================================================
3389 * \brief Return true if the mesh has been edited since a last total re-compute
3390 * and those modifications may prevent successful partial re-compute
3392 //================================================================================
3394 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
3396 Unexpect aCatch(SALOME_SalomeException);
3397 return _impl->HasModificationsToDiscard();
3400 //================================================================================
3402 * \brief Returns a random unique color
3404 //================================================================================
3406 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
3408 const int MAX_ATTEMPTS = 100;
3410 double tolerance = 0.5;
3411 SALOMEDS::Color col;
3415 // generate random color
3416 double red = (double)rand() / RAND_MAX;
3417 double green = (double)rand() / RAND_MAX;
3418 double blue = (double)rand() / RAND_MAX;
3419 // check existence in the list of the existing colors
3420 bool matched = false;
3421 std::list<SALOMEDS::Color>::const_iterator it;
3422 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
3423 SALOMEDS::Color color = *it;
3424 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
3425 matched = tol < tolerance;
3427 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
3428 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
3436 //=============================================================================
3438 * Sets auto-color mode. If it is on, groups get unique random colors
3440 //=============================================================================
3442 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
3444 Unexpect aCatch(SALOME_SalomeException);
3445 _impl->SetAutoColor(theAutoColor);
3447 TPythonDump pyDump; // not to dump group->SetColor() from below code
3448 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
3450 std::list<SALOMEDS::Color> aReservedColors;
3451 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
3452 for ( ; it != _mapGroups.end(); it++ ) {
3453 if ( CORBA::is_nil( it->second )) continue;
3454 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
3455 it->second->SetColor( aColor );
3456 aReservedColors.push_back( aColor );
3460 //=============================================================================
3462 * Returns true if auto-color mode is on
3464 //=============================================================================
3466 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
3468 Unexpect aCatch(SALOME_SalomeException);
3469 return _impl->GetAutoColor();
3472 //=============================================================================
3474 * Checks if there are groups with equal names
3476 //=============================================================================
3478 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
3480 return _impl->HasDuplicatedGroupNamesMED();
3483 //================================================================================
3485 * \brief Care of a file before exporting mesh into it
3487 //================================================================================
3489 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
3491 SMESH_File aFile( file, false );
3493 if ( aFile.exists() ) {
3494 // existing filesystem node
3495 if ( !aFile.isDirectory() ) {
3496 if ( aFile.openForWriting() ) {
3497 if ( overwrite && ! aFile.remove()) {
3498 msg << "Can't replace " << aFile.getName();
3501 msg << "Can't write into " << aFile.getName();
3504 msg << "Location " << aFile.getName() << " is not a file";
3508 // nonexisting file; check if it can be created
3509 if ( !aFile.openForWriting() ) {
3510 msg << "You cannot create the file "
3512 << ". Check the directory existence and access rights";
3520 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
3524 //================================================================================
3526 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
3527 * \param file - file name
3528 * \param overwrite - to erase the file or not
3529 * \retval string - mesh name
3531 //================================================================================
3533 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
3534 CORBA::Boolean overwrite)
3537 PrepareForWriting(file, overwrite);
3538 string aMeshName = "Mesh";
3539 SALOMEDS::Study_var aStudy = SMESH_Gen_i::getStudyServant();
3540 if ( !aStudy->_is_nil() ) {
3541 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( _this() );
3542 if ( !aMeshSO->_is_nil() ) {
3543 CORBA::String_var name = aMeshSO->GetName();
3545 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
3546 if ( !aStudy->GetProperties()->IsLocked() )
3548 SALOMEDS::GenericAttribute_wrap anAttr;
3549 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
3550 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
3551 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
3552 ASSERT(!aFileName->_is_nil());
3553 aFileName->SetValue(file);
3554 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
3555 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
3556 ASSERT(!aFileType->_is_nil());
3557 aFileType->SetValue("FICHIERMED");
3561 // Update Python script
3562 // set name of mesh before export
3563 TPythonDump() << _gen_i << ".SetName("
3564 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3566 // check names of groups
3572 //================================================================================
3574 * \brief Export to MED file
3576 //================================================================================
3578 void SMESH_Mesh_i::ExportMED(const char* file,
3579 CORBA::Boolean auto_groups,
3580 CORBA::Long version,
3581 CORBA::Boolean overwrite,
3582 CORBA::Boolean autoDimension)
3583 throw(SALOME::SALOME_Exception)
3585 //MESSAGE("MED minor version: "<< minor);
3588 _preMeshInfo->FullLoadFromFile();
3590 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3591 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version, 0, autoDimension );
3593 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportMED( r'"
3595 << "auto_groups=" <<auto_groups << ", "
3596 << "minor=" << version << ", "
3597 << "overwrite=" << overwrite << ", "
3598 << "meshPart=None, "
3599 << "autoDimension=" << autoDimension << " )";
3601 SMESH_CATCH( SMESH::throwCorbaException );
3604 //================================================================================
3606 * \brief Export a mesh to a SAUV file
3608 //================================================================================
3610 void SMESH_Mesh_i::ExportSAUV (const char* file,
3611 CORBA::Boolean auto_groups)
3612 throw(SALOME::SALOME_Exception)
3614 Unexpect aCatch(SALOME_SalomeException);
3616 _preMeshInfo->FullLoadFromFile();
3618 string aMeshName = prepareMeshNameAndGroups(file, true);
3619 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3620 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3621 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3625 //================================================================================
3627 * \brief Export a mesh to a DAT file
3629 //================================================================================
3631 void SMESH_Mesh_i::ExportDAT (const char *file)
3632 throw(SALOME::SALOME_Exception)
3634 Unexpect aCatch(SALOME_SalomeException);
3636 _preMeshInfo->FullLoadFromFile();
3638 // Update Python script
3639 // check names of groups
3641 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3644 PrepareForWriting(file);
3645 _impl->ExportDAT(file);
3648 //================================================================================
3650 * \brief Export a mesh to an UNV file
3652 //================================================================================
3654 void SMESH_Mesh_i::ExportUNV (const char *file)
3655 throw(SALOME::SALOME_Exception)
3657 Unexpect aCatch(SALOME_SalomeException);
3659 _preMeshInfo->FullLoadFromFile();
3661 // Update Python script
3662 // check names of groups
3664 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3667 PrepareForWriting(file);
3668 _impl->ExportUNV(file);
3671 //================================================================================
3673 * \brief Export a mesh to an STL file
3675 //================================================================================
3677 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3678 throw(SALOME::SALOME_Exception)
3680 Unexpect aCatch(SALOME_SalomeException);
3682 _preMeshInfo->FullLoadFromFile();
3684 // Update Python script
3685 // check names of groups
3687 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3688 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3690 CORBA::String_var name;
3691 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( _this() );
3692 if ( !so->_is_nil() )
3693 name = so->GetName();
3696 PrepareForWriting( file );
3697 _impl->ExportSTL( file, isascii, name.in() );
3700 //================================================================================
3702 * \brief Export a part of mesh to a med file
3704 //================================================================================
3706 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3708 CORBA::Boolean auto_groups,
3709 CORBA::Long version,
3710 CORBA::Boolean overwrite,
3711 CORBA::Boolean autoDimension,
3712 const GEOM::ListOfFields& fields,
3713 const char* geomAssocFields,
3714 CORBA::Double ZTolerance)
3715 throw (SALOME::SALOME_Exception)
3717 MESSAGE("MED version: "<< version);
3720 _preMeshInfo->FullLoadFromFile();
3723 bool have0dField = false;
3724 if ( fields.length() > 0 )
3726 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3727 if ( shapeToMesh->_is_nil() )
3728 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3730 for ( size_t i = 0; i < fields.length(); ++i )
3732 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3733 THROW_SALOME_CORBA_EXCEPTION
3734 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3735 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3736 if ( fieldShape->_is_nil() )
3737 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3738 if ( !fieldShape->IsSame( shapeToMesh ) )
3739 THROW_SALOME_CORBA_EXCEPTION
3740 ( "Field defined not on shape", SALOME::BAD_PARAM);
3741 if ( fields[i]->GetDimension() == 0 )
3744 if ( geomAssocFields )
3745 for ( int i = 0; geomAssocFields[i]; ++i )
3746 switch ( geomAssocFields[i] ) {
3747 case 'v':case 'e':case 'f':case 's': break;
3748 case 'V':case 'E':case 'F':case 'S': break;
3749 default: THROW_SALOME_CORBA_EXCEPTION
3750 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3754 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3758 string aMeshName = "Mesh";
3759 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3760 if ( CORBA::is_nil( meshPart ) ||
3761 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3763 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3764 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3765 0, autoDimension, /*addODOnVertices=*/have0dField,
3767 meshDS = _impl->GetMeshDS();
3772 _preMeshInfo->FullLoadFromFile();
3774 PrepareForWriting(file, overwrite);
3776 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( meshPart );
3777 if ( !SO->_is_nil() ) {
3778 CORBA::String_var name = SO->GetName();
3782 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3783 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, version,
3784 partDS, autoDimension, /*addODOnVertices=*/have0dField, ZTolerance);
3785 meshDS = tmpDSDeleter._obj = partDS;
3790 if ( _impl->HasShapeToMesh() )
3792 DriverMED_W_Field fieldWriter;
3793 fieldWriter.SetFile( file );
3794 fieldWriter.SetMeshName( aMeshName );
3795 fieldWriter.AddODOnVertices( have0dField );
3797 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3801 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3802 goList->length( fields.length() );
3803 for ( size_t i = 0; i < fields.length(); ++i )
3805 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3808 TPythonDump() << _this() << ".ExportPartToMED( "
3809 << meshPart << ", r'"
3811 << auto_groups << ", "
3813 << overwrite << ", "
3814 << autoDimension << ", "
3816 << ( geomAssocFields ? geomAssocFields : "" ) << "',"
3817 << TVar( ZTolerance )
3820 SMESH_CATCH( SMESH::throwCorbaException );
3823 //================================================================================
3825 * Write GEOM fields to MED file
3827 //================================================================================
3829 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3830 SMESHDS_Mesh* meshDS,
3831 const GEOM::ListOfFields& fields,
3832 const char* geomAssocFields)
3834 #define METH "SMESH_Mesh_i::exportMEDFields() "
3836 if (( fields.length() < 1 ) &&
3837 ( !geomAssocFields || !geomAssocFields[0] ))
3840 std::vector< std::vector< double > > dblVals;
3841 std::vector< std::vector< int > > intVals;
3842 std::vector< int > subIdsByDim[ 4 ];
3843 const double noneDblValue = 0.;
3844 const double noneIntValue = 0;
3846 for ( size_t iF = 0; iF < fields.length(); ++iF )
3850 int dim = fields[ iF ]->GetDimension();
3851 SMDSAbs_ElementType elemType;
3852 TopAbs_ShapeEnum shapeType;
3854 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3855 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3856 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3857 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3859 continue; // skip fields on whole shape
3861 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3862 if ( dataType == GEOM::FDT_String )
3864 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3865 if ( stepIDs->length() < 1 )
3867 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3868 if ( comps->length() < 1 )
3870 CORBA::String_var name = fields[ iF ]->GetName();
3872 if ( !fieldWriter.Set( meshDS,
3876 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3879 for ( size_t iC = 0; iC < comps->length(); ++iC )
3880 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3882 dblVals.resize( comps->length() );
3883 intVals.resize( comps->length() );
3885 // find sub-shape IDs
3887 std::vector< int >& subIds = subIdsByDim[ dim ];
3888 if ( subIds.empty() )
3889 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3890 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3891 subIds.push_back( id );
3895 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3899 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3901 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3902 if ( step->_is_nil() )
3905 CORBA::Long stamp = step->GetStamp();
3906 CORBA::Long id = step->GetID();
3907 fieldWriter.SetDtIt( int( stamp ), int( id ));
3909 // fill dblVals or intVals
3910 for ( size_t iC = 0; iC < comps->length(); ++iC )
3911 if ( dataType == GEOM::FDT_Double )
3913 dblVals[ iC ].clear();
3914 dblVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3918 intVals[ iC ].clear();
3919 intVals[ iC ].resize( meshDS->MaxShapeIndex()+1, 0 );
3923 case GEOM::FDT_Double:
3925 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3926 if ( dblStep->_is_nil() ) continue;
3927 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3928 if ( vv->length() != subIds.size() * comps->length() )
3929 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3930 for ( size_t iS = 0, iV = 0; iS < subIds.size(); ++iS )
3931 for ( size_t iC = 0; iC < comps->length(); ++iC )
3932 dblVals[ iC ][ subIds[ iS ]] = vv[ iV++ ];
3937 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3938 if ( intStep->_is_nil() ) continue;
3939 GEOM::ListOfLong_var vv = intStep->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 intVals[ iC ][ subIds[ iS ]] = (int) vv[ iV++ ];
3947 case GEOM::FDT_Bool:
3949 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3950 if ( boolStep->_is_nil() ) continue;
3951 GEOM::short_array_var vv = boolStep->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++ ];
3962 // pass values to fieldWriter
3963 elemIt = fieldWriter.GetOrderedElems();
3964 if ( dataType == GEOM::FDT_Double )
3965 while ( elemIt->more() )
3967 const SMDS_MeshElement* e = elemIt->next();
3968 const int shapeID = e->getshapeId();
3969 if ( shapeID < 1 || shapeID >= (int) dblVals[0].size() )
3970 for ( size_t iC = 0; iC < comps->length(); ++iC )
3971 fieldWriter.AddValue( noneDblValue );
3973 for ( size_t iC = 0; iC < comps->length(); ++iC )
3974 fieldWriter.AddValue( dblVals[ iC ][ shapeID ]);
3977 while ( elemIt->more() )
3979 const SMDS_MeshElement* e = elemIt->next();
3980 const int shapeID = e->getshapeId();
3981 if ( shapeID < 1 || shapeID >= (int) intVals[0].size() )
3982 for ( size_t iC = 0; iC < comps->length(); ++iC )
3983 fieldWriter.AddValue( (double) noneIntValue );
3985 for ( size_t iC = 0; iC < comps->length(); ++iC )
3986 fieldWriter.AddValue( (double) intVals[ iC ][ shapeID ]);
3990 fieldWriter.Perform();
3991 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3992 if ( res && res->IsKO() )
3994 if ( res->myComment.empty() )
3995 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3997 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4003 if ( !geomAssocFields || !geomAssocFields[0] )
4006 // write geomAssocFields
4008 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
4009 shapeDim[ TopAbs_COMPOUND ] = 3;
4010 shapeDim[ TopAbs_COMPSOLID ] = 3;
4011 shapeDim[ TopAbs_SOLID ] = 3;
4012 shapeDim[ TopAbs_SHELL ] = 2;
4013 shapeDim[ TopAbs_FACE ] = 2;
4014 shapeDim[ TopAbs_WIRE ] = 1;
4015 shapeDim[ TopAbs_EDGE ] = 1;
4016 shapeDim[ TopAbs_VERTEX ] = 0;
4017 shapeDim[ TopAbs_SHAPE ] = 3;
4019 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
4021 std::vector< std::string > compNames;
4022 switch ( geomAssocFields[ iF ]) {
4024 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
4025 compNames.push_back( "dim" );
4028 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
4031 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
4034 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
4038 compNames.push_back( "id" );
4039 for ( size_t iC = 0; iC < compNames.size(); ++iC )
4040 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
4042 fieldWriter.SetDtIt( -1, -1 );
4044 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
4048 if ( compNames.size() == 2 ) // _vertices_
4049 while ( elemIt->more() )
4051 const SMDS_MeshElement* e = elemIt->next();
4052 const int shapeID = e->getshapeId();
4055 fieldWriter.AddValue( (double) -1 );
4056 fieldWriter.AddValue( (double) -1 );
4060 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
4061 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
4062 fieldWriter.AddValue( (double) shapeID );
4066 while ( elemIt->more() )
4068 const SMDS_MeshElement* e = elemIt->next();
4069 const int shapeID = e->getshapeId();
4071 fieldWriter.AddValue( (double) -1 );
4073 fieldWriter.AddValue( (double) shapeID );
4077 fieldWriter.Perform();
4078 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
4079 if ( res && res->IsKO() )
4081 if ( res->myComment.empty() )
4082 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
4084 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
4087 } // loop on geomAssocFields
4092 //================================================================================
4094 * \brief Export a part of mesh to a DAT file
4096 //================================================================================
4098 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
4100 throw (SALOME::SALOME_Exception)
4102 Unexpect aCatch(SALOME_SalomeException);
4104 _preMeshInfo->FullLoadFromFile();
4106 PrepareForWriting(file);
4108 SMESH_MeshPartDS partDS( meshPart );
4109 _impl->ExportDAT(file,&partDS);
4111 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4112 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
4114 //================================================================================
4116 * \brief Export a part of mesh to an UNV file
4118 //================================================================================
4120 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
4122 throw (SALOME::SALOME_Exception)
4124 Unexpect aCatch(SALOME_SalomeException);
4126 _preMeshInfo->FullLoadFromFile();
4128 PrepareForWriting(file);
4130 SMESH_MeshPartDS partDS( meshPart );
4131 _impl->ExportUNV(file, &partDS);
4133 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
4134 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
4136 //================================================================================
4138 * \brief Export a part of mesh to an STL file
4140 //================================================================================
4142 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
4144 ::CORBA::Boolean isascii)
4145 throw (SALOME::SALOME_Exception)
4147 Unexpect aCatch(SALOME_SalomeException);
4149 _preMeshInfo->FullLoadFromFile();
4151 PrepareForWriting(file);
4153 CORBA::String_var name;
4154 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4155 if ( !so->_is_nil() )
4156 name = so->GetName();
4158 SMESH_MeshPartDS partDS( meshPart );
4159 _impl->ExportSTL( file, isascii, name.in(), &partDS );
4161 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
4162 << meshPart<< ", r'" << file << "', " << isascii << ")";
4165 //================================================================================
4167 * \brief Export a part of mesh to an STL file
4169 //================================================================================
4171 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
4173 CORBA::Boolean overwrite,
4174 CORBA::Boolean groupElemsByType)
4175 throw (SALOME::SALOME_Exception)
4178 Unexpect aCatch(SALOME_SalomeException);
4180 _preMeshInfo->FullLoadFromFile();
4182 PrepareForWriting(file,overwrite);
4184 std::string meshName("");
4185 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( meshPart );
4186 if ( !so->_is_nil() )
4188 CORBA::String_var name = so->GetName();
4189 meshName = name.in();
4193 SMESH_MeshPartDS partDS( meshPart );
4194 _impl->ExportCGNS(file, &partDS, meshName.c_str(), groupElemsByType );
4196 SMESH_CATCH( SMESH::throwCorbaException );
4198 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
4199 << meshPart<< ", r'" << file << "', " << overwrite << ")";
4201 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
4205 //================================================================================
4207 * \brief Export a part of mesh to a GMF file
4209 //================================================================================
4211 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
4213 bool withRequiredGroups)
4214 throw (SALOME::SALOME_Exception)
4216 Unexpect aCatch(SALOME_SalomeException);
4218 _preMeshInfo->FullLoadFromFile();
4220 PrepareForWriting(file,/*overwrite=*/true);
4222 SMESH_MeshPartDS partDS( meshPart );
4223 _impl->ExportGMF(file, &partDS, withRequiredGroups);
4225 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
4226 << meshPart<< ", r'"
4228 << withRequiredGroups << ")";
4231 //=============================================================================
4233 * Return computation progress [0.,1]
4235 //=============================================================================
4237 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
4241 return _impl->GetComputeProgress();
4243 SMESH_CATCH( SMESH::doNothing );
4247 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
4249 Unexpect aCatch(SALOME_SalomeException);
4251 return _preMeshInfo->NbNodes();
4253 return _impl->NbNodes();
4256 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
4258 Unexpect aCatch(SALOME_SalomeException);
4260 return _preMeshInfo->NbElements();
4262 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
4265 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
4267 Unexpect aCatch(SALOME_SalomeException);
4269 return _preMeshInfo->Nb0DElements();
4271 return _impl->Nb0DElements();
4274 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
4276 Unexpect aCatch(SALOME_SalomeException);
4278 return _preMeshInfo->NbBalls();
4280 return _impl->NbBalls();
4283 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
4285 Unexpect aCatch(SALOME_SalomeException);
4287 return _preMeshInfo->NbEdges();
4289 return _impl->NbEdges();
4292 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
4293 throw(SALOME::SALOME_Exception)
4295 Unexpect aCatch(SALOME_SalomeException);
4297 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
4299 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
4302 //=============================================================================
4304 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
4306 Unexpect aCatch(SALOME_SalomeException);
4308 return _preMeshInfo->NbFaces();
4310 return _impl->NbFaces();
4313 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
4315 Unexpect aCatch(SALOME_SalomeException);
4317 return _preMeshInfo->NbTriangles();
4319 return _impl->NbTriangles();
4322 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
4324 Unexpect aCatch(SALOME_SalomeException);
4326 return _preMeshInfo->NbBiQuadTriangles();
4328 return _impl->NbBiQuadTriangles();
4331 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
4333 Unexpect aCatch(SALOME_SalomeException);
4335 return _preMeshInfo->NbQuadrangles();
4337 return _impl->NbQuadrangles();
4340 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
4342 Unexpect aCatch(SALOME_SalomeException);
4344 return _preMeshInfo->NbBiQuadQuadrangles();
4346 return _impl->NbBiQuadQuadrangles();
4349 CORBA::Long SMESH_Mesh_i::NbPolygons() throw(SALOME::SALOME_Exception)
4351 Unexpect aCatch(SALOME_SalomeException);
4353 return _preMeshInfo->NbPolygons();
4355 return _impl->NbPolygons();
4358 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
4360 Unexpect aCatch(SALOME_SalomeException);
4362 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
4364 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
4367 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
4368 throw(SALOME::SALOME_Exception)
4370 Unexpect aCatch(SALOME_SalomeException);
4372 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
4374 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
4377 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
4378 throw(SALOME::SALOME_Exception)
4380 Unexpect aCatch(SALOME_SalomeException);
4382 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
4384 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
4387 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
4388 throw(SALOME::SALOME_Exception)
4390 Unexpect aCatch(SALOME_SalomeException);
4392 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
4394 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
4397 //=============================================================================
4399 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
4401 Unexpect aCatch(SALOME_SalomeException);
4403 return _preMeshInfo->NbVolumes();
4405 return _impl->NbVolumes();
4408 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
4410 Unexpect aCatch(SALOME_SalomeException);
4412 return _preMeshInfo->NbTetras();
4414 return _impl->NbTetras();
4417 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
4419 Unexpect aCatch(SALOME_SalomeException);
4421 return _preMeshInfo->NbHexas();
4423 return _impl->NbHexas();
4426 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
4428 Unexpect aCatch(SALOME_SalomeException);
4430 return _preMeshInfo->NbTriQuadHexas();
4432 return _impl->NbTriQuadraticHexas();
4435 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
4437 Unexpect aCatch(SALOME_SalomeException);
4439 return _preMeshInfo->NbPyramids();
4441 return _impl->NbPyramids();
4444 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
4446 Unexpect aCatch(SALOME_SalomeException);
4448 return _preMeshInfo->NbPrisms();
4450 return _impl->NbPrisms();
4453 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
4455 Unexpect aCatch(SALOME_SalomeException);
4457 return _preMeshInfo->NbHexPrisms();
4459 return _impl->NbHexagonalPrisms();
4462 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
4464 Unexpect aCatch(SALOME_SalomeException);
4466 return _preMeshInfo->NbPolyhedrons();
4468 return _impl->NbPolyhedrons();
4471 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
4472 throw(SALOME::SALOME_Exception)
4474 Unexpect aCatch(SALOME_SalomeException);
4476 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
4478 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
4481 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
4482 throw(SALOME::SALOME_Exception)
4484 Unexpect aCatch(SALOME_SalomeException);
4486 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
4488 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
4491 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
4492 throw(SALOME::SALOME_Exception)
4494 Unexpect aCatch(SALOME_SalomeException);
4496 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
4498 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
4501 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
4502 throw(SALOME::SALOME_Exception)
4504 Unexpect aCatch(SALOME_SalomeException);
4506 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
4508 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
4511 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
4512 throw(SALOME::SALOME_Exception)
4514 Unexpect aCatch(SALOME_SalomeException);
4516 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
4518 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
4521 //=============================================================================
4523 * Returns nb of published sub-meshes
4525 //=============================================================================
4527 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
4529 Unexpect aCatch(SALOME_SalomeException);
4530 return _mapSubMesh_i.size();
4533 //=============================================================================
4535 * Dumps mesh into a string
4537 //=============================================================================
4539 char* SMESH_Mesh_i::Dump()
4543 return CORBA::string_dup( os.str().c_str() );
4546 //=============================================================================
4548 * Method of SMESH_IDSource interface
4550 //=============================================================================
4552 SMESH::long_array* SMESH_Mesh_i::GetIDs()
4554 return GetElementsId();
4557 //=============================================================================
4559 * Returns ids of all elements
4561 //=============================================================================
4563 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
4564 throw (SALOME::SALOME_Exception)
4566 Unexpect aCatch(SALOME_SalomeException);
4568 _preMeshInfo->FullLoadFromFile();
4570 SMESH::long_array_var aResult = new SMESH::long_array();
4571 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4573 if ( aSMESHDS_Mesh == NULL )
4574 return aResult._retn();
4576 long nbElements = NbElements();
4577 aResult->length( nbElements );
4578 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
4579 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
4580 aResult[i] = anIt->next()->GetID();
4582 return aResult._retn();
4586 //=============================================================================
4588 * Returns ids of all elements of given type
4590 //=============================================================================
4592 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4593 throw (SALOME::SALOME_Exception)
4595 Unexpect aCatch(SALOME_SalomeException);
4597 _preMeshInfo->FullLoadFromFile();
4599 SMESH::long_array_var aResult = new SMESH::long_array();
4600 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4602 if ( aSMESHDS_Mesh == NULL )
4603 return aResult._retn();
4605 long nbElements = NbElements();
4607 // No sense in returning ids of elements along with ids of nodes:
4608 // when theElemType == SMESH::ALL, return node ids only if
4609 // there are no elements
4610 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4611 return GetNodesId();
4613 aResult->length( nbElements );
4617 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4618 while ( i < nbElements && anIt->more() )
4619 aResult[i++] = anIt->next()->GetID();
4621 aResult->length( i );
4623 return aResult._retn();
4626 //=============================================================================
4628 * Returns ids of all nodes
4630 //=============================================================================
4632 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4633 throw (SALOME::SALOME_Exception)
4635 Unexpect aCatch(SALOME_SalomeException);
4637 _preMeshInfo->FullLoadFromFile();
4639 SMESH::long_array_var aResult = new SMESH::long_array();
4640 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4642 if ( aMeshDS == NULL )
4643 return aResult._retn();
4645 long nbNodes = NbNodes();
4646 aResult->length( nbNodes );
4647 SMDS_NodeIteratorPtr anIt = aMeshDS->nodesIterator();
4648 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4649 aResult[i] = anIt->next()->GetID();
4651 return aResult._retn();
4654 //=============================================================================
4658 //=============================================================================
4660 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4661 throw (SALOME::SALOME_Exception)
4663 SMESH::ElementType type = SMESH::ALL;
4667 _preMeshInfo->FullLoadFromFile();
4669 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4671 SMESH_CATCH( SMESH::throwCorbaException );
4676 //=============================================================================
4680 //=============================================================================
4682 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4683 throw (SALOME::SALOME_Exception)
4686 _preMeshInfo->FullLoadFromFile();
4688 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4690 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4692 return ( SMESH::EntityType ) e->GetEntityType();
4695 //=============================================================================
4699 //=============================================================================
4701 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4702 throw (SALOME::SALOME_Exception)
4705 _preMeshInfo->FullLoadFromFile();
4707 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4709 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4711 return ( SMESH::GeometryType ) e->GetGeomType();
4714 //=============================================================================
4716 * Returns ID of elements for given submesh
4718 //=============================================================================
4719 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4720 throw (SALOME::SALOME_Exception)
4722 SMESH::long_array_var aResult = new SMESH::long_array();
4726 _preMeshInfo->FullLoadFromFile();
4728 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4729 if(!SM) return aResult._retn();
4731 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4732 if(!SDSM) return aResult._retn();
4734 aResult->length(SDSM->NbElements());
4736 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4738 while ( eIt->more() ) {
4739 aResult[i++] = eIt->next()->GetID();
4742 SMESH_CATCH( SMESH::throwCorbaException );
4744 return aResult._retn();
4747 //=============================================================================
4749 * Returns ID of nodes for given submesh
4750 * If param all==true - returns all nodes, else -
4751 * returns only nodes on shapes.
4753 //=============================================================================
4755 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4757 throw (SALOME::SALOME_Exception)
4759 SMESH::long_array_var aResult = new SMESH::long_array();
4763 _preMeshInfo->FullLoadFromFile();
4765 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4766 if(!SM) return aResult._retn();
4768 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4769 if(!SDSM) return aResult._retn();
4772 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4773 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4774 while ( nIt->more() ) {
4775 const SMDS_MeshNode* elem = nIt->next();
4776 theElems.insert( elem->GetID() );
4779 else { // all nodes of submesh elements
4780 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4781 while ( eIt->more() ) {
4782 const SMDS_MeshElement* anElem = eIt->next();
4783 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4784 while ( nIt->more() ) {
4785 const SMDS_MeshElement* elem = nIt->next();
4786 theElems.insert( elem->GetID() );
4791 aResult->length(theElems.size());
4792 set<int>::iterator itElem;
4794 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4795 aResult[i++] = *itElem;
4797 SMESH_CATCH( SMESH::throwCorbaException );
4799 return aResult._retn();
4802 //=============================================================================
4804 * Returns type of elements for given submesh
4806 //=============================================================================
4808 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4809 throw (SALOME::SALOME_Exception)
4811 SMESH::ElementType type = SMESH::ALL;
4815 _preMeshInfo->FullLoadFromFile();
4817 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4818 if(!SM) return SMESH::ALL;
4820 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4821 if(!SDSM) return SMESH::ALL;
4823 if(SDSM->NbElements()==0)
4824 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4826 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4827 const SMDS_MeshElement* anElem = eIt->next();
4829 type = ( SMESH::ElementType ) anElem->GetType();
4831 SMESH_CATCH( SMESH::throwCorbaException );
4837 //=============================================================================
4839 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4841 //=============================================================================
4843 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4846 _preMeshInfo->FullLoadFromFile();
4848 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4849 if ( MYDEBUG ) MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4854 //=============================================================================
4856 * Get XYZ coordinates of node as list of double
4857 * If there is not node for given ID - returns empty list
4859 //=============================================================================
4861 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4864 _preMeshInfo->FullLoadFromFile();
4866 SMESH::double_array_var aResult = new SMESH::double_array();
4867 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4868 if ( aMeshDS == NULL )
4869 return aResult._retn();
4872 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
4874 return aResult._retn();
4878 aResult[0] = aNode->X();
4879 aResult[1] = aNode->Y();
4880 aResult[2] = aNode->Z();
4881 return aResult._retn();
4885 //=============================================================================
4887 * For given node returns list of IDs of inverse elements
4888 * If there is not node for given ID - returns empty list
4890 //=============================================================================
4892 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id,
4893 SMESH::ElementType elemType)
4896 _preMeshInfo->FullLoadFromFile();
4898 SMESH::long_array_var aResult = new SMESH::long_array();
4899 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
4900 if ( aMeshDS == NULL )
4901 return aResult._retn();
4904 const SMDS_MeshNode* aNode = aMeshDS->FindNode( id );
4906 return aResult._retn();
4908 // find inverse elements
4909 SMDSAbs_ElementType type = SMDSAbs_ElementType( elemType );
4910 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator( type );
4911 aResult->length( aNode->NbInverseElements( type ));
4912 for( int i = 0; eIt->more(); ++i )
4914 const SMDS_MeshElement* elem = eIt->next();
4915 aResult[ i ] = elem->GetID();
4917 return aResult._retn();
4920 //=============================================================================
4922 * \brief Return position of a node on shape
4924 //=============================================================================
4926 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4929 _preMeshInfo->FullLoadFromFile();
4931 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4932 aNodePosition->shapeID = 0;
4933 aNodePosition->shapeType = GEOM::SHAPE;
4935 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4936 if ( !mesh ) return aNodePosition;
4938 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4940 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4942 aNodePosition->shapeID = aNode->getshapeId();
4943 switch ( pos->GetTypeOfPosition() ) {
4945 aNodePosition->shapeType = GEOM::EDGE;
4946 aNodePosition->params.length(1);
4947 aNodePosition->params[0] = SMDS_EdgePositionPtr( pos )->GetUParameter();
4949 case SMDS_TOP_FACE: {
4950 SMDS_FacePositionPtr fPos = pos;
4951 aNodePosition->shapeType = GEOM::FACE;
4952 aNodePosition->params.length(2);
4953 aNodePosition->params[0] = fPos->GetUParameter();
4954 aNodePosition->params[1] = fPos->GetVParameter();
4957 case SMDS_TOP_VERTEX:
4958 aNodePosition->shapeType = GEOM::VERTEX;
4960 case SMDS_TOP_3DSPACE:
4961 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4962 aNodePosition->shapeType = GEOM::SOLID;
4963 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4964 aNodePosition->shapeType = GEOM::SHELL;
4970 return aNodePosition;
4973 //=============================================================================
4975 * \brief Return position of an element on shape
4977 //=============================================================================
4979 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4982 _preMeshInfo->FullLoadFromFile();
4984 SMESH::ElementPosition anElementPosition;
4985 anElementPosition.shapeID = 0;
4986 anElementPosition.shapeType = GEOM::SHAPE;
4988 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4989 if ( !mesh ) return anElementPosition;
4991 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4993 anElementPosition.shapeID = anElem->getshapeId();
4994 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4995 if ( !aSp.IsNull() ) {
4996 switch ( aSp.ShapeType() ) {
4998 anElementPosition.shapeType = GEOM::EDGE;
5001 anElementPosition.shapeType = GEOM::FACE;
5004 anElementPosition.shapeType = GEOM::VERTEX;
5007 anElementPosition.shapeType = GEOM::SOLID;
5010 anElementPosition.shapeType = GEOM::SHELL;
5016 return anElementPosition;
5019 //=============================================================================
5021 * If given element is node returns IDs of shape from position
5022 * If there is not node for given ID - returns -1
5024 //=============================================================================
5026 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
5029 _preMeshInfo->FullLoadFromFile();
5031 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5032 if ( aMeshDS == NULL )
5036 const SMDS_MeshNode* aNode = aMeshDS->FindNode(id);
5038 return aNode->getshapeId();
5045 //=============================================================================
5047 * For given element returns ID of result shape after
5048 * ::FindShape() from SMESH_MeshEditor
5049 * If there is not element for given ID - returns -1
5051 //=============================================================================
5053 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
5056 _preMeshInfo->FullLoadFromFile();
5058 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5059 if ( aMeshDS == NULL )
5062 // try to find element
5063 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5067 ::SMESH_MeshEditor aMeshEditor(_impl);
5068 int index = aMeshEditor.FindShape( elem );
5076 //=============================================================================
5078 * Returns number of nodes for given element
5079 * If there is not element for given ID - returns -1
5081 //=============================================================================
5083 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
5086 _preMeshInfo->FullLoadFromFile();
5088 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5089 if ( aMeshDS == NULL ) return -1;
5090 // try to find element
5091 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5092 if(!elem) return -1;
5093 return elem->NbNodes();
5097 //=============================================================================
5099 * Returns ID of node by given index for given element
5100 * If there is not element for given ID - returns -1
5101 * If there is not node for given index - returns -2
5103 //=============================================================================
5105 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
5108 _preMeshInfo->FullLoadFromFile();
5110 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5111 if ( aMeshDS == NULL ) return -1;
5112 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5113 if(!elem) return -1;
5114 if( index>=elem->NbNodes() || index<0 ) return -1;
5115 return elem->GetNode(index)->GetID();
5118 //=============================================================================
5120 * Returns IDs of nodes of given element
5122 //=============================================================================
5124 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
5127 _preMeshInfo->FullLoadFromFile();
5129 SMESH::long_array_var aResult = new SMESH::long_array();
5130 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5132 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(id) )
5134 aResult->length( elem->NbNodes() );
5135 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5136 if ( const SMDS_MeshNode* n = elem->GetNode( i ))
5137 aResult[ i ] = n->GetID();
5140 return aResult._retn();
5143 //=============================================================================
5145 * Returns true if given node is medium node
5146 * in given quadratic element
5148 //=============================================================================
5150 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
5153 _preMeshInfo->FullLoadFromFile();
5155 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5156 if ( aMeshDS == NULL ) return false;
5158 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5159 if(!aNode) return false;
5160 // try to find element
5161 const SMDS_MeshElement* elem = aMeshDS->FindElement(ide);
5162 if(!elem) return false;
5164 return elem->IsMediumNode(aNode);
5168 //=============================================================================
5170 * Returns true if given node is medium node
5171 * in one of quadratic elements
5173 //=============================================================================
5175 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
5176 SMESH::ElementType theElemType)
5179 _preMeshInfo->FullLoadFromFile();
5181 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5182 if ( aMeshDS == NULL ) return false;
5185 const SMDS_MeshNode* aNode = aMeshDS->FindNode(idn);
5186 if(!aNode) return false;
5188 SMESH_MesherHelper aHelper( *(_impl) );
5190 SMDSAbs_ElementType aType;
5191 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
5192 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
5193 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
5194 else aType = SMDSAbs_All;
5196 return aHelper.IsMedium(aNode,aType);
5200 //=============================================================================
5202 * Returns number of edges for given element
5204 //=============================================================================
5206 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
5209 _preMeshInfo->FullLoadFromFile();
5211 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5212 if ( aMeshDS == NULL ) return -1;
5213 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5214 if(!elem) return -1;
5215 return elem->NbEdges();
5219 //=============================================================================
5221 * Returns number of faces for given element
5223 //=============================================================================
5225 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
5228 _preMeshInfo->FullLoadFromFile();
5230 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5231 if ( aMeshDS == NULL ) return -1;
5232 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5233 if(!elem) return -1;
5234 return elem->NbFaces();
5237 //=======================================================================
5238 //function : GetElemFaceNodes
5239 //purpose : Returns nodes of given face (counted from zero) for given element.
5240 //=======================================================================
5242 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
5243 CORBA::Short faceIndex)
5246 _preMeshInfo->FullLoadFromFile();
5248 SMESH::long_array_var aResult = new SMESH::long_array();
5249 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() )
5251 if ( const SMDS_MeshElement* elem = aMeshDS->FindElement(elemId) )
5253 SMDS_VolumeTool vtool( elem, /*skipCentralNodes = */false );
5254 if ( faceIndex < vtool.NbFaces() )
5256 aResult->length( vtool.NbFaceNodes( faceIndex ));
5257 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
5258 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
5259 aResult[ i ] = nn[ i ]->GetID();
5263 return aResult._retn();
5266 //=======================================================================
5267 //function : GetFaceNormal
5268 //purpose : Returns three components of normal of given mesh face.
5269 //=======================================================================
5271 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
5272 CORBA::Boolean normalized)
5275 _preMeshInfo->FullLoadFromFile();
5277 SMESH::double_array_var aResult = new SMESH::double_array();
5279 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5282 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
5284 aResult->length( 3 );
5285 aResult[ 0 ] = normal.X();
5286 aResult[ 1 ] = normal.Y();
5287 aResult[ 2 ] = normal.Z();
5290 return aResult._retn();
5293 //=======================================================================
5294 //function : FindElementByNodes
5295 //purpose : Returns an element based on all given nodes.
5296 //=======================================================================
5298 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
5301 _preMeshInfo->FullLoadFromFile();
5303 CORBA::Long elemID(0);
5304 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5306 vector< const SMDS_MeshNode * > nn( nodes.length() );
5307 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5308 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
5311 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
5312 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
5313 _impl->NbFaces ( ORDER_QUADRATIC ) ||
5314 _impl->NbVolumes( ORDER_QUADRATIC )))
5315 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
5317 if ( elem ) elemID = CORBA::Long( elem->GetID() );
5322 //================================================================================
5324 * \brief Return elements including all given nodes.
5326 //================================================================================
5328 SMESH::long_array* SMESH_Mesh_i::GetElementsByNodes(const SMESH::long_array& nodes,
5329 SMESH::ElementType elemType)
5332 _preMeshInfo->FullLoadFromFile();
5334 SMESH::long_array_var result = new SMESH::long_array();
5336 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
5338 vector< const SMDS_MeshNode * > nn( nodes.length() );
5339 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
5340 nn[i] = mesh->FindNode( nodes[i] );
5342 std::vector<const SMDS_MeshElement *> elems;
5343 mesh->GetElementsByNodes( nn, elems, (SMDSAbs_ElementType) elemType );
5344 result->length( elems.size() );
5345 for ( size_t i = 0; i < elems.size(); ++i )
5346 result[i] = elems[i]->GetID();
5348 return result._retn();
5351 //=============================================================================
5353 * Returns true if given element is polygon
5355 //=============================================================================
5357 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
5360 _preMeshInfo->FullLoadFromFile();
5362 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5363 if ( aMeshDS == NULL ) return false;
5364 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5365 if(!elem) return false;
5366 return elem->IsPoly();
5370 //=============================================================================
5372 * Returns true if given element is quadratic
5374 //=============================================================================
5376 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
5379 _preMeshInfo->FullLoadFromFile();
5381 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5382 if ( aMeshDS == NULL ) return false;
5383 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5384 if(!elem) return false;
5385 return elem->IsQuadratic();
5388 //=============================================================================
5390 * Returns diameter of ball discrete element or zero in case of an invalid \a id
5392 //=============================================================================
5394 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
5397 _preMeshInfo->FullLoadFromFile();
5399 if ( const SMDS_BallElement* ball =
5400 SMDS_Mesh::DownCast<SMDS_BallElement>( _impl->GetMeshDS()->FindElement( id )))
5401 return ball->GetDiameter();
5406 //=============================================================================
5408 * Returns bary center for given element
5410 //=============================================================================
5412 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
5415 _preMeshInfo->FullLoadFromFile();
5417 SMESH::double_array_var aResult = new SMESH::double_array();
5418 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5419 if ( aMeshDS == NULL )
5420 return aResult._retn();
5422 const SMDS_MeshElement* elem = aMeshDS->FindElement(id);
5424 return aResult._retn();
5426 if(elem->GetType()==SMDSAbs_Volume) {
5427 SMDS_VolumeTool aTool;
5428 if(aTool.Set(elem)) {
5430 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
5435 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
5437 double x=0., y=0., z=0.;
5438 for(; anIt->more(); ) {
5440 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
5454 return aResult._retn();
5457 //================================================================================
5459 * \brief Create a group of elements preventing computation of a sub-shape
5461 //================================================================================
5463 SMESH::ListOfGroups*
5464 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
5465 const char* theGroupName )
5466 throw ( SALOME::SALOME_Exception )
5468 Unexpect aCatch(SALOME_SalomeException);
5470 if ( !theGroupName || strlen( theGroupName) == 0 )
5471 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
5473 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
5474 ::SMESH_MeshEditor::ElemFeatures elemType;
5476 // submesh by subshape id
5477 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
5478 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
5481 SMESH_ComputeErrorPtr error = sm->GetComputeError();
5482 if ( error && error->HasBadElems() )
5484 // sort bad elements by type
5485 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
5486 const list<const SMDS_MeshElement*>& badElems =
5487 static_cast<SMESH_BadInputElements*>( error.get() )->myBadElements;
5488 list<const SMDS_MeshElement*>::const_iterator elemIt = badElems.begin();
5489 list<const SMDS_MeshElement*>::const_iterator elemEnd = badElems.end();
5490 for ( ; elemIt != elemEnd; ++elemIt )
5492 const SMDS_MeshElement* elem = *elemIt;
5493 if ( !elem ) continue;
5495 if ( elem->GetID() < 1 )
5497 // elem is a temporary element, make a real element
5498 vector< const SMDS_MeshNode* > nodes;
5499 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
5500 while ( nIt->more() && elem )
5502 nodes.push_back( nIt->next() );
5503 if ( nodes.back()->GetID() < 1 )
5504 elem = 0; // a temporary element on temporary nodes
5508 ::SMESH_MeshEditor editor( _impl );
5509 elem = editor.AddElement( nodes, elemType.Init( elem ));
5513 elemsByType[ elem->GetType() ].push_back( elem );
5516 // how many groups to create?
5518 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5519 nbTypes += int( !elemsByType[ i ].empty() );
5520 groups->length( nbTypes );
5523 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
5525 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
5526 if ( elems.empty() ) continue;
5528 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
5529 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
5531 SMESH::SMESH_Mesh_var mesh = _this();
5532 SALOMEDS::SObject_wrap aSO =
5533 _gen_i->PublishGroup( mesh, groups[ iG ],
5534 GEOM::GEOM_Object::_nil(), theGroupName);
5536 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
5537 if ( !grp_i ) continue;
5539 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
5540 for ( size_t iE = 0; iE < elems.size(); ++iE )
5541 grpDS->SMDSGroup().Add( elems[ iE ]);
5546 return groups._retn();
5549 //=============================================================================
5551 * Create and publish group servants if any groups were imported or created anyhow
5553 //=============================================================================
5555 void SMESH_Mesh_i::CreateGroupServants()
5557 SMESH::SMESH_Mesh_var aMesh = _this();
5560 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
5561 while ( groupIt->more() )
5563 ::SMESH_Group* group = groupIt->next();
5564 int anId = group->GetID();
5566 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
5567 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5569 addedIDs.insert( anId );
5571 SMESH_GroupBase_i* aGroupImpl;
5573 if ( SMESHDS_GroupOnGeom* groupOnGeom =
5574 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
5576 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
5577 shape = groupOnGeom->GetShape();
5580 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
5583 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
5584 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
5585 aGroupImpl->Register();
5587 // register CORBA object for persistence
5588 int nextId = _gen_i->RegisterObject( groupVar );
5589 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
5590 else { nextId = 0; } // avoid "unused variable" warning in release mode
5592 // publishing the groups in the study
5593 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
5594 _gen_i->PublishGroup( aMesh, groupVar, shapeVar, group->GetName());
5596 if ( !addedIDs.empty() )
5599 set<int>::iterator id = addedIDs.begin();
5600 for ( ; id != addedIDs.end(); ++id )
5602 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
5603 int i = std::distance( _mapGroups.begin(), it );
5604 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5609 //=============================================================================
5611 * \brief Return true if all sub-meshes are computed OK - to update an icon
5613 //=============================================================================
5615 bool SMESH_Mesh_i::IsComputedOK()
5617 return _impl->IsComputedOK();
5620 //=============================================================================
5622 * \brief Return groups cantained in _mapGroups by their IDs
5624 //=============================================================================
5626 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5628 int nbGroups = groupIDs.size();
5629 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5630 aList->length( nbGroups );
5632 list<int>::const_iterator ids = groupIDs.begin();
5633 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5635 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5636 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5637 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5639 aList->length( nbGroups );
5640 return aList._retn();
5643 //=============================================================================
5645 * \brief Return information about imported file
5647 //=============================================================================
5649 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5651 SMESH::MedFileInfo_var res( _medFileInfo );
5652 if ( !res.operator->() ) {
5653 res = new SMESH::MedFileInfo;
5655 res->fileSize = res->major = res->minor = res->release = -1;
5660 //=======================================================================
5661 //function : FileInfoToString
5662 //purpose : Persistence of file info
5663 //=======================================================================
5665 std::string SMESH_Mesh_i::FileInfoToString()
5668 if ( &_medFileInfo.in() && _medFileInfo->fileName[0] )
5670 s = SMESH_Comment( _medFileInfo->fileSize )
5671 << " " << _medFileInfo->major
5672 << " " << _medFileInfo->minor
5673 << " " << _medFileInfo->release
5674 << " " << _medFileInfo->fileName;
5679 //=======================================================================
5680 //function : FileInfoFromString
5681 //purpose : Persistence of file info
5682 //=======================================================================
5684 void SMESH_Mesh_i::FileInfoFromString(const std::string& info)
5686 std::string size, major, minor, release, fileName;
5687 std::istringstream is(info);
5688 is >> size >> major >> minor >> release;
5689 fileName = info.data() + ( size.size() + 1 +
5692 release.size()+ 1 );
5694 _medFileInfo = new SMESH::MedFileInfo();
5695 _medFileInfo->fileName = fileName.c_str();
5696 _medFileInfo->fileSize = atoi( size.c_str() );
5697 _medFileInfo->major = atoi( major.c_str() );
5698 _medFileInfo->minor = atoi( minor.c_str() );
5699 _medFileInfo->release = atoi( release.c_str() );
5702 //=============================================================================
5704 * \brief Pass names of mesh groups from study to mesh DS
5706 //=============================================================================
5708 void SMESH_Mesh_i::checkGroupNames()
5710 int nbGrp = NbGroups();
5714 SMESH::ListOfGroups* grpList = 0;
5715 // avoid dump of "GetGroups"
5717 // store python dump into a local variable inside local scope
5718 SMESH::TPythonDump pDump; // do not delete this line of code
5719 grpList = GetGroups();
5722 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5723 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5726 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aGrp );
5727 if ( aGrpSO->_is_nil() )
5729 // correct name of the mesh group if necessary
5730 const char* guiName = aGrpSO->GetName();
5731 if ( strcmp(guiName, aGrp->GetName()) )
5732 aGrp->SetName( guiName );
5736 //=============================================================================
5738 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5740 //=============================================================================
5741 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5743 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5747 //=============================================================================
5749 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5751 //=============================================================================
5753 char* SMESH_Mesh_i::GetParameters()
5755 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5758 //=============================================================================
5760 * \brief Returns list of notebook variables used for last Mesh operation
5762 //=============================================================================
5763 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5765 SMESH::string_array_var aResult = new SMESH::string_array();
5766 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5768 CORBA::String_var aParameters = GetParameters();
5769 SALOMEDS::ListOfListOfStrings_var aSections = SMESH_Gen_i::getStudyServant()->ParseVariables(aParameters);
5770 if ( aSections->length() > 0 ) {
5771 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5772 aResult->length( aVars.length() );
5773 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5774 aResult[i] = CORBA::string_dup( aVars[i] );
5777 return aResult._retn();
5780 //=======================================================================
5781 //function : GetTypes
5782 //purpose : Returns types of elements it contains
5783 //=======================================================================
5785 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5788 return _preMeshInfo->GetTypes();
5790 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5794 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5795 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5796 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5797 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5798 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5799 if (_impl->NbNodes() &&
5800 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5801 types->length( nbTypes );
5803 return types._retn();
5806 //=======================================================================
5807 //function : GetMesh
5808 //purpose : Returns self
5809 //=======================================================================
5811 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5813 return SMESH::SMESH_Mesh::_duplicate( _this() );
5816 //=======================================================================
5817 //function : IsMeshInfoCorrect
5818 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5819 // * happen if mesh data is not yet fully loaded from the file of study.
5820 //=======================================================================
5822 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5824 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5827 //=============================================================================
5829 * \brief Returns number of mesh elements per each \a EntityType
5831 //=============================================================================
5833 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5836 return _preMeshInfo->GetMeshInfo();
5838 SMESH::long_array_var aRes = new SMESH::long_array();
5839 aRes->length(SMESH::Entity_Last);
5840 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5842 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5844 return aRes._retn();
5845 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5846 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5847 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5848 return aRes._retn();
5851 //=============================================================================
5853 * \brief Returns number of mesh elements per each \a ElementType
5855 //=============================================================================
5857 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5859 SMESH::long_array_var aRes = new SMESH::long_array();
5860 aRes->length(SMESH::NB_ELEMENT_TYPES);
5861 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5864 const SMDS_MeshInfo* meshInfo = 0;
5866 meshInfo = _preMeshInfo;
5867 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5868 meshInfo = & meshDS->GetMeshInfo();
5871 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5872 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5874 return aRes._retn();
5877 //=============================================================================
5879 * Collect statistic of mesh elements given by iterator
5881 //=============================================================================
5883 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5884 SMESH::long_array& theInfo)
5886 if (!theItr) return;
5887 while (theItr->more())
5888 theInfo[ theItr->next()->GetEntityType() ]++;
5890 //=============================================================================
5892 * Returns mesh unstructed grid information.
5894 //=============================================================================
5896 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5898 SALOMEDS::TMPFile_var SeqFile;
5899 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5900 SMDS_UnstructuredGrid* aGrid = aMeshDS->GetGrid();
5902 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5903 aWriter->WriteToOutputStringOn();
5904 aWriter->SetInputData(aGrid);
5905 aWriter->SetFileTypeToBinary();
5907 char* str = aWriter->GetOutputString();
5908 int size = aWriter->GetOutputStringLength();
5910 //Allocate octet buffer of required size
5911 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5912 //Copy ostrstream content to the octet buffer
5913 memcpy(OctetBuf, str, size);
5914 //Create and return TMPFile
5915 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5919 return SeqFile._retn();
5922 //=============================================================================
5923 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5924 * SMESH::ElementType type) */
5926 using namespace SMESH::Controls;
5927 //-----------------------------------------------------------------------------
5928 struct PredicateIterator : public SMDS_ElemIterator
5930 SMDS_ElemIteratorPtr _elemIter;
5931 PredicatePtr _predicate;
5932 const SMDS_MeshElement* _elem;
5933 SMDSAbs_ElementType _type;
5935 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5936 PredicatePtr predicate,
5937 SMDSAbs_ElementType type):
5938 _elemIter(iterator), _predicate(predicate), _type(type)
5946 virtual const SMDS_MeshElement* next()
5948 const SMDS_MeshElement* res = _elem;
5950 while ( _elemIter->more() && !_elem )
5952 if ((_elem = _elemIter->next()) &&
5953 (( _type != SMDSAbs_All && _type != _elem->GetType() ) ||
5954 ( !_predicate->IsSatisfy( _elem->GetID() ))))
5961 //-----------------------------------------------------------------------------
5962 struct IDSourceIterator : public SMDS_ElemIterator
5964 const CORBA::Long* _idPtr;
5965 const CORBA::Long* _idEndPtr;
5966 SMESH::long_array_var _idArray;
5967 const SMDS_Mesh* _mesh;
5968 const SMDSAbs_ElementType _type;
5969 const SMDS_MeshElement* _elem;
5971 IDSourceIterator( const SMDS_Mesh* mesh,
5972 const CORBA::Long* ids,
5974 SMDSAbs_ElementType type):
5975 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5977 if ( _idPtr && nbIds && _mesh )
5980 IDSourceIterator( const SMDS_Mesh* mesh,
5981 SMESH::long_array* idArray,
5982 SMDSAbs_ElementType type):
5983 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5985 if ( idArray && _mesh )
5987 _idPtr = &_idArray[0];
5988 _idEndPtr = _idPtr + _idArray->length();
5996 virtual const SMDS_MeshElement* next()
5998 const SMDS_MeshElement* res = _elem;
6000 while ( _idPtr < _idEndPtr && !_elem )
6002 if ( _type == SMDSAbs_Node )
6004 _elem = _mesh->FindNode( *_idPtr++ );
6006 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
6007 (_elem->GetType() != _type && _type != SMDSAbs_All ))
6015 //-----------------------------------------------------------------------------
6017 struct NodeOfElemIterator : public SMDS_ElemIterator
6019 TColStd_MapOfInteger _checkedNodeIDs;
6020 SMDS_ElemIteratorPtr _elemIter;
6021 SMDS_ElemIteratorPtr _nodeIter;
6022 const SMDS_MeshElement* _node;
6024 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
6026 if ( _elemIter && _elemIter->more() )
6028 _nodeIter = _elemIter->next()->nodesIterator();
6036 virtual const SMDS_MeshElement* next()
6038 const SMDS_MeshElement* res = _node;
6040 while ( !_node && ( _elemIter->more() || _nodeIter->more() ))
6042 if ( _nodeIter->more() )
6044 _node = _nodeIter->next();
6045 if ( !_checkedNodeIDs.Add( _node->GetID() ))
6050 _nodeIter = _elemIter->next()->nodesIterator();
6058 //=============================================================================
6060 * Return iterator on elements of given type in given object
6062 //=============================================================================
6064 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
6065 SMESH::ElementType theType)
6067 SMDS_ElemIteratorPtr elemIt;
6068 bool typeOK = ( theType == SMESH::ALL );
6069 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
6071 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
6072 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
6073 if ( !mesh_i ) return elemIt;
6074 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
6076 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
6078 elemIt = meshDS->elementsIterator( elemType );
6081 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
6083 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
6086 elemIt = sm->GetElements();
6087 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6089 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
6090 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
6094 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
6096 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
6097 if ( groupDS && ( elemType == groupDS->GetType() ||
6098 elemType == SMDSAbs_Node ||
6099 elemType == SMDSAbs_All ))
6101 elemIt = groupDS->GetElements();
6102 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
6105 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
6107 if ( filter_i->GetElementType() == theType ||
6108 filter_i->GetElementType() == SMESH::ALL ||
6109 elemType == SMDSAbs_Node ||
6110 elemType == SMDSAbs_All)
6112 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
6113 if ( pred_i && pred_i->GetPredicate() )
6115 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
6116 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
6117 SMDSAbs_ElementType iterType = elemType == SMDSAbs_Node ? filterType : elemType;
6118 elemIt = SMDS_ElemIteratorPtr
6119 ( new PredicateIterator( allElemIt, pred_i->GetPredicate(), iterType ));
6120 typeOK = ( elemType == SMDSAbs_Node ? filterType == SMDSAbs_Node : elemIt->more() );
6126 SMESH::array_of_ElementType_var types = theObject->GetTypes();
6127 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
6128 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
6130 SMDSAbs_ElementType iterType = isNodes ? SMDSAbs_Node : elemType;
6131 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
6134 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
6135 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, iterType ));
6139 SMESH::long_array_var ids = theObject->GetIDs();
6140 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), iterType ));
6142 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
6145 if ( elemIt && elemIt->more() && !typeOK )
6147 if ( elemType == SMDSAbs_Node )
6149 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
6153 elemIt = SMDS_ElemIteratorPtr();
6159 //=============================================================================
6160 namespace // Finding concurrent hypotheses
6161 //=============================================================================
6165 * \brief mapping of mesh dimension into shape type
6167 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
6169 TopAbs_ShapeEnum aType = TopAbs_SOLID;
6171 case 0: aType = TopAbs_VERTEX; break;
6172 case 1: aType = TopAbs_EDGE; break;
6173 case 2: aType = TopAbs_FACE; break;
6175 default:aType = TopAbs_SOLID; break;
6180 //-----------------------------------------------------------------------------
6182 * \brief Internal structure used to find concurrent submeshes
6184 * It represents a pair < submesh, concurrent dimension >, where
6185 * 'concurrent dimension' is dimension of shape where the submesh can concurrent
6186 * with another submesh. In other words, it is dimension of a hypothesis assigned
6193 int _dim; //!< a dimension the algo can build (concurrent dimension)
6194 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
6195 TopTools_MapOfShape _shapeMap;
6196 SMESH_subMesh* _subMesh;
6197 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
6199 //-----------------------------------------------------------------------------
6200 // Return the algorithm
6201 const SMESH_Algo* GetAlgo() const
6202 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
6204 //-----------------------------------------------------------------------------
6206 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
6208 const TopoDS_Shape& theShape)
6210 _subMesh = (SMESH_subMesh*)theSubMesh;
6211 SetShape( theDim, theShape );
6214 //-----------------------------------------------------------------------------
6216 void SetShape(const int theDim,
6217 const TopoDS_Shape& theShape)
6220 _ownDim = SMESH_Gen::GetShapeDim(theShape);
6221 if (_dim >= _ownDim)
6222 _shapeMap.Add( theShape );
6224 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
6225 for( ; anExp.More(); anExp.Next() )
6226 _shapeMap.Add( anExp.Current() );
6230 //-----------------------------------------------------------------------------
6231 //! Check sharing of sub-shapes
6232 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
6233 const TopTools_MapOfShape& theToFind,
6234 const TopAbs_ShapeEnum theType)
6236 bool isShared = false;
6237 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
6238 for (; !isShared && anItr.More(); anItr.Next() )
6240 const TopoDS_Shape aSubSh = anItr.Key();
6241 // check for case when concurrent dimensions are same
6242 isShared = theToFind.Contains( aSubSh );
6243 // check for sub-shape with concurrent dimension
6244 TopExp_Explorer anExp( aSubSh, theType );
6245 for ( ; !isShared && anExp.More(); anExp.Next() )
6246 isShared = theToFind.Contains( anExp.Current() );
6251 //-----------------------------------------------------------------------------
6252 //! check algorithms
6253 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
6254 const SMESHDS_Hypothesis* theA2)
6256 if ( !theA1 || !theA2 ||
6257 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
6258 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
6259 return false; // one of the hypothesis is not algorithm
6260 // check algorithm names (should be equal)
6261 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
6265 //-----------------------------------------------------------------------------
6266 //! Check if sub-shape hypotheses are concurrent
6267 bool IsConcurrent(const SMESH_DimHyp* theOther) const
6269 if ( _subMesh == theOther->_subMesh )
6270 return false; // same sub-shape - should not be
6272 // if ( <own dim of either of submeshes> == <concurrent dim> &&
6273 // any of the two submeshes is not on COMPOUND shape )
6274 // -> no concurrency
6275 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
6276 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
6277 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
6278 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
6279 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
6282 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
6283 if ( !checkSubShape )
6286 // check algorithms to be same
6287 const SMESH_Algo* a1 = this->GetAlgo();
6288 const SMESH_Algo* a2 = theOther->GetAlgo();
6289 bool isSame = checkAlgo( a1, a2 );
6293 return false; // pb?
6294 return a1->GetDim() == a2->GetDim(); // different algorithms of same dim -> concurrency !
6297 // check hypothesises for concurrence (skip first as algorithm)
6299 // pointers should be same, because it is referened from mesh hypothesis partition
6300 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
6301 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
6302 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
6303 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
6305 // the submeshes are concurrent if their algorithms has different parameters
6306 return nbSame != theOther->_hypotheses.size() - 1;
6309 // Return true if algorithm of this SMESH_DimHyp is used if no
6310 // sub-mesh order is imposed by the user
6311 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
6313 // NeedDiscreteBoundary() algo has a higher priority
6314 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
6315 theOther->GetAlgo()->NeedDiscreteBoundary() )
6316 return !this->GetAlgo()->NeedDiscreteBoundary();
6318 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
6321 }; // end of SMESH_DimHyp
6322 //-----------------------------------------------------------------------------
6324 typedef list<const SMESH_DimHyp*> TDimHypList;
6326 //-----------------------------------------------------------------------------
6328 void addDimHypInstance(const int theDim,
6329 const TopoDS_Shape& theShape,
6330 const SMESH_Algo* theAlgo,
6331 const SMESH_subMesh* theSubMesh,
6332 const list <const SMESHDS_Hypothesis*>& theHypList,
6333 TDimHypList* theDimHypListArr )
6335 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
6336 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
6337 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
6338 dimHyp->_hypotheses.push_front(theAlgo);
6339 listOfdimHyp.push_back( dimHyp );
6342 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
6343 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
6344 theHypList.begin(), theHypList.end() );
6347 //-----------------------------------------------------------------------------
6348 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
6349 TDimHypList& theListOfConcurr)
6351 if ( theListOfConcurr.empty() )
6353 theListOfConcurr.push_back( theDimHyp );
6357 TDimHypList::iterator hypIt = theListOfConcurr.begin();
6358 while ( hypIt != theListOfConcurr.end() &&
6359 !theDimHyp->IsHigherPriorityThan( *hypIt ))
6361 theListOfConcurr.insert( hypIt, theDimHyp );
6365 //-----------------------------------------------------------------------------
6366 void findConcurrents(const SMESH_DimHyp* theDimHyp,
6367 const TDimHypList& theListOfDimHyp,
6368 TDimHypList& theListOfConcurrHyp,
6369 set<int>& theSetOfConcurrId )
6371 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
6372 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
6374 const SMESH_DimHyp* curDimHyp = *rIt;
6375 if ( curDimHyp == theDimHyp )
6376 break; // meet own dimHyp pointer in same dimension
6378 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
6379 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
6381 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
6386 //-----------------------------------------------------------------------------
6387 void unionLists(TListOfInt& theListOfId,
6388 TListOfListOfInt& theListOfListOfId,
6391 TListOfListOfInt::iterator it = theListOfListOfId.begin();
6392 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
6394 continue; //skip already treated lists
6395 // check if other list has any same submesh object
6396 TListOfInt& otherListOfId = *it;
6397 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
6398 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
6401 // union two lists (from source into target)
6402 TListOfInt::iterator it2 = otherListOfId.begin();
6403 for ( ; it2 != otherListOfId.end(); it2++ ) {
6404 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
6405 theListOfId.push_back(*it2);
6407 // clear source list
6408 otherListOfId.clear();
6411 //-----------------------------------------------------------------------------
6413 //! free memory allocated for dimension-hypothesis objects
6414 void removeDimHyps( TDimHypList* theArrOfList )
6416 for (int i = 0; i < 4; i++ ) {
6417 TDimHypList& listOfdimHyp = theArrOfList[i];
6418 TDimHypList::const_iterator it = listOfdimHyp.begin();
6419 for ( ; it != listOfdimHyp.end(); it++ )
6424 //-----------------------------------------------------------------------------
6426 * \brief find common submeshes with given submesh
6427 * \param theSubMeshList list of already collected submesh to check
6428 * \param theSubMesh given submesh to intersect with other
6429 * \param theCommonSubMeshes collected common submeshes
6431 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
6432 const SMESH_subMesh* theSubMesh,
6433 set<const SMESH_subMesh*>& theCommon )
6437 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
6438 for ( ; it != theSubMeshList.end(); it++ )
6439 theSubMesh->FindIntersection( *it, theCommon );
6440 theSubMeshList.push_back( theSubMesh );
6441 //theCommon.insert( theSubMesh );
6444 //-----------------------------------------------------------------------------
6445 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
6447 TListOfListOfInt::const_iterator listsIt = smLists.begin();
6448 for ( ; listsIt != smLists.end(); ++listsIt )
6450 const TListOfInt& smIDs = *listsIt;
6451 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
6459 //=============================================================================
6461 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
6463 //=============================================================================
6465 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
6467 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6468 if ( isSubMeshInList( submeshID, anOrder ))
6471 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6472 return isSubMeshInList( submeshID, allConurrent );
6475 //=============================================================================
6477 * \brief Return submesh objects list in meshing order
6479 //=============================================================================
6481 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
6483 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
6485 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
6487 return aResult._retn();
6489 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
6490 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
6491 anOrder.splice( anOrder.end(), allConurrent );
6494 TListOfListOfInt::iterator listIt = anOrder.begin();
6495 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6496 unionLists( *listIt, anOrder, listIndx + 1 );
6498 // convert submesh ids into interface instances
6499 // and dump command into python
6500 convertMeshOrder( anOrder, aResult, false );
6502 return aResult._retn();
6505 //=============================================================================
6507 * \brief Finds concurrent sub-meshes
6509 //=============================================================================
6511 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
6513 TListOfListOfInt anOrder;
6514 ::SMESH_Mesh& mesh = GetImpl();
6516 // collect submeshes and detect concurrent algorithms and hypothesises
6517 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
6519 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
6520 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
6521 ::SMESH_subMesh* sm = (*i_sm).second;
6523 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
6525 // list of assigned hypothesises
6526 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
6527 // Find out dimensions where the submesh can be concurrent.
6528 // We define the dimensions by algo of each of hypotheses in hypList
6529 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
6530 for( ; hypIt != hypList.end(); hypIt++ ) {
6531 SMESH_Algo* anAlgo = 0;
6532 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
6533 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
6534 // hyp it-self is algo
6535 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
6537 // try to find algorithm with help of sub-shapes
6538 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
6539 for ( ; !anAlgo && anExp.More(); anExp.Next() )
6540 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
6543 continue; // no algorithm assigned to a current submesh
6545 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
6546 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
6548 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
6549 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
6550 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
6552 } // end iterations on submesh
6554 // iterate on created dimension-hypotheses and check for concurrents
6555 for ( int i = 0; i < 4; i++ ) {
6556 const TDimHypList& listOfDimHyp = dimHypListArr[i];
6557 // check for concurrents in own and other dimensions (step-by-step)
6558 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
6559 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
6560 const SMESH_DimHyp* dimHyp = *dhIt;
6561 TDimHypList listOfConcurr;
6562 set<int> setOfConcurrIds;
6563 // looking for concurrents and collect into own list
6564 for ( int j = i; j < 4; j++ )
6565 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
6566 // check if any concurrents found
6567 if ( listOfConcurr.size() > 0 ) {
6568 // add own submesh to list of concurrent
6569 addInOrderOfPriority( dimHyp, listOfConcurr );
6570 list<int> listOfConcurrIds;
6571 TDimHypList::iterator hypIt = listOfConcurr.begin();
6572 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
6573 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
6574 anOrder.push_back( listOfConcurrIds );
6579 removeDimHyps(dimHypListArr);
6581 // now, minimize the number of concurrent groups
6582 // Here we assume that lists of submeshes can have same submesh
6583 // in case of multi-dimension algorithms, as result
6584 // list with common submesh has to be united into one list
6586 TListOfListOfInt::iterator listIt = anOrder.begin();
6587 for(; listIt != anOrder.end(); listIt++, listIndx++ )
6588 unionLists( *listIt, anOrder, listIndx + 1 );
6594 //=============================================================================
6596 * \brief Set submesh object order
6597 * \param theSubMeshArray submesh array order
6599 //=============================================================================
6601 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
6604 _preMeshInfo->ForgetOrLoad();
6607 ::SMESH_Mesh& mesh = GetImpl();
6609 TPythonDump aPythonDump; // prevent dump of called methods
6610 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
6612 TListOfListOfInt subMeshOrder;
6613 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
6615 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
6616 TListOfInt subMeshIds;
6618 aPythonDump << ", ";
6619 aPythonDump << "[ ";
6620 // Collect subMeshes which should be clear
6621 // do it list-by-list, because modification of submesh order
6622 // take effect between concurrent submeshes only
6623 set<const SMESH_subMesh*> subMeshToClear;
6624 list<const SMESH_subMesh*> subMeshList;
6625 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
6627 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
6629 aPythonDump << ", ";
6630 aPythonDump << subMesh;
6631 subMeshIds.push_back( subMesh->GetId() );
6632 // detect common parts of submeshes
6633 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
6634 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
6636 aPythonDump << " ]";
6637 subMeshOrder.push_back( subMeshIds );
6639 // clear collected sub-meshes
6640 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
6641 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
6642 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
6644 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
6645 if ( SMESH_Algo* algo = sm->GetAlgo() ) // #16748
6646 sm->AlgoStateEngine( SMESH_subMesh::MODIF_HYP, algo ); // to clear a cached algo
6649 aPythonDump << " ])";
6651 mesh.SetMeshOrder( subMeshOrder );
6654 SMESH::SMESH_Mesh_var me = _this();
6655 _gen_i->UpdateIcons( me );
6660 //=============================================================================
6662 * \brief Convert submesh ids into submesh interfaces
6664 //=============================================================================
6666 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
6667 SMESH::submesh_array_array& theResOrder,
6668 const bool theIsDump)
6670 int nbSet = theIdsOrder.size();
6671 TPythonDump aPythonDump; // prevent dump of called methods
6673 aPythonDump << "[ ";
6674 theResOrder.length(nbSet);
6675 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6677 for( ; it != theIdsOrder.end(); it++ ) {
6678 // translate submesh identificators into submesh objects
6679 // takeing into account real number of concurrent lists
6680 const TListOfInt& aSubOrder = (*it);
6681 if (!aSubOrder.size())
6684 aPythonDump << "[ ";
6685 // convert shape indices into interfaces
6686 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6687 aResSubSet->length(aSubOrder.size());
6688 TListOfInt::const_iterator subIt = aSubOrder.begin();
6690 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6691 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6693 SMESH::SMESH_subMesh_var subMesh =
6694 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6697 aPythonDump << ", ";
6698 aPythonDump << subMesh;
6700 aResSubSet[ j++ ] = subMesh;
6703 aPythonDump << " ]";
6705 theResOrder[ listIndx++ ] = aResSubSet;
6707 // correct number of lists
6708 theResOrder.length( listIndx );
6711 // finilise python dump
6712 aPythonDump << " ]";
6713 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6717 namespace // utils used by SMESH_MeshPartDS
6720 * \brief Class used to access to protected data of SMDS_MeshInfo
6722 struct TMeshInfo : public SMDS_MeshInfo
6724 void Add(const SMDS_MeshElement* e) { SMDS_MeshInfo::addWithPoly( e ); }
6727 * \brief Element holing its ID only
6729 struct TElemID : public SMDS_LinearEdge
6731 TElemID(int ID) : SMDS_LinearEdge(0,0) { setID( ID ); }
6735 //================================================================================
6737 // Implementation of SMESH_MeshPartDS
6739 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6740 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6742 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6743 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6746 _meshDS = mesh_i->GetImpl().GetMeshDS();
6748 SetPersistentId( _meshDS->GetPersistentId() );
6750 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6752 // <meshPart> is the whole mesh
6753 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6755 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6756 myGroupSet = _meshDS->GetGroups();
6761 SMESH::long_array_var anIDs = meshPart->GetIDs();
6762 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6763 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6765 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6766 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6767 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6772 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6773 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6774 if ( _elements[ e->GetType() ].insert( e ).second )
6777 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6778 while ( nIt->more() )
6780 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6781 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6788 ShapeToMesh( _meshDS->ShapeToMesh() );
6790 _meshDS = 0; // to enforce iteration on _elements and _nodes
6793 // -------------------------------------------------------------------------------------
6794 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6795 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6798 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6799 for ( ; partIt != meshPart.end(); ++partIt )
6800 if ( const SMDS_MeshElement * e = *partIt )
6801 if ( _elements[ e->GetType() ].insert( e ).second )
6804 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6805 while ( nIt->more() )
6807 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6808 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6814 // -------------------------------------------------------------------------------------
6815 const SMDS_MeshElement * SMESH_MeshPartDS::FindElement(int IDelem) const
6817 if ( _meshDS ) return _meshDS->FindElement( IDelem );
6819 TElemID elem( IDelem );
6820 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6821 if ( !_elements[ iType ].empty() )
6823 TIDSortedElemSet::const_iterator it = _elements[ iType ].find( &elem );
6824 if ( it != _elements[ iType ].end() )
6829 // -------------------------------------------------------------------------------------
6830 bool SMESH_MeshPartDS::HasNumerationHoles()
6832 if ( _meshDS ) return _meshDS->HasNumerationHoles();
6834 return ( MinNodeID() != 1 ||
6835 MaxNodeID() != NbNodes() ||
6836 MinElementID() != 1 ||
6837 MaxElementID() != NbElements() );
6839 // -------------------------------------------------------------------------------------
6840 int SMESH_MeshPartDS::MaxNodeID() const
6842 if ( _meshDS ) return _meshDS->MaxNodeID();
6843 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].rbegin())->GetID();
6845 // -------------------------------------------------------------------------------------
6846 int SMESH_MeshPartDS::MinNodeID() const
6848 if ( _meshDS ) return _meshDS->MinNodeID();
6849 return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID();
6851 // -------------------------------------------------------------------------------------
6852 int SMESH_MeshPartDS::MaxElementID() const
6854 if ( _meshDS ) return _meshDS->MaxElementID();
6856 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6857 if ( !_elements[ iType ].empty() )
6858 maxID = Max( maxID, (*_elements[ iType ].rbegin())->GetID() );
6861 // -------------------------------------------------------------------------------------
6862 int SMESH_MeshPartDS::MinElementID() const
6864 if ( _meshDS ) return _meshDS->MinElementID();
6866 for ( int iType = SMDSAbs_Edge; iType < SMDSAbs_NbElementTypes; ++iType )
6867 if ( !_elements[ iType ].empty() )
6868 minID = Min( minID, (*_elements[ iType ].begin())->GetID() );
6871 // -------------------------------------------------------------------------------------
6872 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6874 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6876 typedef SMDS_SetIterator
6877 <const SMDS_MeshElement*,
6878 TIDSortedElemSet::const_iterator,
6879 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6880 SMDS_MeshElement::GeomFilter
6883 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( geomType );
6885 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6886 _elements[type].end(),
6887 SMDS_MeshElement::GeomFilter( geomType )));
6889 // -------------------------------------------------------------------------------------
6890 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6892 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6894 typedef SMDS_SetIterator
6895 <const SMDS_MeshElement*,
6896 TIDSortedElemSet::const_iterator,
6897 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6898 SMDS_MeshElement::EntityFilter
6901 SMDSAbs_ElementType type = SMDS_MeshCell::ElemType( entity );
6903 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6904 _elements[type].end(),
6905 SMDS_MeshElement::EntityFilter( entity )));
6907 // -------------------------------------------------------------------------------------
6908 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6910 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6911 if ( type == SMDSAbs_All && !_meshDS )
6913 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6915 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6916 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6918 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6920 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6921 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6923 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6924 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6926 // -------------------------------------------------------------------------------------
6927 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6928 iterType SMESH_MeshPartDS::methName() const \
6930 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6931 return _meshDS ? _meshDS->methName() : iterType \
6932 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6934 // -------------------------------------------------------------------------------------
6935 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6936 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6937 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6938 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6939 #undef _GET_ITER_DEFINE
6941 // END Implementation of SMESH_MeshPartDS
6943 //================================================================================