1 // Copyright (C) 2007-2014 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_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_Filter_i.hxx"
45 #include "SMESH_Gen_i.hxx"
46 #include "SMESH_Group.hxx"
47 #include "SMESH_Group_i.hxx"
48 #include "SMESH_MeshAlgos.hxx"
49 #include "SMESH_MeshEditor.hxx"
50 #include "SMESH_MeshEditor_i.hxx"
51 #include "SMESH_MeshPartDS.hxx"
52 #include "SMESH_MesherHelper.hxx"
53 #include "SMESH_PreMeshInfo.hxx"
54 #include "SMESH_PythonDump.hxx"
55 #include "SMESH_subMesh_i.hxx"
58 #include <SALOMEDS_Attributes_wrap.hxx>
59 #include <SALOMEDS_wrap.hxx>
60 #include <SALOME_NamingService.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <Utils_SINGLETON.hxx>
63 #include <utilities.h>
65 #include <GEOMImpl_Types.hxx>
66 #include <GEOM_wrap.hxx>
69 #include <BRep_Builder.hxx>
70 #include <OSD_Directory.hxx>
71 #include <OSD_File.hxx>
72 #include <OSD_Path.hxx>
73 #include <OSD_Protection.hxx>
74 #include <Standard_OutOfMemory.hxx>
75 #include <TColStd_MapIteratorOfMapOfInteger.hxx>
76 #include <TColStd_MapOfInteger.hxx>
77 #include <TColStd_SequenceOfInteger.hxx>
78 #include <TCollection_AsciiString.hxx>
80 #include <TopExp_Explorer.hxx>
81 #include <TopTools_MapIteratorOfMapOfShape.hxx>
82 #include <TopTools_MapOfShape.hxx>
83 #include <TopoDS_Compound.hxx>
93 // to pass CORBA exception through SMESH_TRY
94 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
96 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
99 static int MYDEBUG = 0;
101 static int MYDEBUG = 0;
105 using SMESH::TPythonDump;
107 int SMESH_Mesh_i::_idGenerator = 0;
109 //=============================================================================
113 //=============================================================================
115 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
117 CORBA::Long studyId )
118 : SALOME::GenericObj_i( thePOA )
120 MESSAGE("SMESH_Mesh_i");
123 _id = _idGenerator++;
126 _previewEditor = NULL;
131 //=============================================================================
135 //=============================================================================
137 SMESH_Mesh_i::~SMESH_Mesh_i()
139 MESSAGE("~SMESH_Mesh_i");
142 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
143 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
144 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
146 aGroup->UnRegister();
147 SMESH::SMESH_GroupBase_var( itGr->second );
152 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
153 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
154 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
156 aSubMesh->UnRegister();
157 SMESH::SMESH_subMesh_var( itSM->second );
159 _mapSubMeshIor.clear();
161 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
162 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
163 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
164 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
165 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
166 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
169 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
173 delete _editor; _editor = NULL;
174 delete _previewEditor; _previewEditor = NULL;
175 delete _impl; _impl = NULL;
176 delete _preMeshInfo; _preMeshInfo = NULL;
179 //=============================================================================
183 * Associates <this> mesh with <theShape> and puts a reference
184 * to <theShape> into the current study;
185 * the previous shape is substituted by the new one.
187 //=============================================================================
189 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
190 throw (SALOME::SALOME_Exception)
192 Unexpect aCatch(SALOME_SalomeException);
194 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
196 catch(SALOME_Exception & S_ex) {
197 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
199 // to track changes of GEOM groups
200 SMESH::SMESH_Mesh_var mesh = _this();
201 addGeomGroupData( theShapeObject, mesh );
202 _mainShapeTick = theShapeObject->GetTick();
205 //================================================================================
207 * \brief return true if mesh has a shape to build a shape on
209 //================================================================================
211 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
212 throw (SALOME::SALOME_Exception)
214 Unexpect aCatch(SALOME_SalomeException);
217 res = _impl->HasShapeToMesh();
219 catch(SALOME_Exception & S_ex) {
220 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
225 //=======================================================================
226 //function : GetShapeToMesh
228 //=======================================================================
230 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
231 throw (SALOME::SALOME_Exception)
233 Unexpect aCatch(SALOME_SalomeException);
234 GEOM::GEOM_Object_var aShapeObj;
236 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
238 aShapeObj = _gen_i->ShapeToGeomObject( S );
240 catch(SALOME_Exception & S_ex) {
241 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
243 return aShapeObj._retn();
246 //================================================================================
248 * \brief Return false if the mesh is not yet fully loaded from the study file
250 //================================================================================
252 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
254 Unexpect aCatch(SALOME_SalomeException);
255 return !_preMeshInfo;
258 //================================================================================
260 * \brief Load full mesh data from the study file
262 //================================================================================
264 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
266 Unexpect aCatch(SALOME_SalomeException);
268 _preMeshInfo->FullLoadFromFile();
271 //================================================================================
273 * \brief Remove all nodes and elements
275 //================================================================================
277 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
279 Unexpect aCatch(SALOME_SalomeException);
281 _preMeshInfo->ForgetAllData();
285 //CheckGeomGroupModif(); // issue 20145
287 catch(SALOME_Exception & S_ex) {
288 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
290 _impl->GetMeshDS()->Modified();
292 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
295 //================================================================================
297 * \brief Remove all nodes and elements for indicated shape
299 //================================================================================
301 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
302 throw (SALOME::SALOME_Exception)
304 Unexpect aCatch(SALOME_SalomeException);
306 _preMeshInfo->FullLoadFromFile();
309 _impl->ClearSubMesh( ShapeID );
311 catch(SALOME_Exception & S_ex) {
312 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
314 _impl->GetMeshDS()->Modified();
316 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
319 //=============================================================================
321 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
323 //=============================================================================
325 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
327 SMESH::DriverMED_ReadStatus res;
330 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
331 res = SMESH::DRS_OK; break;
332 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
333 res = SMESH::DRS_EMPTY; break;
334 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
335 res = SMESH::DRS_WARN_RENUMBER; break;
336 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
337 res = SMESH::DRS_WARN_SKIP_ELEM; break;
338 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
339 res = SMESH::DRS_WARN_DESCENDING; break;
340 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
342 res = SMESH::DRS_FAIL; break;
347 //=============================================================================
349 * Convert ::SMESH_ComputeError to SMESH::ComputeError
351 //=============================================================================
353 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
355 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
356 errVar->subShapeID = -1;
357 errVar->hasBadMesh = false;
359 if ( !errorPtr || errorPtr->IsOK() )
361 errVar->code = SMESH::COMPERR_OK;
365 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
366 errVar->comment = errorPtr->myComment.c_str();
368 return errVar._retn();
371 //=============================================================================
375 * Imports mesh data from MED file
377 //=============================================================================
379 SMESH::DriverMED_ReadStatus
380 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
381 throw ( SALOME::SALOME_Exception )
383 Unexpect aCatch(SALOME_SalomeException);
386 status = _impl->MEDToMesh( theFileName, theMeshName );
388 catch( SALOME_Exception& S_ex ) {
389 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
392 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
395 CreateGroupServants();
397 int major, minor, release;
398 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
399 major = minor = release = -1;
400 _medFileInfo = new SMESH::MedFileInfo();
401 _medFileInfo->fileName = theFileName;
402 _medFileInfo->fileSize = 0;
403 _medFileInfo->major = major;
404 _medFileInfo->minor = minor;
405 _medFileInfo->release = release;
408 if ( ::_stati64( theFileName, &d ) != -1 )
411 if ( ::stat64( theFileName, &d ) != -1 )
413 _medFileInfo->fileSize = d.st_size;
415 return ConvertDriverMEDReadStatus(status);
418 //================================================================================
420 * \brief Imports mesh data from the CGNS file
422 //================================================================================
424 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
425 const int theMeshIndex,
426 std::string& theMeshName )
427 throw ( SALOME::SALOME_Exception )
429 Unexpect aCatch(SALOME_SalomeException);
432 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
434 catch( SALOME_Exception& S_ex ) {
435 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
438 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
441 CreateGroupServants();
443 return ConvertDriverMEDReadStatus(status);
446 //================================================================================
448 * \brief Return string representation of a MED file version comprising nbDigits
450 //================================================================================
452 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
454 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
456 return CORBA::string_dup( ver.c_str() );
459 //=============================================================================
463 * Imports mesh data from MED file
465 //=============================================================================
467 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
468 throw ( SALOME::SALOME_Exception )
472 // Read mesh with name = <theMeshName> into SMESH_Mesh
473 _impl->UNVToMesh( theFileName );
475 CreateGroupServants();
477 SMESH_CATCH( SMESH::throwCorbaException );
482 //=============================================================================
486 * Imports mesh data from STL file
488 //=============================================================================
489 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
490 throw ( SALOME::SALOME_Exception )
494 // Read mesh with name = <theMeshName> into SMESH_Mesh
495 _impl->STLToMesh( theFileName );
497 SMESH_CATCH( SMESH::throwCorbaException );
502 //================================================================================
504 * \brief Function used in SMESH_CATCH by ImportGMFFile()
506 //================================================================================
510 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
512 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
516 //================================================================================
518 * \brief Imports data from a GMF file and returns an error description
520 //================================================================================
522 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
523 bool theMakeRequiredGroups )
524 throw (SALOME::SALOME_Exception)
526 SMESH_ComputeErrorPtr error;
529 #define SMESH_CAUGHT error =
532 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
534 SMESH_CATCH( exceptionToComputeError );
538 CreateGroupServants();
540 return ConvertComputeError( error );
543 //=============================================================================
547 //=============================================================================
549 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
551 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
552 (SMESH_Hypothesis::Hypothesis_Status theStatus)
555 RETURNCASE( HYP_OK );
556 RETURNCASE( HYP_MISSING );
557 RETURNCASE( HYP_CONCURENT );
558 RETURNCASE( HYP_BAD_PARAMETER );
559 RETURNCASE( HYP_HIDDEN_ALGO );
560 RETURNCASE( HYP_HIDING_ALGO );
561 RETURNCASE( HYP_UNKNOWN_FATAL );
562 RETURNCASE( HYP_INCOMPATIBLE );
563 RETURNCASE( HYP_NOTCONFORM );
564 RETURNCASE( HYP_ALREADY_EXIST );
565 RETURNCASE( HYP_BAD_DIM );
566 RETURNCASE( HYP_BAD_SUBSHAPE );
567 RETURNCASE( HYP_BAD_GEOMETRY );
568 RETURNCASE( HYP_NEED_SHAPE );
571 return SMESH::HYP_UNKNOWN_FATAL;
574 //=============================================================================
578 * calls internal addHypothesis() and then adds a reference to <anHyp> under
579 * the SObject actually having a reference to <aSubShape>.
580 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
582 //=============================================================================
584 SMESH::Hypothesis_Status SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
585 SMESH::SMESH_Hypothesis_ptr anHyp)
586 throw(SALOME::SALOME_Exception)
588 Unexpect aCatch(SALOME_SalomeException);
590 _preMeshInfo->ForgetOrLoad();
592 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShapeObject, anHyp );
594 SMESH::SMESH_Mesh_var mesh( _this() );
595 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
597 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
598 _gen_i->AddHypothesisToShape( study, mesh, aSubShapeObject, anHyp );
600 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
602 // Update Python script
603 //if(_impl->HasShapeToMesh())
605 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
606 << aSubShapeObject << ", " << anHyp << " )";
609 // TPythonDump() << "status = " << mesh << ".AddHypothesis( "<< anHyp << " )";
612 return ConvertHypothesisStatus(status);
615 //=============================================================================
619 //=============================================================================
621 SMESH_Hypothesis::Hypothesis_Status
622 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
623 SMESH::SMESH_Hypothesis_ptr anHyp)
625 if(MYDEBUG) MESSAGE("addHypothesis");
627 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
628 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
630 if (CORBA::is_nil( anHyp ))
631 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
633 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
636 TopoDS_Shape myLocSubShape;
637 //use PseudoShape in case if mesh has no shape
639 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject);
641 myLocSubShape = _impl->GetShapeToMesh();
643 const int hypId = anHyp->GetId();
644 status = _impl->AddHypothesis(myLocSubShape, hypId);
645 if ( !SMESH_Hypothesis::IsStatusFatal(status) ) {
646 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
648 // assure there is a corresponding submesh
649 if ( !_impl->IsMainShape( myLocSubShape )) {
650 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
651 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
652 SMESH::SMESH_subMesh_var( createSubMesh( aSubShapeObject ));
656 catch(SALOME_Exception & S_ex)
658 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
663 //=============================================================================
667 //=============================================================================
669 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
670 SMESH::SMESH_Hypothesis_ptr anHyp)
671 throw(SALOME::SALOME_Exception)
673 Unexpect aCatch(SALOME_SalomeException);
675 _preMeshInfo->ForgetOrLoad();
677 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShapeObject, anHyp );
678 SMESH::SMESH_Mesh_var mesh = _this();
680 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
682 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
683 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShapeObject, anHyp );
685 // Update Python script
686 if(_impl->HasShapeToMesh())
687 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
688 << aSubShapeObject << ", " << anHyp << " )";
690 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
693 return ConvertHypothesisStatus(status);
696 //=============================================================================
700 //=============================================================================
702 SMESH_Hypothesis::Hypothesis_Status
703 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShapeObject,
704 SMESH::SMESH_Hypothesis_ptr anHyp)
706 if(MYDEBUG) MESSAGE("removeHypothesis()");
708 if (CORBA::is_nil( aSubShapeObject ) && HasShapeToMesh())
709 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
711 if (CORBA::is_nil( anHyp ))
712 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
714 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
717 TopoDS_Shape myLocSubShape;
718 //use PseudoShape in case if mesh has no shape
719 if( _impl->HasShapeToMesh() )
720 myLocSubShape = _gen_i->GeomObjectToShape( aSubShapeObject );
722 myLocSubShape = _impl->GetShapeToMesh();
724 const int hypId = anHyp->GetId();
725 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
726 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
728 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
732 catch(SALOME_Exception & S_ex)
734 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
739 //=============================================================================
743 //=============================================================================
745 SMESH::ListOfHypothesis *
746 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShapeObject)
747 throw(SALOME::SALOME_Exception)
749 Unexpect aCatch(SALOME_SalomeException);
750 if (MYDEBUG) MESSAGE("GetHypothesisList");
751 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShapeObject))
752 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
754 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
757 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
758 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
759 myLocSubShape = _impl->GetShapeToMesh();
760 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
761 int i = 0, n = aLocalList.size();
764 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
765 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
766 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
768 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
769 if ( id_hypptr != _mapHypo.end() )
770 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
774 catch(SALOME_Exception & S_ex) {
775 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
778 return aList._retn();
781 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
783 Unexpect aCatch(SALOME_SalomeException);
784 if (MYDEBUG) MESSAGE("GetSubMeshes");
786 SMESH::submesh_array_var aList = new SMESH::submesh_array();
789 TPythonDump aPythonDump;
790 if ( !_mapSubMeshIor.empty() )
794 aList->length( _mapSubMeshIor.size() );
796 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
797 for ( ; it != _mapSubMeshIor.end(); it++ ) {
798 if ( CORBA::is_nil( it->second )) continue;
799 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
801 if (i > 1) aPythonDump << ", ";
802 aPythonDump << it->second;
806 catch(SALOME_Exception & S_ex) {
807 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
810 // Update Python script
811 if ( !_mapSubMeshIor.empty() )
812 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
814 return aList._retn();
817 //=============================================================================
821 //=============================================================================
823 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShapeObject,
824 const char* theName )
825 throw(SALOME::SALOME_Exception)
827 Unexpect aCatch(SALOME_SalomeException);
828 if (CORBA::is_nil(aSubShapeObject))
829 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
831 SMESH::SMESH_subMesh_var subMesh;
832 SMESH::SMESH_Mesh_var aMesh = _this();
834 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShapeObject);
836 //Get or Create the SMESH_subMesh object implementation
838 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
840 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
842 TopoDS_Iterator it( myLocSubShape );
844 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
846 subMesh = getSubMesh( subMeshId );
848 // create a new subMesh object servant if there is none for the shape
849 if ( subMesh->_is_nil() )
850 subMesh = createSubMesh( aSubShapeObject );
851 if ( _gen_i->CanPublishInStudy( subMesh ))
853 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
854 SALOMEDS::SObject_wrap aSO =
855 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShapeObject, theName );
856 if ( !aSO->_is_nil()) {
857 // Update Python script
858 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
859 << aSubShapeObject << ", '" << theName << "' )";
863 catch(SALOME_Exception & S_ex) {
864 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
866 return subMesh._retn();
869 //=============================================================================
873 //=============================================================================
875 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
876 throw (SALOME::SALOME_Exception)
880 if ( theSubMesh->_is_nil() )
883 GEOM::GEOM_Object_var aSubShapeObject;
884 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
885 if ( !aStudy->_is_nil() ) {
886 // Remove submesh's SObject
887 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
888 if ( !anSO->_is_nil() ) {
889 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
890 SALOMEDS::SObject_wrap anObj, aRef;
891 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
892 anObj->ReferencedObject( aRef.inout() ))
894 CORBA::Object_var obj = aRef->GetObject();
895 aSubShapeObject = GEOM::GEOM_Object::_narrow( obj );
897 // if ( aSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
898 // aSubShapeObject = theSubMesh->GetSubShape();
900 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
901 builder->RemoveObjectWithChildren( anSO );
903 // Update Python script
904 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
908 if ( removeSubMesh( theSubMesh, aSubShapeObject.in() ))
910 _preMeshInfo->ForgetOrLoad();
912 SMESH_CATCH( SMESH::throwCorbaException );
915 //=============================================================================
919 //=============================================================================
921 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
922 const char* theName )
923 throw(SALOME::SALOME_Exception)
925 Unexpect aCatch(SALOME_SalomeException);
927 _preMeshInfo->FullLoadFromFile();
929 SMESH::SMESH_Group_var aNewGroup =
930 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
932 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
934 SMESH::SMESH_Mesh_var mesh = _this();
935 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
936 SALOMEDS::SObject_wrap aSO =
937 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
938 if ( !aSO->_is_nil())
939 // Update Python script
940 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
941 << theElemType << ", '" << theName << "' )";
943 return aNewGroup._retn();
946 //=============================================================================
950 //=============================================================================
951 SMESH::SMESH_GroupOnGeom_ptr
952 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
954 GEOM::GEOM_Object_ptr theGeomObj)
955 throw(SALOME::SALOME_Exception)
957 Unexpect aCatch(SALOME_SalomeException);
959 _preMeshInfo->FullLoadFromFile();
961 SMESH::SMESH_GroupOnGeom_var aNewGroup;
963 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
964 if ( !aShape.IsNull() )
967 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
969 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
971 SMESH::SMESH_Mesh_var mesh = _this();
972 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
973 SALOMEDS::SObject_wrap aSO =
974 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
975 if ( !aSO->_is_nil())
976 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
977 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
981 return aNewGroup._retn();
984 //================================================================================
986 * \brief Creates a group whose contents is defined by filter
987 * \param theElemType - group type
988 * \param theName - group name
989 * \param theFilter - the filter
990 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
992 //================================================================================
994 SMESH::SMESH_GroupOnFilter_ptr
995 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
997 SMESH::Filter_ptr theFilter )
998 throw (SALOME::SALOME_Exception)
1000 Unexpect aCatch(SALOME_SalomeException);
1002 _preMeshInfo->FullLoadFromFile();
1004 if ( CORBA::is_nil( theFilter ))
1005 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1007 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1009 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1011 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1012 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1015 if ( !aNewGroup->_is_nil() )
1016 aNewGroup->SetFilter( theFilter );
1018 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1020 SMESH::SMESH_Mesh_var mesh = _this();
1021 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1022 SALOMEDS::SObject_wrap aSO =
1023 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1025 if ( !aSO->_is_nil())
1026 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1027 << theElemType << ", '" << theName << "', " << theFilter << " )";
1029 return aNewGroup._retn();
1032 //=============================================================================
1036 //=============================================================================
1038 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1039 throw (SALOME::SALOME_Exception)
1041 if ( theGroup->_is_nil() )
1046 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1050 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1051 if ( !aStudy->_is_nil() )
1053 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1054 if ( !aGroupSO->_is_nil() )
1056 // Update Python script
1057 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1059 // Remove group's SObject
1060 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1061 builder->RemoveObjectWithChildren( aGroupSO );
1065 // Remove the group from SMESH data structures
1066 removeGroup( aGroup->GetLocalID() );
1068 SMESH_CATCH( SMESH::throwCorbaException );
1071 //=============================================================================
1073 * Remove group with its contents
1075 //=============================================================================
1077 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1078 throw (SALOME::SALOME_Exception)
1082 _preMeshInfo->FullLoadFromFile();
1084 if ( theGroup->_is_nil() )
1088 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1089 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1090 while ( elemIt->more() )
1091 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1093 TPythonDump pyDump; // Supress dump from RemoveGroup()
1095 // Update Python script (theGroup must be alive for this)
1096 pyDump << SMESH::SMESH_Mesh_var(_this())
1097 << ".RemoveGroupWithContents( " << theGroup << " )";
1100 RemoveGroup( theGroup );
1102 SMESH_CATCH( SMESH::throwCorbaException );
1105 //================================================================================
1107 * \brief Get the list of groups existing in the mesh
1108 * \retval SMESH::ListOfGroups * - list of groups
1110 //================================================================================
1112 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1114 Unexpect aCatch(SALOME_SalomeException);
1115 if (MYDEBUG) MESSAGE("GetGroups");
1117 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1120 TPythonDump aPythonDump;
1121 if ( !_mapGroups.empty() )
1123 aPythonDump << "[ ";
1125 aList->length( _mapGroups.size() );
1127 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1128 for ( ; it != _mapGroups.end(); it++ ) {
1129 if ( CORBA::is_nil( it->second )) continue;
1130 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1132 if (i > 1) aPythonDump << ", ";
1133 aPythonDump << it->second;
1137 catch(SALOME_Exception & S_ex) {
1138 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1140 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1142 return aList._retn();
1145 //=============================================================================
1147 * Get number of groups existing in the mesh
1149 //=============================================================================
1151 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1153 Unexpect aCatch(SALOME_SalomeException);
1154 return _mapGroups.size();
1157 //=============================================================================
1159 * New group including all mesh elements present in initial groups is created.
1161 //=============================================================================
1163 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1164 SMESH::SMESH_GroupBase_ptr theGroup2,
1165 const char* theName )
1166 throw (SALOME::SALOME_Exception)
1168 SMESH::SMESH_Group_var aResGrp;
1172 _preMeshInfo->FullLoadFromFile();
1174 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1175 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1177 if ( theGroup1->GetType() != theGroup2->GetType() )
1178 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1183 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1184 if ( aResGrp->_is_nil() )
1185 return SMESH::SMESH_Group::_nil();
1187 aResGrp->AddFrom( theGroup1 );
1188 aResGrp->AddFrom( theGroup2 );
1190 // Update Python script
1191 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1192 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1194 SMESH_CATCH( SMESH::throwCorbaException );
1196 return aResGrp._retn();
1199 //=============================================================================
1201 * \brief New group including all mesh elements present in initial groups is created.
1202 * \param theGroups list of groups
1203 * \param theName name of group to be created
1204 * \return pointer to the new group
1206 //=============================================================================
1208 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1209 const char* theName )
1210 throw (SALOME::SALOME_Exception)
1212 SMESH::SMESH_Group_var aResGrp;
1215 _preMeshInfo->FullLoadFromFile();
1218 return SMESH::SMESH_Group::_nil();
1223 SMESH::ElementType aType = SMESH::ALL;
1224 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1226 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1227 if ( CORBA::is_nil( aGrp ) )
1229 if ( aType == SMESH::ALL )
1230 aType = aGrp->GetType();
1231 else if ( aType != aGrp->GetType() )
1232 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1235 if ( aType == SMESH::ALL )
1236 return SMESH::SMESH_Group::_nil();
1241 aResGrp = CreateGroup( aType, theName );
1242 if ( aResGrp->_is_nil() )
1243 return SMESH::SMESH_Group::_nil();
1245 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1246 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1248 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1249 if ( !CORBA::is_nil( aGrp ) )
1251 aResGrp->AddFrom( aGrp );
1252 if ( g > 0 ) pyDump << ", ";
1256 pyDump << " ], '" << theName << "' )";
1258 SMESH_CATCH( SMESH::throwCorbaException );
1260 return aResGrp._retn();
1263 //=============================================================================
1265 * New group is created. All mesh elements that are
1266 * present in both initial groups are added to the new one.
1268 //=============================================================================
1270 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1271 SMESH::SMESH_GroupBase_ptr theGroup2,
1272 const char* theName )
1273 throw (SALOME::SALOME_Exception)
1275 SMESH::SMESH_Group_var aResGrp;
1280 _preMeshInfo->FullLoadFromFile();
1282 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1283 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1285 if ( theGroup1->GetType() != theGroup2->GetType() )
1286 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1290 // Create Intersection
1291 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1292 if ( aResGrp->_is_nil() )
1293 return aResGrp._retn();
1295 SMESHDS_GroupBase* groupDS1 = 0;
1296 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1297 groupDS1 = grp_i->GetGroupDS();
1299 SMESHDS_GroupBase* groupDS2 = 0;
1300 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1301 groupDS2 = grp_i->GetGroupDS();
1303 SMESHDS_Group* resGroupDS = 0;
1304 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1305 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1307 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1309 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1310 while ( elemIt1->more() )
1312 const SMDS_MeshElement* e = elemIt1->next();
1313 if ( groupDS2->Contains( e ))
1314 resGroupDS->SMDSGroup().Add( e );
1317 // Update Python script
1318 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1319 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1321 SMESH_CATCH( SMESH::throwCorbaException );
1323 return aResGrp._retn();
1326 //=============================================================================
1328 \brief Intersect list of groups. New group is created. All mesh elements that
1329 are present in all initial groups simultaneously are added to the new one.
1330 \param theGroups list of groups
1331 \param theName name of group to be created
1332 \return pointer on the group
1334 //=============================================================================
1335 SMESH::SMESH_Group_ptr
1336 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1337 const char* theName )
1338 throw (SALOME::SALOME_Exception)
1340 SMESH::SMESH_Group_var aResGrp;
1345 _preMeshInfo->FullLoadFromFile();
1348 return SMESH::SMESH_Group::_nil();
1350 // check types and get SMESHDS_GroupBase's
1351 SMESH::ElementType aType = SMESH::ALL;
1352 vector< SMESHDS_GroupBase* > groupVec;
1353 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1355 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1356 if ( CORBA::is_nil( aGrp ) )
1358 if ( aType == SMESH::ALL )
1359 aType = aGrp->GetType();
1360 else if ( aType != aGrp->GetType() )
1361 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1364 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1365 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1367 if ( grpDS->IsEmpty() )
1372 groupVec.push_back( grpDS );
1375 if ( aType == SMESH::ALL ) // all groups are nil
1376 return SMESH::SMESH_Group::_nil();
1381 aResGrp = CreateGroup( aType, theName );
1383 SMESHDS_Group* resGroupDS = 0;
1384 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1385 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1386 if ( !resGroupDS || groupVec.empty() )
1387 return aResGrp._retn();
1390 size_t i, nb = groupVec.size();
1391 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1392 while ( elemIt1->more() )
1394 const SMDS_MeshElement* e = elemIt1->next();
1396 for ( i = 1; ( i < nb && inAll ); ++i )
1397 inAll = groupVec[i]->Contains( e );
1400 resGroupDS->SMDSGroup().Add( e );
1403 // Update Python script
1404 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1405 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1407 SMESH_CATCH( SMESH::throwCorbaException );
1409 return aResGrp._retn();
1412 //=============================================================================
1414 * New group is created. All mesh elements that are present in
1415 * a main group but is not present in a tool group are added to the new one
1417 //=============================================================================
1419 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1420 SMESH::SMESH_GroupBase_ptr theGroup2,
1421 const char* theName )
1422 throw (SALOME::SALOME_Exception)
1424 SMESH::SMESH_Group_var aResGrp;
1429 _preMeshInfo->FullLoadFromFile();
1431 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1432 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1434 if ( theGroup1->GetType() != theGroup2->GetType() )
1435 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1439 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1440 if ( aResGrp->_is_nil() )
1441 return aResGrp._retn();
1443 SMESHDS_GroupBase* groupDS1 = 0;
1444 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1445 groupDS1 = grp_i->GetGroupDS();
1447 SMESHDS_GroupBase* groupDS2 = 0;
1448 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1449 groupDS2 = grp_i->GetGroupDS();
1451 SMESHDS_Group* resGroupDS = 0;
1452 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1453 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1455 if ( groupDS1 && groupDS2 && resGroupDS )
1457 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1458 while ( elemIt1->more() )
1460 const SMDS_MeshElement* e = elemIt1->next();
1461 if ( !groupDS2->Contains( e ))
1462 resGroupDS->SMDSGroup().Add( e );
1465 // Update Python script
1466 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1467 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1469 SMESH_CATCH( SMESH::throwCorbaException );
1471 return aResGrp._retn();
1474 //=============================================================================
1476 \brief Cut lists of groups. New group is created. All mesh elements that are
1477 present in main groups but do not present in tool groups are added to the new one
1478 \param theMainGroups list of main groups
1479 \param theToolGroups list of tool groups
1480 \param theName name of group to be created
1481 \return pointer on the group
1483 //=============================================================================
1484 SMESH::SMESH_Group_ptr
1485 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1486 const SMESH::ListOfGroups& theToolGroups,
1487 const char* theName )
1488 throw (SALOME::SALOME_Exception)
1490 SMESH::SMESH_Group_var aResGrp;
1495 _preMeshInfo->FullLoadFromFile();
1498 return SMESH::SMESH_Group::_nil();
1500 // check types and get SMESHDS_GroupBase's
1501 SMESH::ElementType aType = SMESH::ALL;
1502 vector< SMESHDS_GroupBase* > toolGroupVec;
1503 vector< SMDS_ElemIteratorPtr > mainIterVec;
1505 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1507 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1508 if ( CORBA::is_nil( aGrp ) )
1510 if ( aType == SMESH::ALL )
1511 aType = aGrp->GetType();
1512 else if ( aType != aGrp->GetType() )
1513 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1515 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1516 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1517 if ( !grpDS->IsEmpty() )
1518 mainIterVec.push_back( grpDS->GetElements() );
1520 if ( aType == SMESH::ALL ) // all main groups are nil
1521 return SMESH::SMESH_Group::_nil();
1522 if ( mainIterVec.empty() ) // all main groups are empty
1523 return aResGrp._retn();
1525 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1527 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1528 if ( CORBA::is_nil( aGrp ) )
1530 if ( aType != aGrp->GetType() )
1531 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1533 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1534 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1535 toolGroupVec.push_back( grpDS );
1541 aResGrp = CreateGroup( aType, theName );
1543 SMESHDS_Group* resGroupDS = 0;
1544 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1545 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1547 return aResGrp._retn();
1550 size_t i, nb = toolGroupVec.size();
1551 SMDS_ElemIteratorPtr mainElemIt
1552 ( new SMDS_IteratorOnIterators
1553 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1554 while ( mainElemIt->more() )
1556 const SMDS_MeshElement* e = mainElemIt->next();
1558 for ( i = 0; ( i < nb && !isIn ); ++i )
1559 isIn = toolGroupVec[i]->Contains( e );
1562 resGroupDS->SMDSGroup().Add( e );
1565 // Update Python script
1566 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1567 << ".CutListOfGroups( " << theMainGroups
1568 << theToolGroups << ", '" << theName << "' )";
1570 SMESH_CATCH( SMESH::throwCorbaException );
1572 return aResGrp._retn();
1575 //=============================================================================
1577 \brief Create groups of entities from existing groups of superior dimensions
1579 1) extract all nodes from each group,
1580 2) combine all elements of specified dimension laying on these nodes.
1581 \param theGroups list of source groups
1582 \param theElemType dimension of elements
1583 \param theName name of new group
1584 \return pointer on new group
1588 //=============================================================================
1590 SMESH::SMESH_Group_ptr
1591 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1592 SMESH::ElementType theElemType,
1593 const char* theName )
1594 throw (SALOME::SALOME_Exception)
1596 SMESH::SMESH_Group_var aResGrp;
1600 _preMeshInfo->FullLoadFromFile();
1602 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1604 if ( !theName || !aMeshDS )
1605 return SMESH::SMESH_Group::_nil();
1607 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1613 aResGrp = CreateGroup( theElemType, theName );
1614 if ( aResGrp->_is_nil() )
1615 return SMESH::SMESH_Group::_nil();
1617 SMESHDS_GroupBase* groupBaseDS =
1618 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1619 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1621 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1623 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1624 if ( CORBA::is_nil( aGrp ) )
1627 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1628 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1630 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1632 while ( elIt->more() ) {
1633 const SMDS_MeshElement* el = elIt->next();
1634 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1635 while ( nIt->more() )
1636 resGroupCore.Add( nIt->next() );
1639 else // get elements of theElemType based on nodes of every element of group
1641 while ( elIt->more() )
1643 const SMDS_MeshElement* el = elIt->next(); // an element of group
1644 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1645 TIDSortedElemSet checkedElems;
1646 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1647 while ( nIt->more() )
1649 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1650 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1651 // check nodes of elements of theElemType around el
1652 while ( elOfTypeIt->more() )
1654 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1655 if ( !checkedElems.insert( elOfType ).second ) continue;
1657 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1658 bool allNodesOK = true;
1659 while ( nIt2->more() && allNodesOK )
1660 allNodesOK = elNodes.count( nIt2->next() );
1662 resGroupCore.Add( elOfType );
1669 // Update Python script
1670 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1671 << ".CreateDimGroup( "
1672 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1674 SMESH_CATCH( SMESH::throwCorbaException );
1676 return aResGrp._retn();
1679 //================================================================================
1681 * \brief Remember GEOM group data
1683 //================================================================================
1685 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1686 CORBA::Object_ptr theSmeshObj)
1688 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1691 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1692 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1693 if ( groupSO->_is_nil() )
1696 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1697 GEOM::GEOM_IGroupOperations_wrap groupOp =
1698 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1699 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1702 _geomGroupData.push_back( TGeomGroupData() );
1703 TGeomGroupData & groupData = _geomGroupData.back();
1705 CORBA::String_var entry = groupSO->GetID();
1706 groupData._groupEntry = entry.in();
1708 for ( int i = 0; i < ids->length(); ++i )
1709 groupData._indices.insert( ids[i] );
1711 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1714 //================================================================================
1716 * Remove GEOM group data relating to removed smesh object
1718 //================================================================================
1720 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1722 list<TGeomGroupData>::iterator
1723 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1724 for ( ; data != dataEnd; ++data ) {
1725 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1726 _geomGroupData.erase( data );
1732 //================================================================================
1734 * \brief Return new group contents if it has been changed and update group data
1736 //================================================================================
1738 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1740 TopoDS_Shape newShape;
1743 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1744 if ( study->_is_nil() ) return newShape; // means "not changed"
1745 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1746 if ( !groupSO->_is_nil() )
1748 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1749 if ( CORBA::is_nil( groupObj )) return newShape;
1750 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1752 // get indices of group items
1753 set<int> curIndices;
1754 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1755 GEOM::GEOM_IGroupOperations_wrap groupOp =
1756 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1757 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1758 for ( int i = 0; i < ids->length(); ++i )
1759 curIndices.insert( ids[i] );
1761 if ( groupData._indices == curIndices )
1762 return newShape; // group not changed
1765 groupData._indices = curIndices;
1767 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1768 if ( !geomClient ) return newShape;
1769 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1770 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1771 newShape = _gen_i->GeomObjectToShape( geomGroup );
1774 if ( newShape.IsNull() ) {
1775 // geom group becomes empty - return empty compound
1776 TopoDS_Compound compound;
1777 BRep_Builder().MakeCompound(compound);
1778 newShape = compound;
1785 //-----------------------------------------------------------------------------
1787 * \brief Storage of shape and index used in CheckGeomGroupModif()
1789 struct TIndexedShape
1792 TopoDS_Shape _shape;
1793 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1795 //-----------------------------------------------------------------------------
1797 * \brief Data to re-create a group on geometry
1799 struct TGroupOnGeomData
1803 SMDSAbs_ElementType _type;
1805 Quantity_Color _color;
1809 //=============================================================================
1811 * \brief Update data if geometry changes
1815 //=============================================================================
1817 void SMESH_Mesh_i::CheckGeomModif()
1819 if ( !_impl->HasShapeToMesh() ) return;
1821 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1822 if ( study->_is_nil() ) return;
1824 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1825 if ( mainGO->_is_nil() ) return;
1827 if ( mainGO->GetType() == GEOM_GROUP )
1829 CheckGeomGroupModif();
1832 if ( mainGO->GetTick() == _mainShapeTick )
1835 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1836 if ( !geomClient ) return;
1837 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1838 if ( geomGen->_is_nil() ) return;
1840 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1841 geomClient->RemoveShapeFromBuffer( ior.in() );
1843 // Update data taking into account that
1844 // all sub-shapes change but IDs of sub-shapes remain
1847 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1848 if ( newShape.IsNull() )
1851 _mainShapeTick = mainGO->GetTick();
1853 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1855 // store data of groups on geometry
1856 vector< TGroupOnGeomData > groupsData;
1857 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1858 groupsData.reserve( groups.size() );
1859 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1860 for ( ; g != groups.end(); ++g )
1861 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1863 TGroupOnGeomData data;
1864 data._oldID = group->GetID();
1865 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1866 data._type = group->GetType();
1867 data._name = group->GetStoreName();
1868 data._color = group->GetColor();
1869 groupsData.push_back( data );
1871 // store assigned hypotheses
1872 vector< pair< int, THypList > > ids2Hyps;
1873 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1874 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1876 const TopoDS_Shape& s = s2hyps.Key();
1877 const THypList& hyps = s2hyps.ChangeValue();
1878 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1881 // change shape to mesh
1882 _impl->ShapeToMesh( TopoDS_Shape() );
1883 _impl->ShapeToMesh( newShape );
1885 // re-assign hypotheses
1886 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1888 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1889 const THypList& hyps = ids2Hyps[i].second;
1890 THypList::const_iterator h = hyps.begin();
1891 for ( ; h != hyps.end(); ++h )
1892 _impl->AddHypothesis( s, (*h)->GetID() );
1896 for ( size_t i = 0; i < groupsData.size(); ++i )
1898 const TGroupOnGeomData& data = groupsData[i];
1900 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1901 if ( i2g == _mapGroups.end() ) continue;
1903 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1904 if ( !gr_i ) continue;
1907 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1908 meshDS->IndexToShape( data._shapeID ));
1911 _mapGroups.erase( i2g );
1915 g->GetGroupDS()->SetColor( data._color );
1916 gr_i->changeLocalId( id );
1917 _mapGroups[ id ] = i2g->second;
1918 if ( data._oldID != id )
1919 _mapGroups.erase( i2g );
1923 // update _mapSubMesh
1924 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1925 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1926 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1930 //=============================================================================
1932 * \brief Update objects depending on changed geom groups
1934 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1935 * issue 0020210: Update of a smesh group after modification of the associated geom group
1937 //=============================================================================
1939 void SMESH_Mesh_i::CheckGeomGroupModif()
1941 if ( !_impl->HasShapeToMesh() ) return;
1943 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1944 if ( study->_is_nil() ) return;
1946 CORBA::Long nbEntities = NbNodes() + NbElements();
1948 // Check if group contents changed
1950 typedef map< string, TopoDS_Shape > TEntry2Geom;
1951 TEntry2Geom newGroupContents;
1953 list<TGeomGroupData>::iterator
1954 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1955 for ( ; data != dataEnd; ++data )
1957 pair< TEntry2Geom::iterator, bool > it_new =
1958 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1959 bool processedGroup = !it_new.second;
1960 TopoDS_Shape& newShape = it_new.first->second;
1961 if ( !processedGroup )
1962 newShape = newGroupShape( *data );
1963 if ( newShape.IsNull() )
1964 continue; // no changes
1967 _preMeshInfo->ForgetOrLoad();
1969 if ( processedGroup ) { // update group indices
1970 list<TGeomGroupData>::iterator data2 = data;
1971 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1972 data->_indices = data2->_indices;
1975 // Update SMESH objects according to new GEOM group contents
1977 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1978 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1980 int oldID = submesh->GetId();
1981 if ( !_mapSubMeshIor.count( oldID ))
1983 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1985 // update hypotheses
1986 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1987 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1988 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1990 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1991 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1993 // care of submeshes
1994 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1995 int newID = newSubmesh->GetId();
1996 if ( newID != oldID ) {
1997 _mapSubMesh [ newID ] = newSubmesh;
1998 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1999 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2000 _mapSubMesh. erase(oldID);
2001 _mapSubMesh_i. erase(oldID);
2002 _mapSubMeshIor.erase(oldID);
2003 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2008 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2009 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2010 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2012 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2014 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2015 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2016 ds->SetShape( newShape );
2021 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2022 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2024 // Remove groups and submeshes basing on removed sub-shapes
2026 TopTools_MapOfShape newShapeMap;
2027 TopoDS_Iterator shapeIt( newShape );
2028 for ( ; shapeIt.More(); shapeIt.Next() )
2029 newShapeMap.Add( shapeIt.Value() );
2031 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2032 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2034 if ( newShapeMap.Contains( shapeIt.Value() ))
2036 TopTools_IndexedMapOfShape oldShapeMap;
2037 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2038 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2040 const TopoDS_Shape& oldShape = oldShapeMap(i);
2041 int oldInd = meshDS->ShapeToIndex( oldShape );
2043 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2044 if ( i_smIor != _mapSubMeshIor.end() ) {
2045 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2048 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2049 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2051 // check if a group bases on oldInd shape
2052 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2053 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2054 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2055 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2057 RemoveGroup( i_grp->second ); // several groups can base on same shape
2058 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2063 // Reassign hypotheses and update groups after setting the new shape to mesh
2065 // collect anassigned hypotheses
2066 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2067 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2068 TShapeHypList assignedHyps;
2069 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2071 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2072 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2073 if ( !hyps.empty() ) {
2074 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2075 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2076 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2079 // collect shapes supporting groups
2080 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2081 TShapeTypeList groupData;
2082 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2083 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2084 for ( ; grIt != groups.end(); ++grIt )
2086 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2088 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2090 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2091 _impl->ShapeToMesh( newShape );
2093 // reassign hypotheses
2094 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2095 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2097 TIndexedShape& geom = indS_hyps->first;
2098 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2099 int oldID = geom._index;
2100 int newID = meshDS->ShapeToIndex( geom._shape );
2101 if ( oldID == 1 ) { // main shape
2103 geom._shape = newShape;
2107 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2108 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2109 // care of submeshes
2110 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2111 if ( newID != oldID ) {
2112 _mapSubMesh [ newID ] = newSubmesh;
2113 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2114 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2115 _mapSubMesh. erase(oldID);
2116 _mapSubMesh_i. erase(oldID);
2117 _mapSubMeshIor.erase(oldID);
2118 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2122 TShapeTypeList::iterator geomType = groupData.begin();
2123 for ( ; geomType != groupData.end(); ++geomType )
2125 const TIndexedShape& geom = geomType->first;
2126 int oldID = geom._index;
2127 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2130 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2131 CORBA::String_var name = groupSO->GetName();
2133 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2135 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2136 group_i->changeLocalId( newID );
2139 break; // everything has been updated
2142 } // loop on group data
2146 CORBA::Long newNbEntities = NbNodes() + NbElements();
2147 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2148 if ( newNbEntities != nbEntities )
2150 // Add all SObjects with icons to soToUpdateIcons
2151 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2153 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2154 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2155 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2157 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2158 i_gr != _mapGroups.end(); ++i_gr ) // groups
2159 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2162 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2163 for ( ; so != soToUpdateIcons.end(); ++so )
2164 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2167 //=============================================================================
2169 * \brief Create standalone group from a group on geometry or filter
2171 //=============================================================================
2173 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2174 throw (SALOME::SALOME_Exception)
2176 SMESH::SMESH_Group_var aGroup;
2181 _preMeshInfo->FullLoadFromFile();
2183 if ( theGroup->_is_nil() )
2184 return aGroup._retn();
2186 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2188 return aGroup._retn();
2190 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2192 const int anId = aGroupToRem->GetLocalID();
2193 if ( !_impl->ConvertToStandalone( anId ) )
2194 return aGroup._retn();
2195 removeGeomGroupData( theGroup );
2197 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2199 // remove old instance of group from own map
2200 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2201 _mapGroups.erase( anId );
2203 SALOMEDS::StudyBuilder_var builder;
2204 SALOMEDS::SObject_wrap aGroupSO;
2205 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2206 if ( !aStudy->_is_nil() ) {
2207 builder = aStudy->NewBuilder();
2208 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2209 if ( !aGroupSO->_is_nil() )
2211 // remove reference to geometry
2212 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2213 for ( ; chItr->More(); chItr->Next() )
2214 // Remove group's child SObject
2215 builder->RemoveObject( chItr->Value() );
2217 // Update Python script
2218 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2219 << ".ConvertToStandalone( " << aGroupSO << " )";
2221 // change icon of Group on Filter
2224 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2225 const int isEmpty = ( elemTypes->length() == 0 );
2228 SALOMEDS::GenericAttribute_wrap anAttr =
2229 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2230 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2231 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2237 // remember new group in own map
2238 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2239 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2241 // register CORBA object for persistence
2242 _gen_i->RegisterObject( aGroup );
2244 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2245 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2246 //aGroup->Register();
2247 aGroupToRem->UnRegister();
2249 SMESH_CATCH( SMESH::throwCorbaException );
2251 return aGroup._retn();
2254 //=============================================================================
2258 //=============================================================================
2260 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2262 if(MYDEBUG) MESSAGE( "createSubMesh" );
2263 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2264 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2265 const int subMeshId = mySubMesh->GetId();
2267 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2268 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2270 _mapSubMesh [subMeshId] = mySubMesh;
2271 _mapSubMesh_i [subMeshId] = subMeshServant;
2272 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2274 subMeshServant->Register();
2276 // register CORBA object for persistence
2277 int nextId = _gen_i->RegisterObject( subMesh );
2278 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2279 else { nextId = 0; } // avoid "unused variable" warning
2281 // to track changes of GEOM groups
2282 addGeomGroupData( theSubShapeObject, subMesh );
2284 return subMesh._retn();
2287 //=======================================================================
2288 //function : getSubMesh
2290 //=======================================================================
2292 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2294 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2295 if ( it == _mapSubMeshIor.end() )
2296 return SMESH::SMESH_subMesh::_nil();
2298 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2301 //=============================================================================
2305 //=============================================================================
2307 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2308 GEOM::GEOM_Object_ptr theSubShapeObject )
2310 bool isHypChanged = false;
2311 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2312 return isHypChanged;
2314 const int subMeshId = theSubMesh->GetId();
2316 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2318 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2320 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2323 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2324 isHypChanged = !hyps.empty();
2325 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2326 for ( ; hyp != hyps.end(); ++hyp )
2327 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2334 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2335 isHypChanged = ( aHypList->length() > 0 );
2336 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2337 removeHypothesis( theSubShapeObject, aHypList[i] );
2340 catch( const SALOME::SALOME_Exception& ) {
2341 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2343 removeGeomGroupData( theSubShapeObject );
2347 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2348 if ( id_smi != _mapSubMesh_i.end() )
2349 id_smi->second->UnRegister();
2351 // remove a CORBA object
2352 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2353 if ( id_smptr != _mapSubMeshIor.end() )
2354 SMESH::SMESH_subMesh_var( id_smptr->second );
2356 _mapSubMesh.erase(subMeshId);
2357 _mapSubMesh_i.erase(subMeshId);
2358 _mapSubMeshIor.erase(subMeshId);
2360 return isHypChanged;
2363 //=============================================================================
2367 //=============================================================================
2369 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2370 const char* theName,
2371 const TopoDS_Shape& theShape,
2372 const SMESH_PredicatePtr& thePredicate )
2374 std::string newName;
2375 if ( !theName || strlen( theName ) == 0 )
2377 std::set< std::string > presentNames;
2378 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2379 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2381 CORBA::String_var name = i_gr->second->GetName();
2382 presentNames.insert( name.in() );
2385 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2386 } while ( !presentNames.insert( newName ).second );
2387 theName = newName.c_str();
2390 SMESH::SMESH_GroupBase_var aGroup;
2391 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2393 SMESH_GroupBase_i* aGroupImpl;
2394 if ( !theShape.IsNull() )
2395 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2396 else if ( thePredicate )
2397 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2399 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2401 aGroup = aGroupImpl->_this();
2402 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2403 aGroupImpl->Register();
2405 // register CORBA object for persistence
2406 int nextId = _gen_i->RegisterObject( aGroup );
2407 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2408 else { nextId = 0; } // avoid "unused variable" warning in release mode
2410 // to track changes of GEOM groups
2411 if ( !theShape.IsNull() ) {
2412 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2413 addGeomGroupData( geom, aGroup );
2416 return aGroup._retn();
2419 //=============================================================================
2421 * SMESH_Mesh_i::removeGroup
2423 * Should be called by ~SMESH_Group_i()
2425 //=============================================================================
2427 void SMESH_Mesh_i::removeGroup( const int theId )
2429 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2430 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2431 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2432 _mapGroups.erase( theId );
2433 removeGeomGroupData( group );
2434 if ( !_impl->RemoveGroup( theId ))
2436 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2437 RemoveGroup( group );
2439 group->UnRegister();
2443 //=============================================================================
2447 //=============================================================================
2449 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2450 throw(SALOME::SALOME_Exception)
2452 SMESH::log_array_var aLog;
2456 _preMeshInfo->FullLoadFromFile();
2458 list < SMESHDS_Command * >logDS = _impl->GetLog();
2459 aLog = new SMESH::log_array;
2461 int lg = logDS.size();
2464 list < SMESHDS_Command * >::iterator its = logDS.begin();
2465 while(its != logDS.end()){
2466 SMESHDS_Command *com = *its;
2467 int comType = com->GetType();
2469 int lgcom = com->GetNumber();
2471 const list < int >&intList = com->GetIndexes();
2472 int inum = intList.size();
2474 list < int >::const_iterator ii = intList.begin();
2475 const list < double >&coordList = com->GetCoords();
2476 int rnum = coordList.size();
2478 list < double >::const_iterator ir = coordList.begin();
2479 aLog[indexLog].commandType = comType;
2480 aLog[indexLog].number = lgcom;
2481 aLog[indexLog].coords.length(rnum);
2482 aLog[indexLog].indexes.length(inum);
2483 for(int i = 0; i < rnum; i++){
2484 aLog[indexLog].coords[i] = *ir;
2485 //MESSAGE(" "<<i<<" "<<ir.Value());
2488 for(int i = 0; i < inum; i++){
2489 aLog[indexLog].indexes[i] = *ii;
2490 //MESSAGE(" "<<i<<" "<<ii.Value());
2499 SMESH_CATCH( SMESH::throwCorbaException );
2501 return aLog._retn();
2505 //=============================================================================
2509 //=============================================================================
2511 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2515 SMESH_CATCH( SMESH::throwCorbaException );
2518 //=============================================================================
2522 //=============================================================================
2524 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2529 //=============================================================================
2533 //=============================================================================
2535 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2540 //=============================================================================
2543 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2544 // issue 0020918: groups removal is caused by hyp modification
2545 // issue 0021208: to forget not loaded mesh data at hyp modification
2546 struct TCallUp_i : public SMESH_Mesh::TCallUp
2548 SMESH_Mesh_i* _mesh;
2549 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2550 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2551 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2552 virtual void Load () { _mesh->Load(); }
2556 //================================================================================
2558 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2560 //================================================================================
2562 void SMESH_Mesh_i::onHypothesisModified()
2565 _preMeshInfo->ForgetOrLoad();
2568 //=============================================================================
2572 //=============================================================================
2574 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2576 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2579 _impl->SetCallUp( new TCallUp_i(this));
2582 //=============================================================================
2586 //=============================================================================
2588 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2590 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2594 //=============================================================================
2596 * Return mesh editor
2598 //=============================================================================
2600 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2601 throw (SALOME::SALOME_Exception)
2603 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2607 _preMeshInfo->FullLoadFromFile();
2609 // Create MeshEditor
2611 _editor = new SMESH_MeshEditor_i( this, false );
2612 aMeshEdVar = _editor->_this();
2614 // Update Python script
2615 TPythonDump() << _editor << " = "
2616 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2618 SMESH_CATCH( SMESH::throwCorbaException );
2620 return aMeshEdVar._retn();
2623 //=============================================================================
2625 * Return mesh edition previewer
2627 //=============================================================================
2629 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2630 throw (SALOME::SALOME_Exception)
2632 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2636 _preMeshInfo->FullLoadFromFile();
2638 if ( !_previewEditor )
2639 _previewEditor = new SMESH_MeshEditor_i( this, true );
2640 aMeshEdVar = _previewEditor->_this();
2642 SMESH_CATCH( SMESH::throwCorbaException );
2644 return aMeshEdVar._retn();
2647 //================================================================================
2649 * \brief Return true if the mesh has been edited since a last total re-compute
2650 * and those modifications may prevent successful partial re-compute
2652 //================================================================================
2654 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2656 Unexpect aCatch(SALOME_SalomeException);
2657 return _impl->HasModificationsToDiscard();
2660 //================================================================================
2662 * \brief Returns a random unique color
2664 //================================================================================
2666 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2668 const int MAX_ATTEMPTS = 100;
2670 double tolerance = 0.5;
2671 SALOMEDS::Color col;
2675 // generate random color
2676 double red = (double)rand() / RAND_MAX;
2677 double green = (double)rand() / RAND_MAX;
2678 double blue = (double)rand() / RAND_MAX;
2679 // check existence in the list of the existing colors
2680 bool matched = false;
2681 std::list<SALOMEDS::Color>::const_iterator it;
2682 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2683 SALOMEDS::Color color = *it;
2684 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2685 matched = tol < tolerance;
2687 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2688 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2696 //=============================================================================
2698 * Sets auto-color mode. If it is on, groups get unique random colors
2700 //=============================================================================
2702 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2704 Unexpect aCatch(SALOME_SalomeException);
2705 _impl->SetAutoColor(theAutoColor);
2707 TPythonDump pyDump; // not to dump group->SetColor() from below code
2708 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2710 std::list<SALOMEDS::Color> aReservedColors;
2711 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2712 for ( ; it != _mapGroups.end(); it++ ) {
2713 if ( CORBA::is_nil( it->second )) continue;
2714 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2715 it->second->SetColor( aColor );
2716 aReservedColors.push_back( aColor );
2720 //=============================================================================
2722 * Returns true if auto-color mode is on
2724 //=============================================================================
2726 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2728 Unexpect aCatch(SALOME_SalomeException);
2729 return _impl->GetAutoColor();
2732 //=============================================================================
2734 * Checks if there are groups with equal names
2736 //=============================================================================
2738 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2740 return _impl->HasDuplicatedGroupNamesMED();
2743 //================================================================================
2745 * \brief Care of a file before exporting mesh into it
2747 //================================================================================
2749 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2751 TCollection_AsciiString aFullName ((char*)file);
2752 OSD_Path aPath (aFullName);
2753 OSD_File aFile (aPath);
2754 if (aFile.Exists()) {
2755 // existing filesystem node
2756 if (aFile.KindOfFile() == OSD_FILE) {
2757 if (aFile.IsWriteable()) {
2762 if (aFile.Failed()) {
2763 TCollection_AsciiString msg ("File ");
2764 msg += aFullName + " cannot be replaced.";
2765 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2768 TCollection_AsciiString msg ("File ");
2769 msg += aFullName + " cannot be overwritten.";
2770 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2773 TCollection_AsciiString msg ("Location ");
2774 msg += aFullName + " is not a file.";
2775 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2778 // nonexisting file; check if it can be created
2780 aFile.Build(OSD_WriteOnly, OSD_Protection());
2781 if (aFile.Failed()) {
2782 TCollection_AsciiString msg ("You cannot create the file ");
2783 msg += aFullName + ". Check the directory existance and access rights.";
2784 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2792 //================================================================================
2794 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2795 * \param file - file name
2796 * \param overwrite - to erase the file or not
2797 * \retval string - mesh name
2799 //================================================================================
2801 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2802 CORBA::Boolean overwrite)
2805 PrepareForWriting(file, overwrite);
2806 string aMeshName = "Mesh";
2807 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2808 if ( !aStudy->_is_nil() ) {
2809 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2810 if ( !aMeshSO->_is_nil() ) {
2811 CORBA::String_var name = aMeshSO->GetName();
2813 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2814 if ( !aStudy->GetProperties()->IsLocked() )
2816 SALOMEDS::GenericAttribute_wrap anAttr;
2817 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2818 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2819 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2820 ASSERT(!aFileName->_is_nil());
2821 aFileName->SetValue(file);
2822 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2823 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2824 ASSERT(!aFileType->_is_nil());
2825 aFileType->SetValue("FICHIERMED");
2829 // Update Python script
2830 // set name of mesh before export
2831 TPythonDump() << _gen_i << ".SetName("
2832 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2834 // check names of groups
2840 //================================================================================
2842 * \brief Export to med file
2844 //================================================================================
2846 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2847 CORBA::Boolean auto_groups,
2848 SMESH::MED_VERSION theVersion,
2849 CORBA::Boolean overwrite,
2850 CORBA::Boolean autoDimension)
2851 throw(SALOME::SALOME_Exception)
2855 _preMeshInfo->FullLoadFromFile();
2857 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2858 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2860 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2861 << file << "', " << auto_groups << ", "
2862 << theVersion << ", " << overwrite << ", "
2863 << autoDimension << " )";
2865 SMESH_CATCH( SMESH::throwCorbaException );
2868 //================================================================================
2870 * \brief Export a mesh to a med file
2872 //================================================================================
2874 void SMESH_Mesh_i::ExportToMED (const char* file,
2875 CORBA::Boolean auto_groups,
2876 SMESH::MED_VERSION theVersion)
2877 throw(SALOME::SALOME_Exception)
2879 ExportToMEDX(file,auto_groups,theVersion,true);
2882 //================================================================================
2884 * \brief Export a mesh to a med file
2886 //================================================================================
2888 void SMESH_Mesh_i::ExportMED (const char* file,
2889 CORBA::Boolean auto_groups)
2890 throw(SALOME::SALOME_Exception)
2892 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2895 //================================================================================
2897 * \brief Export a mesh to a SAUV file
2899 //================================================================================
2901 void SMESH_Mesh_i::ExportSAUV (const char* file,
2902 CORBA::Boolean auto_groups)
2903 throw(SALOME::SALOME_Exception)
2905 Unexpect aCatch(SALOME_SalomeException);
2907 _preMeshInfo->FullLoadFromFile();
2909 string aMeshName = prepareMeshNameAndGroups(file, true);
2910 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2911 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2912 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2916 //================================================================================
2918 * \brief Export a mesh to a DAT file
2920 //================================================================================
2922 void SMESH_Mesh_i::ExportDAT (const char *file)
2923 throw(SALOME::SALOME_Exception)
2925 Unexpect aCatch(SALOME_SalomeException);
2927 _preMeshInfo->FullLoadFromFile();
2929 // Update Python script
2930 // check names of groups
2932 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2935 PrepareForWriting(file);
2936 _impl->ExportDAT(file);
2939 //================================================================================
2941 * \brief Export a mesh to an UNV file
2943 //================================================================================
2945 void SMESH_Mesh_i::ExportUNV (const char *file)
2946 throw(SALOME::SALOME_Exception)
2948 Unexpect aCatch(SALOME_SalomeException);
2950 _preMeshInfo->FullLoadFromFile();
2952 // Update Python script
2953 // check names of groups
2955 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2958 PrepareForWriting(file);
2959 _impl->ExportUNV(file);
2962 //================================================================================
2964 * \brief Export a mesh to an STL file
2966 //================================================================================
2968 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2969 throw(SALOME::SALOME_Exception)
2971 Unexpect aCatch(SALOME_SalomeException);
2973 _preMeshInfo->FullLoadFromFile();
2975 // Update Python script
2976 // check names of groups
2978 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2979 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2982 PrepareForWriting(file);
2983 _impl->ExportSTL(file, isascii);
2986 //================================================================================
2988 * \brief Export a part of mesh to a med file
2990 //================================================================================
2992 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
2994 CORBA::Boolean auto_groups,
2995 SMESH::MED_VERSION version,
2996 CORBA::Boolean overwrite,
2997 CORBA::Boolean autoDimension,
2998 const GEOM::ListOfFields& fields,
2999 const char* geomAssocFields)
3000 throw (SALOME::SALOME_Exception)
3004 _preMeshInfo->FullLoadFromFile();
3007 bool have0dField = false;
3008 if ( fields.length() > 0 )
3010 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3011 if ( shapeToMesh->_is_nil() )
3012 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3014 for ( size_t i = 0; i < fields.length(); ++i )
3016 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3017 THROW_SALOME_CORBA_EXCEPTION
3018 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3019 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3020 if ( fieldShape->_is_nil() )
3021 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3022 if ( !fieldShape->IsSame( shapeToMesh ) )
3023 THROW_SALOME_CORBA_EXCEPTION
3024 ( "Field defined not on shape", SALOME::BAD_PARAM);
3025 if ( fields[i]->GetDimension() == 0 )
3028 if ( geomAssocFields )
3029 for ( int i = 0; geomAssocFields[i]; ++i )
3030 switch ( geomAssocFields[i] ) {
3031 case 'v':case 'e':case 'f':case 's': break;
3032 case 'V':case 'E':case 'F':case 'S': break;
3033 default: THROW_SALOME_CORBA_EXCEPTION
3034 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3038 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3042 string aMeshName = "Mesh";
3043 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3044 if ( CORBA::is_nil( meshPart ) ||
3045 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3047 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3048 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3049 version, 0, autoDimension, have0dField);
3050 meshDS = _impl->GetMeshDS();
3055 _preMeshInfo->FullLoadFromFile();
3057 PrepareForWriting(file, overwrite);
3059 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3060 if ( !aStudy->_is_nil() ) {
3061 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3062 if ( !SO->_is_nil() ) {
3063 CORBA::String_var name = SO->GetName();
3067 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3068 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3069 version, partDS, autoDimension, have0dField);
3070 meshDS = tmpDSDeleter._obj = partDS;
3075 if ( _impl->HasShapeToMesh() )
3077 DriverMED_W_Field fieldWriter;
3078 fieldWriter.SetFile( file );
3079 fieldWriter.SetMeshName( aMeshName );
3080 fieldWriter.AddODOnVertices( have0dField );
3082 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3086 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3087 goList->length( fields.length() );
3088 for ( size_t i = 0; i < fields.length(); ++i )
3090 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3093 TPythonDump() << _this() << ".ExportPartToMED( "
3094 << meshPart << ", r'" << file << "', "
3095 << auto_groups << ", " << version << ", " << overwrite << ", "
3096 << autoDimension << ", " << goList
3097 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3099 SMESH_CATCH( SMESH::throwCorbaException );
3102 //================================================================================
3104 * Write GEOM fields to MED file
3106 //================================================================================
3108 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3109 SMESHDS_Mesh* meshDS,
3110 const GEOM::ListOfFields& fields,
3111 const char* geomAssocFields)
3113 #define METH "SMESH_Mesh_i::exportMEDFields() "
3115 if (( fields.length() < 1 ) &&
3116 ( !geomAssocFields || !geomAssocFields[0] ))
3119 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3120 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3121 std::vector< int > subIdsByDim[ 4 ];
3122 const double noneDblValue = 0.;
3123 const double noneIntValue = 0;
3125 for ( size_t iF = 0; iF < fields.length(); ++iF )
3129 int dim = fields[ iF ]->GetDimension();
3130 SMDSAbs_ElementType elemType;
3131 TopAbs_ShapeEnum shapeType;
3133 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3134 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3135 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3136 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3138 continue; // skip fields on whole shape
3140 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3141 if ( dataType == GEOM::FDT_String )
3143 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3144 if ( stepIDs->length() < 1 )
3146 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3147 if ( comps->length() < 1 )
3149 CORBA::String_var name = fields[ iF ]->GetName();
3151 if ( !fieldWriter.Set( meshDS,
3155 ( dataType == GEOM::FDT_Int )))
3158 for ( size_t iC = 0; iC < comps->length(); ++iC )
3159 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3161 // find sub-shape IDs
3163 std::vector< int >& subIds = subIdsByDim[ dim ];
3164 if ( subIds.empty() )
3165 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3166 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3167 subIds.push_back( id );
3171 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3175 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3177 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3178 if ( step->_is_nil() )
3181 CORBA::Long stamp = step->GetStamp();
3182 CORBA::Long id = step->GetID();
3183 fieldWriter.SetDtIt( int( stamp ), int( id ));
3185 // fill dblVals or intVals
3188 case GEOM::FDT_Double:
3190 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3191 if ( dblStep->_is_nil() ) continue;
3192 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3193 if ( vv->length() != subIds.size() )
3194 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3195 for ( size_t i = 0; i < vv->length(); ++i )
3196 dblVals[ subIds[ i ]] = vv[ i ];
3201 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3202 if ( intStep->_is_nil() ) continue;
3203 GEOM::ListOfLong_var vv = intStep->GetValues();
3204 if ( vv->length() != subIds.size() )
3205 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3206 for ( size_t i = 0; i < vv->length(); ++i )
3207 intVals[ subIds[ i ]] = (int) vv[ i ];
3210 case GEOM::FDT_Bool:
3212 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3213 if ( boolStep->_is_nil() ) continue;
3214 GEOM::short_array_var vv = boolStep->GetValues();
3215 if ( vv->length() != subIds.size() )
3216 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3217 for ( size_t i = 0; i < vv->length(); ++i )
3218 intVals[ subIds[ i ]] = (int) vv[ i ];
3224 // pass values to fieldWriter
3225 elemIt = fieldWriter.GetOrderedElems();
3226 if ( dataType == GEOM::FDT_Double )
3227 while ( elemIt->more() )
3229 const SMDS_MeshElement* e = elemIt->next();
3230 const int shapeID = e->getshapeId();
3231 if ( shapeID < 1 || shapeID >= dblVals.size() )
3232 fieldWriter.AddValue( noneDblValue );
3234 fieldWriter.AddValue( dblVals[ shapeID ]);
3237 while ( elemIt->more() )
3239 const SMDS_MeshElement* e = elemIt->next();
3240 const int shapeID = e->getshapeId();
3241 if ( shapeID < 1 || shapeID >= intVals.size() )
3242 fieldWriter.AddValue( noneIntValue );
3244 fieldWriter.AddValue( intVals[ shapeID ]);
3248 fieldWriter.Perform();
3249 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3250 if ( res && res->IsKO() )
3252 if ( res->myComment.empty() )
3253 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3255 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3261 if ( !geomAssocFields || !geomAssocFields[0] )
3264 // write geomAssocFields
3266 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3267 shapeDim[ TopAbs_COMPOUND ] = 3;
3268 shapeDim[ TopAbs_COMPSOLID ] = 3;
3269 shapeDim[ TopAbs_SOLID ] = 3;
3270 shapeDim[ TopAbs_SHELL ] = 2;
3271 shapeDim[ TopAbs_FACE ] = 2;
3272 shapeDim[ TopAbs_WIRE ] = 1;
3273 shapeDim[ TopAbs_EDGE ] = 1;
3274 shapeDim[ TopAbs_VERTEX ] = 0;
3275 shapeDim[ TopAbs_SHAPE ] = 3;
3277 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3279 std::vector< std::string > compNames;
3280 switch ( geomAssocFields[ iF ]) {
3282 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
3283 compNames.push_back( "dim" );
3286 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
3289 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
3292 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
3296 compNames.push_back( "id" );
3297 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3298 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3300 fieldWriter.SetDtIt( -1, -1 );
3302 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3306 if ( compNames.size() == 2 ) // _vertices_
3307 while ( elemIt->more() )
3309 const SMDS_MeshElement* e = elemIt->next();
3310 const int shapeID = e->getshapeId();
3313 fieldWriter.AddValue( -1 );
3314 fieldWriter.AddValue( -1 );
3318 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3319 fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
3320 fieldWriter.AddValue( shapeID );
3324 while ( elemIt->more() )
3326 const SMDS_MeshElement* e = elemIt->next();
3327 const int shapeID = e->getshapeId();
3329 fieldWriter.AddValue( -1 );
3331 fieldWriter.AddValue( shapeID );
3335 fieldWriter.Perform();
3336 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3337 if ( res && res->IsKO() )
3339 if ( res->myComment.empty() )
3340 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3342 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3345 } // loop on geomAssocFields
3350 //================================================================================
3352 * \brief Export a part of mesh to a DAT file
3354 //================================================================================
3356 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3358 throw (SALOME::SALOME_Exception)
3360 Unexpect aCatch(SALOME_SalomeException);
3362 _preMeshInfo->FullLoadFromFile();
3364 PrepareForWriting(file);
3366 SMESH_MeshPartDS partDS( meshPart );
3367 _impl->ExportDAT(file,&partDS);
3369 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3370 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3372 //================================================================================
3374 * \brief Export a part of mesh to an UNV file
3376 //================================================================================
3378 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3380 throw (SALOME::SALOME_Exception)
3382 Unexpect aCatch(SALOME_SalomeException);
3384 _preMeshInfo->FullLoadFromFile();
3386 PrepareForWriting(file);
3388 SMESH_MeshPartDS partDS( meshPart );
3389 _impl->ExportUNV(file, &partDS);
3391 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3392 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3394 //================================================================================
3396 * \brief Export a part of mesh to an STL file
3398 //================================================================================
3400 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3402 ::CORBA::Boolean isascii)
3403 throw (SALOME::SALOME_Exception)
3405 Unexpect aCatch(SALOME_SalomeException);
3407 _preMeshInfo->FullLoadFromFile();
3409 PrepareForWriting(file);
3411 SMESH_MeshPartDS partDS( meshPart );
3412 _impl->ExportSTL(file, isascii, &partDS);
3414 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3415 << meshPart<< ", r'" << file << "', " << isascii << ")";
3418 //================================================================================
3420 * \brief Export a part of mesh to an STL file
3422 //================================================================================
3424 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3426 CORBA::Boolean overwrite)
3427 throw (SALOME::SALOME_Exception)
3430 Unexpect aCatch(SALOME_SalomeException);
3432 _preMeshInfo->FullLoadFromFile();
3434 PrepareForWriting(file,overwrite);
3436 SMESH_MeshPartDS partDS( meshPart );
3437 _impl->ExportCGNS(file, &partDS);
3439 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3440 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3442 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3446 //================================================================================
3448 * \brief Export a part of mesh to a GMF file
3450 //================================================================================
3452 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3454 bool withRequiredGroups)
3455 throw (SALOME::SALOME_Exception)
3457 Unexpect aCatch(SALOME_SalomeException);
3459 _preMeshInfo->FullLoadFromFile();
3461 PrepareForWriting(file,/*overwrite=*/true);
3463 SMESH_MeshPartDS partDS( meshPart );
3464 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3466 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3467 << meshPart<< ", r'"
3469 << withRequiredGroups << ")";
3472 //=============================================================================
3474 * Return computation progress [0.,1]
3476 //=============================================================================
3478 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3482 return _impl->GetComputeProgress();
3484 SMESH_CATCH( SMESH::doNothing );
3488 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3490 Unexpect aCatch(SALOME_SalomeException);
3492 return _preMeshInfo->NbNodes();
3494 return _impl->NbNodes();
3497 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3499 Unexpect aCatch(SALOME_SalomeException);
3501 return _preMeshInfo->NbElements();
3503 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3506 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3508 Unexpect aCatch(SALOME_SalomeException);
3510 return _preMeshInfo->Nb0DElements();
3512 return _impl->Nb0DElements();
3515 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3517 Unexpect aCatch(SALOME_SalomeException);
3519 return _preMeshInfo->NbBalls();
3521 return _impl->NbBalls();
3524 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3526 Unexpect aCatch(SALOME_SalomeException);
3528 return _preMeshInfo->NbEdges();
3530 return _impl->NbEdges();
3533 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3534 throw(SALOME::SALOME_Exception)
3536 Unexpect aCatch(SALOME_SalomeException);
3538 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3540 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3543 //=============================================================================
3545 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3547 Unexpect aCatch(SALOME_SalomeException);
3549 return _preMeshInfo->NbFaces();
3551 return _impl->NbFaces();
3554 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3556 Unexpect aCatch(SALOME_SalomeException);
3558 return _preMeshInfo->NbTriangles();
3560 return _impl->NbTriangles();
3563 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3565 Unexpect aCatch(SALOME_SalomeException);
3567 return _preMeshInfo->NbBiQuadTriangles();
3569 return _impl->NbBiQuadTriangles();
3572 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3574 Unexpect aCatch(SALOME_SalomeException);
3576 return _preMeshInfo->NbQuadrangles();
3578 return _impl->NbQuadrangles();
3581 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3583 Unexpect aCatch(SALOME_SalomeException);
3585 return _preMeshInfo->NbBiQuadQuadrangles();
3587 return _impl->NbBiQuadQuadrangles();
3590 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3592 Unexpect aCatch(SALOME_SalomeException);
3594 return _preMeshInfo->NbPolygons();
3596 return _impl->NbPolygons();
3599 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3600 throw(SALOME::SALOME_Exception)
3602 Unexpect aCatch(SALOME_SalomeException);
3604 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3606 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3609 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3610 throw(SALOME::SALOME_Exception)
3612 Unexpect aCatch(SALOME_SalomeException);
3614 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3616 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3619 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3620 throw(SALOME::SALOME_Exception)
3622 Unexpect aCatch(SALOME_SalomeException);
3624 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3626 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3629 //=============================================================================
3631 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3633 Unexpect aCatch(SALOME_SalomeException);
3635 return _preMeshInfo->NbVolumes();
3637 return _impl->NbVolumes();
3640 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3642 Unexpect aCatch(SALOME_SalomeException);
3644 return _preMeshInfo->NbTetras();
3646 return _impl->NbTetras();
3649 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3651 Unexpect aCatch(SALOME_SalomeException);
3653 return _preMeshInfo->NbHexas();
3655 return _impl->NbHexas();
3658 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3660 Unexpect aCatch(SALOME_SalomeException);
3662 return _preMeshInfo->NbTriQuadHexas();
3664 return _impl->NbTriQuadraticHexas();
3667 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3669 Unexpect aCatch(SALOME_SalomeException);
3671 return _preMeshInfo->NbPyramids();
3673 return _impl->NbPyramids();
3676 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3678 Unexpect aCatch(SALOME_SalomeException);
3680 return _preMeshInfo->NbPrisms();
3682 return _impl->NbPrisms();
3685 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3687 Unexpect aCatch(SALOME_SalomeException);
3689 return _preMeshInfo->NbHexPrisms();
3691 return _impl->NbHexagonalPrisms();
3694 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3696 Unexpect aCatch(SALOME_SalomeException);
3698 return _preMeshInfo->NbPolyhedrons();
3700 return _impl->NbPolyhedrons();
3703 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3704 throw(SALOME::SALOME_Exception)
3706 Unexpect aCatch(SALOME_SalomeException);
3708 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3710 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3713 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3714 throw(SALOME::SALOME_Exception)
3716 Unexpect aCatch(SALOME_SalomeException);
3718 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3720 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3723 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3724 throw(SALOME::SALOME_Exception)
3726 Unexpect aCatch(SALOME_SalomeException);
3728 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3730 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3733 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3734 throw(SALOME::SALOME_Exception)
3736 Unexpect aCatch(SALOME_SalomeException);
3738 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3740 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3743 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3744 throw(SALOME::SALOME_Exception)
3746 Unexpect aCatch(SALOME_SalomeException);
3748 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3750 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3753 //=============================================================================
3755 * Returns nb of published sub-meshes
3757 //=============================================================================
3759 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3762 return _mapSubMesh_i.size();
3765 //=============================================================================
3767 * Dumps mesh into a string
3769 //=============================================================================
3771 char* SMESH_Mesh_i::Dump()
3775 return CORBA::string_dup( os.str().c_str() );
3778 //=============================================================================
3780 * Method of SMESH_IDSource interface
3782 //=============================================================================
3784 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3786 return GetElementsId();
3789 //=============================================================================
3791 * Returns ids of all elements
3793 //=============================================================================
3795 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3796 throw (SALOME::SALOME_Exception)
3798 Unexpect aCatch(SALOME_SalomeException);
3800 _preMeshInfo->FullLoadFromFile();
3802 SMESH::long_array_var aResult = new SMESH::long_array();
3803 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3805 if ( aSMESHDS_Mesh == NULL )
3806 return aResult._retn();
3808 long nbElements = NbElements();
3809 aResult->length( nbElements );
3810 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3811 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3812 aResult[i] = anIt->next()->GetID();
3814 return aResult._retn();
3818 //=============================================================================
3820 * Returns ids of all elements of given type
3822 //=============================================================================
3824 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3825 throw (SALOME::SALOME_Exception)
3827 Unexpect aCatch(SALOME_SalomeException);
3829 _preMeshInfo->FullLoadFromFile();
3831 SMESH::long_array_var aResult = new SMESH::long_array();
3832 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3834 if ( aSMESHDS_Mesh == NULL )
3835 return aResult._retn();
3837 long nbElements = NbElements();
3839 // No sense in returning ids of elements along with ids of nodes:
3840 // when theElemType == SMESH::ALL, return node ids only if
3841 // there are no elements
3842 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3843 return GetNodesId();
3845 aResult->length( nbElements );
3849 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3850 while ( i < nbElements && anIt->more() )
3851 aResult[i++] = anIt->next()->GetID();
3853 aResult->length( i );
3855 return aResult._retn();
3858 //=============================================================================
3860 * Returns ids of all nodes
3862 //=============================================================================
3864 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3865 throw (SALOME::SALOME_Exception)
3867 Unexpect aCatch(SALOME_SalomeException);
3869 _preMeshInfo->FullLoadFromFile();
3871 SMESH::long_array_var aResult = new SMESH::long_array();
3872 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3874 if ( aSMESHDS_Mesh == NULL )
3875 return aResult._retn();
3877 long nbNodes = NbNodes();
3878 aResult->length( nbNodes );
3879 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3880 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3881 aResult[i] = anIt->next()->GetID();
3883 return aResult._retn();
3886 //=============================================================================
3890 //=============================================================================
3892 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3893 throw (SALOME::SALOME_Exception)
3895 SMESH::ElementType type;
3899 _preMeshInfo->FullLoadFromFile();
3901 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3903 SMESH_CATCH( SMESH::throwCorbaException );
3908 //=============================================================================
3912 //=============================================================================
3914 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3915 throw (SALOME::SALOME_Exception)
3918 _preMeshInfo->FullLoadFromFile();
3920 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3922 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3924 return ( SMESH::EntityType ) e->GetEntityType();
3927 //=============================================================================
3931 //=============================================================================
3933 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3934 throw (SALOME::SALOME_Exception)
3937 _preMeshInfo->FullLoadFromFile();
3939 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3941 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3943 return ( SMESH::GeometryType ) e->GetGeomType();
3946 //=============================================================================
3948 * Returns ID of elements for given submesh
3950 //=============================================================================
3951 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3952 throw (SALOME::SALOME_Exception)
3954 SMESH::long_array_var aResult = new SMESH::long_array();
3958 _preMeshInfo->FullLoadFromFile();
3960 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3961 if(!SM) return aResult._retn();
3963 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3964 if(!SDSM) return aResult._retn();
3966 aResult->length(SDSM->NbElements());
3968 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3970 while ( eIt->more() ) {
3971 aResult[i++] = eIt->next()->GetID();
3974 SMESH_CATCH( SMESH::throwCorbaException );
3976 return aResult._retn();
3979 //=============================================================================
3981 * Returns ID of nodes for given submesh
3982 * If param all==true - returns all nodes, else -
3983 * returns only nodes on shapes.
3985 //=============================================================================
3987 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3989 throw (SALOME::SALOME_Exception)
3991 SMESH::long_array_var aResult = new SMESH::long_array();
3995 _preMeshInfo->FullLoadFromFile();
3997 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3998 if(!SM) return aResult._retn();
4000 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4001 if(!SDSM) return aResult._retn();
4004 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4005 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4006 while ( nIt->more() ) {
4007 const SMDS_MeshNode* elem = nIt->next();
4008 theElems.insert( elem->GetID() );
4011 else { // all nodes of submesh elements
4012 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4013 while ( eIt->more() ) {
4014 const SMDS_MeshElement* anElem = eIt->next();
4015 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4016 while ( nIt->more() ) {
4017 const SMDS_MeshElement* elem = nIt->next();
4018 theElems.insert( elem->GetID() );
4023 aResult->length(theElems.size());
4024 set<int>::iterator itElem;
4026 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4027 aResult[i++] = *itElem;
4029 SMESH_CATCH( SMESH::throwCorbaException );
4031 return aResult._retn();
4034 //=============================================================================
4036 * Returns type of elements for given submesh
4038 //=============================================================================
4040 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4041 throw (SALOME::SALOME_Exception)
4043 SMESH::ElementType type;
4047 _preMeshInfo->FullLoadFromFile();
4049 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4050 if(!SM) return SMESH::ALL;
4052 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4053 if(!SDSM) return SMESH::ALL;
4055 if(SDSM->NbElements()==0)
4056 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4058 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4059 const SMDS_MeshElement* anElem = eIt->next();
4061 type = ( SMESH::ElementType ) anElem->GetType();
4063 SMESH_CATCH( SMESH::throwCorbaException );
4069 //=============================================================================
4071 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4073 //=============================================================================
4075 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4078 _preMeshInfo->FullLoadFromFile();
4080 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4082 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4087 //=============================================================================
4089 * Get XYZ coordinates of node as list of double
4090 * If there is not node for given ID - returns empty list
4092 //=============================================================================
4094 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4097 _preMeshInfo->FullLoadFromFile();
4099 SMESH::double_array_var aResult = new SMESH::double_array();
4100 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4101 if ( aSMESHDS_Mesh == NULL )
4102 return aResult._retn();
4105 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4107 return aResult._retn();
4111 aResult[0] = aNode->X();
4112 aResult[1] = aNode->Y();
4113 aResult[2] = aNode->Z();
4114 return aResult._retn();
4118 //=============================================================================
4120 * For given node returns list of IDs of inverse elements
4121 * If there is not node for given ID - returns empty list
4123 //=============================================================================
4125 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4128 _preMeshInfo->FullLoadFromFile();
4130 SMESH::long_array_var aResult = new SMESH::long_array();
4131 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4132 if ( aSMESHDS_Mesh == NULL )
4133 return aResult._retn();
4136 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4138 return aResult._retn();
4140 // find inverse elements
4141 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4142 TColStd_SequenceOfInteger IDs;
4143 while(eIt->more()) {
4144 const SMDS_MeshElement* elem = eIt->next();
4145 IDs.Append(elem->GetID());
4147 if(IDs.Length()>0) {
4148 aResult->length(IDs.Length());
4150 for(; i<=IDs.Length(); i++) {
4151 aResult[i-1] = IDs.Value(i);
4154 return aResult._retn();
4157 //=============================================================================
4159 * \brief Return position of a node on shape
4161 //=============================================================================
4163 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4166 _preMeshInfo->FullLoadFromFile();
4168 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4169 aNodePosition->shapeID = 0;
4170 aNodePosition->shapeType = GEOM::SHAPE;
4172 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4173 if ( !mesh ) return aNodePosition;
4175 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4177 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4179 aNodePosition->shapeID = aNode->getshapeId();
4180 switch ( pos->GetTypeOfPosition() ) {
4182 aNodePosition->shapeType = GEOM::EDGE;
4183 aNodePosition->params.length(1);
4184 aNodePosition->params[0] =
4185 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4188 aNodePosition->shapeType = GEOM::FACE;
4189 aNodePosition->params.length(2);
4190 aNodePosition->params[0] =
4191 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4192 aNodePosition->params[1] =
4193 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4195 case SMDS_TOP_VERTEX:
4196 aNodePosition->shapeType = GEOM::VERTEX;
4198 case SMDS_TOP_3DSPACE:
4199 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4200 aNodePosition->shapeType = GEOM::SOLID;
4201 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4202 aNodePosition->shapeType = GEOM::SHELL;
4208 return aNodePosition;
4211 //=============================================================================
4213 * \brief Return position of an element on shape
4215 //=============================================================================
4217 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4220 _preMeshInfo->FullLoadFromFile();
4222 SMESH::ElementPosition anElementPosition;
4223 anElementPosition.shapeID = 0;
4224 anElementPosition.shapeType = GEOM::SHAPE;
4226 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4227 if ( !mesh ) return anElementPosition;
4229 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4231 anElementPosition.shapeID = anElem->getshapeId();
4232 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4233 if ( !aSp.IsNull() ) {
4234 switch ( aSp.ShapeType() ) {
4236 anElementPosition.shapeType = GEOM::EDGE;
4239 anElementPosition.shapeType = GEOM::FACE;
4242 anElementPosition.shapeType = GEOM::VERTEX;
4245 anElementPosition.shapeType = GEOM::SOLID;
4248 anElementPosition.shapeType = GEOM::SHELL;
4254 return anElementPosition;
4257 //=============================================================================
4259 * If given element is node returns IDs of shape from position
4260 * If there is not node for given ID - returns -1
4262 //=============================================================================
4264 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4267 _preMeshInfo->FullLoadFromFile();
4269 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4270 if ( aSMESHDS_Mesh == NULL )
4274 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4276 return aNode->getshapeId();
4283 //=============================================================================
4285 * For given element returns ID of result shape after
4286 * ::FindShape() from SMESH_MeshEditor
4287 * If there is not element for given ID - returns -1
4289 //=============================================================================
4291 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4294 _preMeshInfo->FullLoadFromFile();
4296 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4297 if ( aSMESHDS_Mesh == NULL )
4300 // try to find element
4301 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4305 ::SMESH_MeshEditor aMeshEditor(_impl);
4306 int index = aMeshEditor.FindShape( elem );
4314 //=============================================================================
4316 * Returns number of nodes for given element
4317 * If there is not element for given ID - returns -1
4319 //=============================================================================
4321 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4324 _preMeshInfo->FullLoadFromFile();
4326 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4327 if ( aSMESHDS_Mesh == NULL ) return -1;
4328 // try to find element
4329 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4330 if(!elem) return -1;
4331 return elem->NbNodes();
4335 //=============================================================================
4337 * Returns ID of node by given index for given element
4338 * If there is not element for given ID - returns -1
4339 * If there is not node for given index - returns -2
4341 //=============================================================================
4343 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4346 _preMeshInfo->FullLoadFromFile();
4348 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4349 if ( aSMESHDS_Mesh == NULL ) return -1;
4350 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4351 if(!elem) return -1;
4352 if( index>=elem->NbNodes() || index<0 ) return -1;
4353 return elem->GetNode(index)->GetID();
4356 //=============================================================================
4358 * Returns IDs of nodes of given element
4360 //=============================================================================
4362 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4365 _preMeshInfo->FullLoadFromFile();
4367 SMESH::long_array_var aResult = new SMESH::long_array();
4368 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4370 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4372 aResult->length( elem->NbNodes() );
4373 for ( int i = 0; i < elem->NbNodes(); ++i )
4374 aResult[ i ] = elem->GetNode( i )->GetID();
4377 return aResult._retn();
4380 //=============================================================================
4382 * Returns true if given node is medium node
4383 * in given quadratic element
4385 //=============================================================================
4387 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4390 _preMeshInfo->FullLoadFromFile();
4392 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4393 if ( aSMESHDS_Mesh == NULL ) return false;
4395 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4396 if(!aNode) return false;
4397 // try to find element
4398 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4399 if(!elem) return false;
4401 return elem->IsMediumNode(aNode);
4405 //=============================================================================
4407 * Returns true if given node is medium node
4408 * in one of quadratic elements
4410 //=============================================================================
4412 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4413 SMESH::ElementType theElemType)
4416 _preMeshInfo->FullLoadFromFile();
4418 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4419 if ( aSMESHDS_Mesh == NULL ) return false;
4422 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4423 if(!aNode) return false;
4425 SMESH_MesherHelper aHelper( *(_impl) );
4427 SMDSAbs_ElementType aType;
4428 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4429 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4430 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4431 else aType = SMDSAbs_All;
4433 return aHelper.IsMedium(aNode,aType);
4437 //=============================================================================
4439 * Returns number of edges for given element
4441 //=============================================================================
4443 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4446 _preMeshInfo->FullLoadFromFile();
4448 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4449 if ( aSMESHDS_Mesh == NULL ) return -1;
4450 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4451 if(!elem) return -1;
4452 return elem->NbEdges();
4456 //=============================================================================
4458 * Returns number of faces for given element
4460 //=============================================================================
4462 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4465 _preMeshInfo->FullLoadFromFile();
4467 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4468 if ( aSMESHDS_Mesh == NULL ) return -1;
4469 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4470 if(!elem) return -1;
4471 return elem->NbFaces();
4474 //=======================================================================
4475 //function : GetElemFaceNodes
4476 //purpose : Returns nodes of given face (counted from zero) for given element.
4477 //=======================================================================
4479 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4480 CORBA::Short faceIndex)
4483 _preMeshInfo->FullLoadFromFile();
4485 SMESH::long_array_var aResult = new SMESH::long_array();
4486 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4488 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4490 SMDS_VolumeTool vtool( elem );
4491 if ( faceIndex < vtool.NbFaces() )
4493 aResult->length( vtool.NbFaceNodes( faceIndex ));
4494 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4495 for ( int i = 0; i < aResult->length(); ++i )
4496 aResult[ i ] = nn[ i ]->GetID();
4500 return aResult._retn();
4503 //=======================================================================
4504 //function : GetElemFaceNodes
4505 //purpose : Returns three components of normal of given mesh face.
4506 //=======================================================================
4508 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4509 CORBA::Boolean normalized)
4512 _preMeshInfo->FullLoadFromFile();
4514 SMESH::double_array_var aResult = new SMESH::double_array();
4516 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4519 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4521 aResult->length( 3 );
4522 aResult[ 0 ] = normal.X();
4523 aResult[ 1 ] = normal.Y();
4524 aResult[ 2 ] = normal.Z();
4527 return aResult._retn();
4530 //=======================================================================
4531 //function : FindElementByNodes
4532 //purpose : Returns an element based on all given nodes.
4533 //=======================================================================
4535 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4538 _preMeshInfo->FullLoadFromFile();
4540 CORBA::Long elemID(0);
4541 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4543 vector< const SMDS_MeshNode * > nn( nodes.length() );
4544 for ( int i = 0; i < nodes.length(); ++i )
4545 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4548 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4549 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4550 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4551 _impl->NbVolumes( ORDER_QUADRATIC )))
4552 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4554 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4559 //=============================================================================
4561 * Returns true if given element is polygon
4563 //=============================================================================
4565 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4568 _preMeshInfo->FullLoadFromFile();
4570 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4571 if ( aSMESHDS_Mesh == NULL ) return false;
4572 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4573 if(!elem) return false;
4574 return elem->IsPoly();
4578 //=============================================================================
4580 * Returns true if given element is quadratic
4582 //=============================================================================
4584 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4587 _preMeshInfo->FullLoadFromFile();
4589 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4590 if ( aSMESHDS_Mesh == NULL ) return false;
4591 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4592 if(!elem) return false;
4593 return elem->IsQuadratic();
4596 //=============================================================================
4598 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4600 //=============================================================================
4602 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4605 _preMeshInfo->FullLoadFromFile();
4607 if ( const SMDS_BallElement* ball =
4608 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4609 return ball->GetDiameter();
4614 //=============================================================================
4616 * Returns bary center for given element
4618 //=============================================================================
4620 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4623 _preMeshInfo->FullLoadFromFile();
4625 SMESH::double_array_var aResult = new SMESH::double_array();
4626 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4627 if ( aSMESHDS_Mesh == NULL )
4628 return aResult._retn();
4630 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4632 return aResult._retn();
4634 if(elem->GetType()==SMDSAbs_Volume) {
4635 SMDS_VolumeTool aTool;
4636 if(aTool.Set(elem)) {
4638 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4643 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4645 double x=0., y=0., z=0.;
4646 for(; anIt->more(); ) {
4648 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4662 return aResult._retn();
4665 //================================================================================
4667 * \brief Create a group of elements preventing computation of a sub-shape
4669 //================================================================================
4671 SMESH::ListOfGroups*
4672 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4673 const char* theGroupName )
4674 throw ( SALOME::SALOME_Exception )
4676 Unexpect aCatch(SALOME_SalomeException);
4678 if ( !theGroupName || strlen( theGroupName) == 0 )
4679 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4681 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4683 // submesh by subshape id
4684 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4685 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4688 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4689 if ( error && !error->myBadElements.empty())
4691 // sort bad elements by type
4692 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4693 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4694 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4695 for ( ; elemIt != elemEnd; ++elemIt )
4697 const SMDS_MeshElement* elem = *elemIt;
4698 if ( !elem ) continue;
4700 if ( elem->GetID() < 1 )
4702 // elem is a temporary element, make a real element
4703 vector< const SMDS_MeshNode* > nodes;
4704 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4705 while ( nIt->more() && elem )
4707 nodes.push_back( nIt->next() );
4708 if ( nodes.back()->GetID() < 1 )
4709 elem = 0; // a temporary element on temporary nodes
4713 ::SMESH_MeshEditor editor( _impl );
4714 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4718 elemsByType[ elem->GetType() ].push_back( elem );
4721 // how many groups to create?
4723 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4724 nbTypes += int( !elemsByType[ i ].empty() );
4725 groups->length( nbTypes );
4728 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4730 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4731 if ( elems.empty() ) continue;
4733 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4734 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4736 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4737 SMESH::SMESH_Mesh_var mesh = _this();
4738 SALOMEDS::SObject_wrap aSO =
4739 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4740 GEOM::GEOM_Object::_nil(), theGroupName);
4741 aSO->_is_nil(); // avoid "unused variable" warning
4743 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4744 if ( !grp_i ) continue;
4746 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4747 for ( size_t iE = 0; iE < elems.size(); ++iE )
4748 grpDS->SMDSGroup().Add( elems[ iE ]);
4753 return groups._retn();
4756 //=============================================================================
4758 * Create and publish group servants if any groups were imported or created anyhow
4760 //=============================================================================
4762 void SMESH_Mesh_i::CreateGroupServants()
4764 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4765 SMESH::SMESH_Mesh_var aMesh = _this();
4768 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4769 while ( groupIt->more() )
4771 ::SMESH_Group* group = groupIt->next();
4772 int anId = group->GetGroupDS()->GetID();
4774 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4775 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4777 addedIDs.insert( anId );
4779 SMESH_GroupBase_i* aGroupImpl;
4781 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4782 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4784 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4785 shape = groupOnGeom->GetShape();
4788 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4791 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4792 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4793 aGroupImpl->Register();
4795 // register CORBA object for persistence
4796 int nextId = _gen_i->RegisterObject( groupVar );
4797 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4798 else { nextId = 0; } // avoid "unused variable" warning in release mode
4800 // publishing the groups in the study
4801 if ( !aStudy->_is_nil() ) {
4802 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4803 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4806 if ( !addedIDs.empty() )
4809 set<int>::iterator id = addedIDs.begin();
4810 for ( ; id != addedIDs.end(); ++id )
4812 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4813 int i = std::distance( _mapGroups.begin(), it );
4814 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4819 //=============================================================================
4821 * \brief Return groups cantained in _mapGroups by their IDs
4823 //=============================================================================
4825 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4827 int nbGroups = groupIDs.size();
4828 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4829 aList->length( nbGroups );
4831 list<int>::const_iterator ids = groupIDs.begin();
4832 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4834 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4835 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4836 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4838 aList->length( nbGroups );
4839 return aList._retn();
4842 //=============================================================================
4844 * \brief Return information about imported file
4846 //=============================================================================
4848 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4850 SMESH::MedFileInfo_var res( _medFileInfo );
4851 if ( !res.operator->() ) {
4852 res = new SMESH::MedFileInfo;
4854 res->fileSize = res->major = res->minor = res->release = -1;
4859 //=============================================================================
4861 * \brief Pass names of mesh groups from study to mesh DS
4863 //=============================================================================
4865 void SMESH_Mesh_i::checkGroupNames()
4867 int nbGrp = NbGroups();
4871 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4872 if ( aStudy->_is_nil() )
4873 return; // nothing to do
4875 SMESH::ListOfGroups* grpList = 0;
4876 // avoid dump of "GetGroups"
4878 // store python dump into a local variable inside local scope
4879 SMESH::TPythonDump pDump; // do not delete this line of code
4880 grpList = GetGroups();
4883 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4884 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4887 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4888 if ( aGrpSO->_is_nil() )
4890 // correct name of the mesh group if necessary
4891 const char* guiName = aGrpSO->GetName();
4892 if ( strcmp(guiName, aGrp->GetName()) )
4893 aGrp->SetName( guiName );
4897 //=============================================================================
4899 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4901 //=============================================================================
4902 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4904 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4908 //=============================================================================
4910 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4912 //=============================================================================
4914 char* SMESH_Mesh_i::GetParameters()
4916 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4919 //=============================================================================
4921 * \brief Returns list of notebook variables used for last Mesh operation
4923 //=============================================================================
4924 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4926 SMESH::string_array_var aResult = new SMESH::string_array();
4927 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4929 CORBA::String_var aParameters = GetParameters();
4930 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4931 if ( !aStudy->_is_nil()) {
4932 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4933 if(aSections->length() > 0) {
4934 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4935 aResult->length(aVars.length());
4936 for(int i = 0;i < aVars.length();i++)
4937 aResult[i] = CORBA::string_dup( aVars[i]);
4941 return aResult._retn();
4944 //=======================================================================
4945 //function : GetTypes
4946 //purpose : Returns types of elements it contains
4947 //=======================================================================
4949 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4952 return _preMeshInfo->GetTypes();
4954 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4958 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4959 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4960 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4961 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4962 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4963 types->length( nbTypes );
4965 return types._retn();
4968 //=======================================================================
4969 //function : GetMesh
4970 //purpose : Returns self
4971 //=======================================================================
4973 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4975 return SMESH::SMESH_Mesh::_duplicate( _this() );
4978 //=======================================================================
4979 //function : IsMeshInfoCorrect
4980 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4981 // * happen if mesh data is not yet fully loaded from the file of study.
4982 //=======================================================================
4984 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4986 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4989 //=============================================================================
4991 * \brief Returns number of mesh elements per each \a EntityType
4993 //=============================================================================
4995 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4998 return _preMeshInfo->GetMeshInfo();
5000 SMESH::long_array_var aRes = new SMESH::long_array();
5001 aRes->length(SMESH::Entity_Last);
5002 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5004 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5006 return aRes._retn();
5007 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5008 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5009 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5010 return aRes._retn();
5013 //=============================================================================
5015 * \brief Returns number of mesh elements per each \a ElementType
5017 //=============================================================================
5019 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5021 SMESH::long_array_var aRes = new SMESH::long_array();
5022 aRes->length(SMESH::NB_ELEMENT_TYPES);
5023 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5026 const SMDS_MeshInfo* meshInfo = 0;
5028 meshInfo = _preMeshInfo;
5029 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5030 meshInfo = & meshDS->GetMeshInfo();
5033 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5034 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5036 return aRes._retn();
5039 //=============================================================================
5041 * Collect statistic of mesh elements given by iterator
5043 //=============================================================================
5045 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5046 SMESH::long_array& theInfo)
5048 if (!theItr) return;
5049 while (theItr->more())
5050 theInfo[ theItr->next()->GetEntityType() ]++;
5053 //=============================================================================
5054 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5055 * SMESH::ElementType type) */
5057 using namespace SMESH::Controls;
5058 //-----------------------------------------------------------------------------
5059 struct PredicateIterator : public SMDS_ElemIterator
5061 SMDS_ElemIteratorPtr _elemIter;
5062 PredicatePtr _predicate;
5063 const SMDS_MeshElement* _elem;
5065 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5066 PredicatePtr predicate):
5067 _elemIter(iterator), _predicate(predicate)
5075 virtual const SMDS_MeshElement* next()
5077 const SMDS_MeshElement* res = _elem;
5079 while ( _elemIter->more() && !_elem )
5081 _elem = _elemIter->next();
5082 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5089 //-----------------------------------------------------------------------------
5090 struct IDSourceIterator : public SMDS_ElemIterator
5092 const CORBA::Long* _idPtr;
5093 const CORBA::Long* _idEndPtr;
5094 SMESH::long_array_var _idArray;
5095 const SMDS_Mesh* _mesh;
5096 const SMDSAbs_ElementType _type;
5097 const SMDS_MeshElement* _elem;
5099 IDSourceIterator( const SMDS_Mesh* mesh,
5100 const CORBA::Long* ids,
5102 SMDSAbs_ElementType type):
5103 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5105 if ( _idPtr && nbIds && _mesh )
5108 IDSourceIterator( const SMDS_Mesh* mesh,
5109 SMESH::long_array* idArray,
5110 SMDSAbs_ElementType type):
5111 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5113 if ( idArray && _mesh )
5115 _idPtr = &_idArray[0];
5116 _idEndPtr = _idPtr + _idArray->length();
5124 virtual const SMDS_MeshElement* next()
5126 const SMDS_MeshElement* res = _elem;
5128 while ( _idPtr < _idEndPtr && !_elem )
5130 if ( _type == SMDSAbs_Node )
5132 _elem = _mesh->FindNode( *_idPtr++ );
5134 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5135 _elem->GetType() != _type )
5143 //-----------------------------------------------------------------------------
5145 struct NodeOfElemIterator : public SMDS_ElemIterator
5147 TColStd_MapOfInteger _checkedNodeIDs;
5148 SMDS_ElemIteratorPtr _elemIter;
5149 SMDS_ElemIteratorPtr _nodeIter;
5150 const SMDS_MeshElement* _node;
5152 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5154 if ( _elemIter && _elemIter->more() )
5156 _nodeIter = _elemIter->next()->nodesIterator();
5164 virtual const SMDS_MeshElement* next()
5166 const SMDS_MeshElement* res = _node;
5168 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5170 if ( _nodeIter->more() )
5172 _node = _nodeIter->next();
5173 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5178 _nodeIter = _elemIter->next()->nodesIterator();
5186 //=============================================================================
5188 * Return iterator on elements of given type in given object
5190 //=============================================================================
5192 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5193 SMESH::ElementType theType)
5195 SMDS_ElemIteratorPtr elemIt;
5196 bool typeOK = false;
5197 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5199 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5200 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5201 if ( !mesh_i ) return elemIt;
5202 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5204 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5206 elemIt = meshDS->elementsIterator( elemType );
5209 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5211 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5214 elemIt = sm->GetElements();
5215 if ( elemType != SMDSAbs_Node )
5217 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5218 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5222 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5224 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5225 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5227 elemIt = groupDS->GetElements();
5228 typeOK = ( groupDS->GetType() == elemType );
5231 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5233 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5235 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5236 if ( pred_i && pred_i->GetPredicate() )
5238 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5239 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5240 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5241 typeOK = ( filterType == elemType );
5247 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5248 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5249 if ( isNodes && elemType != SMDSAbs_Node )
5251 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5254 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5255 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5259 SMESH::long_array_var ids = theObject->GetIDs();
5260 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5262 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5265 if ( elemIt && elemIt->more() && !typeOK )
5267 if ( elemType == SMDSAbs_Node )
5269 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5273 elemIt = SMDS_ElemIteratorPtr();
5279 //=============================================================================
5280 namespace // Finding concurrent hypotheses
5281 //=============================================================================
5285 * \brief mapping of mesh dimension into shape type
5287 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5289 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5291 case 0: aType = TopAbs_VERTEX; break;
5292 case 1: aType = TopAbs_EDGE; break;
5293 case 2: aType = TopAbs_FACE; break;
5295 default:aType = TopAbs_SOLID; break;
5300 //-----------------------------------------------------------------------------
5302 * \brief Internal structure used to find concurent submeshes
5304 * It represents a pair < submesh, concurent dimension >, where
5305 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5306 * with another submesh. In other words, it is dimension of a hypothesis assigned
5313 int _dim; //!< a dimension the algo can build (concurrent dimension)
5314 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5315 TopTools_MapOfShape _shapeMap;
5316 SMESH_subMesh* _subMesh;
5317 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5319 //-----------------------------------------------------------------------------
5320 // Return the algorithm
5321 const SMESH_Algo* GetAlgo() const
5322 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5324 //-----------------------------------------------------------------------------
5326 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5328 const TopoDS_Shape& theShape)
5330 _subMesh = (SMESH_subMesh*)theSubMesh;
5331 SetShape( theDim, theShape );
5334 //-----------------------------------------------------------------------------
5336 void SetShape(const int theDim,
5337 const TopoDS_Shape& theShape)
5340 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5341 if (_dim >= _ownDim)
5342 _shapeMap.Add( theShape );
5344 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5345 for( ; anExp.More(); anExp.Next() )
5346 _shapeMap.Add( anExp.Current() );
5350 //-----------------------------------------------------------------------------
5351 //! Check sharing of sub-shapes
5352 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5353 const TopTools_MapOfShape& theToFind,
5354 const TopAbs_ShapeEnum theType)
5356 bool isShared = false;
5357 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5358 for (; !isShared && anItr.More(); anItr.Next() )
5360 const TopoDS_Shape aSubSh = anItr.Key();
5361 // check for case when concurrent dimensions are same
5362 isShared = theToFind.Contains( aSubSh );
5363 // check for sub-shape with concurrent dimension
5364 TopExp_Explorer anExp( aSubSh, theType );
5365 for ( ; !isShared && anExp.More(); anExp.Next() )
5366 isShared = theToFind.Contains( anExp.Current() );
5371 //-----------------------------------------------------------------------------
5372 //! check algorithms
5373 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5374 const SMESHDS_Hypothesis* theA2)
5376 if ( !theA1 || !theA2 ||
5377 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5378 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5379 return false; // one of the hypothesis is not algorithm
5380 // check algorithm names (should be equal)
5381 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5385 //-----------------------------------------------------------------------------
5386 //! Check if sub-shape hypotheses are concurrent
5387 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5389 if ( _subMesh == theOther->_subMesh )
5390 return false; // same sub-shape - should not be
5392 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5393 // any of the two submeshes is not on COMPOUND shape )
5394 // -> no concurrency
5395 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5396 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5397 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5398 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5399 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5402 // bool checkSubShape = ( _dim >= theOther->_dim )
5403 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5404 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5405 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5406 if ( !checkSubShape )
5409 // check algorithms to be same
5410 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5411 return true; // different algorithms -> concurrency !
5413 // check hypothesises for concurrence (skip first as algorithm)
5415 // pointers should be same, because it is referened from mesh hypothesis partition
5416 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5417 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5418 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5419 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5421 // the submeshes are concurrent if their algorithms has different parameters
5422 return nbSame != theOther->_hypotheses.size() - 1;
5425 // Return true if algorithm of this SMESH_DimHyp is used if no
5426 // sub-mesh order is imposed by the user
5427 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5429 // NeedDiscreteBoundary() algo has a higher priority
5430 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5431 theOther->GetAlgo()->NeedDiscreteBoundary() )
5432 return !this->GetAlgo()->NeedDiscreteBoundary();
5434 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5437 }; // end of SMESH_DimHyp
5438 //-----------------------------------------------------------------------------
5440 typedef list<const SMESH_DimHyp*> TDimHypList;
5442 //-----------------------------------------------------------------------------
5444 void addDimHypInstance(const int theDim,
5445 const TopoDS_Shape& theShape,
5446 const SMESH_Algo* theAlgo,
5447 const SMESH_subMesh* theSubMesh,
5448 const list <const SMESHDS_Hypothesis*>& theHypList,
5449 TDimHypList* theDimHypListArr )
5451 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5452 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5453 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5454 dimHyp->_hypotheses.push_front(theAlgo);
5455 listOfdimHyp.push_back( dimHyp );
5458 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5459 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5460 theHypList.begin(), theHypList.end() );
5463 //-----------------------------------------------------------------------------
5464 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5465 TDimHypList& theListOfConcurr)
5467 if ( theListOfConcurr.empty() )
5469 theListOfConcurr.push_back( theDimHyp );
5473 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5474 while ( hypIt != theListOfConcurr.end() &&
5475 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5477 theListOfConcurr.insert( hypIt, theDimHyp );
5481 //-----------------------------------------------------------------------------
5482 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5483 const TDimHypList& theListOfDimHyp,
5484 TDimHypList& theListOfConcurrHyp,
5485 set<int>& theSetOfConcurrId )
5487 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5488 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5490 const SMESH_DimHyp* curDimHyp = *rIt;
5491 if ( curDimHyp == theDimHyp )
5492 break; // meet own dimHyp pointer in same dimension
5494 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5495 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5497 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5502 //-----------------------------------------------------------------------------
5503 void unionLists(TListOfInt& theListOfId,
5504 TListOfListOfInt& theListOfListOfId,
5507 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5508 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5510 continue; //skip already treated lists
5511 // check if other list has any same submesh object
5512 TListOfInt& otherListOfId = *it;
5513 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5514 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5517 // union two lists (from source into target)
5518 TListOfInt::iterator it2 = otherListOfId.begin();
5519 for ( ; it2 != otherListOfId.end(); it2++ ) {
5520 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5521 theListOfId.push_back(*it2);
5523 // clear source list
5524 otherListOfId.clear();
5527 //-----------------------------------------------------------------------------
5529 //! free memory allocated for dimension-hypothesis objects
5530 void removeDimHyps( TDimHypList* theArrOfList )
5532 for (int i = 0; i < 4; i++ ) {
5533 TDimHypList& listOfdimHyp = theArrOfList[i];
5534 TDimHypList::const_iterator it = listOfdimHyp.begin();
5535 for ( ; it != listOfdimHyp.end(); it++ )
5540 //-----------------------------------------------------------------------------
5542 * \brief find common submeshes with given submesh
5543 * \param theSubMeshList list of already collected submesh to check
5544 * \param theSubMesh given submesh to intersect with other
5545 * \param theCommonSubMeshes collected common submeshes
5547 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5548 const SMESH_subMesh* theSubMesh,
5549 set<const SMESH_subMesh*>& theCommon )
5553 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5554 for ( ; it != theSubMeshList.end(); it++ )
5555 theSubMesh->FindIntersection( *it, theCommon );
5556 theSubMeshList.push_back( theSubMesh );
5557 //theCommon.insert( theSubMesh );
5560 //-----------------------------------------------------------------------------
5561 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5563 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5564 for ( ; listsIt != smLists.end(); ++listsIt )
5566 const TListOfInt& smIDs = *listsIt;
5567 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5575 //=============================================================================
5577 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5579 //=============================================================================
5581 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5583 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5584 if ( isSubMeshInList( submeshID, anOrder ))
5587 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5588 return isSubMeshInList( submeshID, allConurrent );
5591 //=============================================================================
5593 * \brief Return submesh objects list in meshing order
5595 //=============================================================================
5597 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5599 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5601 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5603 return aResult._retn();
5605 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5606 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5607 anOrder.splice( anOrder.end(), allConurrent );
5610 TListOfListOfInt::iterator listIt = anOrder.begin();
5611 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5612 unionLists( *listIt, anOrder, listIndx + 1 );
5614 // convert submesh ids into interface instances
5615 // and dump command into python
5616 convertMeshOrder( anOrder, aResult, false );
5618 return aResult._retn();
5621 //=============================================================================
5623 * \brief Finds concurrent sub-meshes
5625 //=============================================================================
5627 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5629 TListOfListOfInt anOrder;
5630 ::SMESH_Mesh& mesh = GetImpl();
5632 // collect submeshes and detect concurrent algorithms and hypothesises
5633 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5635 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5636 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5637 ::SMESH_subMesh* sm = (*i_sm).second;
5639 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5641 // list of assigned hypothesises
5642 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5643 // Find out dimensions where the submesh can be concurrent.
5644 // We define the dimensions by algo of each of hypotheses in hypList
5645 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5646 for( ; hypIt != hypList.end(); hypIt++ ) {
5647 SMESH_Algo* anAlgo = 0;
5648 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5649 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5650 // hyp it-self is algo
5651 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5653 // try to find algorithm with help of sub-shapes
5654 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5655 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5656 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5659 continue; // no algorithm assigned to a current submesh
5661 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5662 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5664 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5665 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5666 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5668 } // end iterations on submesh
5670 // iterate on created dimension-hypotheses and check for concurrents
5671 for ( int i = 0; i < 4; i++ ) {
5672 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5673 // check for concurrents in own and other dimensions (step-by-step)
5674 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5675 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5676 const SMESH_DimHyp* dimHyp = *dhIt;
5677 TDimHypList listOfConcurr;
5678 set<int> setOfConcurrIds;
5679 // looking for concurrents and collect into own list
5680 for ( int j = i; j < 4; j++ )
5681 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5682 // check if any concurrents found
5683 if ( listOfConcurr.size() > 0 ) {
5684 // add own submesh to list of concurrent
5685 addInOrderOfPriority( dimHyp, listOfConcurr );
5686 list<int> listOfConcurrIds;
5687 TDimHypList::iterator hypIt = listOfConcurr.begin();
5688 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5689 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5690 anOrder.push_back( listOfConcurrIds );
5695 removeDimHyps(dimHypListArr);
5697 // now, minimise the number of concurrent groups
5698 // Here we assume that lists of submeshes can have same submesh
5699 // in case of multi-dimension algorithms, as result
5700 // list with common submesh has to be united into one list
5702 TListOfListOfInt::iterator listIt = anOrder.begin();
5703 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5704 unionLists( *listIt, anOrder, listIndx + 1 );
5710 //=============================================================================
5712 * \brief Set submesh object order
5713 * \param theSubMeshArray submesh array order
5715 //=============================================================================
5717 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5720 _preMeshInfo->ForgetOrLoad();
5723 ::SMESH_Mesh& mesh = GetImpl();
5725 TPythonDump aPythonDump; // prevent dump of called methods
5726 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5728 TListOfListOfInt subMeshOrder;
5729 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5731 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5732 TListOfInt subMeshIds;
5733 aPythonDump << "[ ";
5734 // Collect subMeshes which should be clear
5735 // do it list-by-list, because modification of submesh order
5736 // take effect between concurrent submeshes only
5737 set<const SMESH_subMesh*> subMeshToClear;
5738 list<const SMESH_subMesh*> subMeshList;
5739 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5741 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5743 aPythonDump << ", ";
5744 aPythonDump << subMesh;
5745 subMeshIds.push_back( subMesh->GetId() );
5746 // detect common parts of submeshes
5747 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5748 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5750 aPythonDump << " ]";
5751 subMeshOrder.push_back( subMeshIds );
5753 // clear collected submeshes
5754 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5755 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5756 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5757 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5759 aPythonDump << " ])";
5761 mesh.SetMeshOrder( subMeshOrder );
5767 //=============================================================================
5769 * \brief Convert submesh ids into submesh interfaces
5771 //=============================================================================
5773 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5774 SMESH::submesh_array_array& theResOrder,
5775 const bool theIsDump)
5777 int nbSet = theIdsOrder.size();
5778 TPythonDump aPythonDump; // prevent dump of called methods
5780 aPythonDump << "[ ";
5781 theResOrder.length(nbSet);
5782 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5784 for( ; it != theIdsOrder.end(); it++ ) {
5785 // translate submesh identificators into submesh objects
5786 // takeing into account real number of concurrent lists
5787 const TListOfInt& aSubOrder = (*it);
5788 if (!aSubOrder.size())
5791 aPythonDump << "[ ";
5792 // convert shape indeces into interfaces
5793 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5794 aResSubSet->length(aSubOrder.size());
5795 TListOfInt::const_iterator subIt = aSubOrder.begin();
5797 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5798 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5800 SMESH::SMESH_subMesh_var subMesh =
5801 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5804 aPythonDump << ", ";
5805 aPythonDump << subMesh;
5807 aResSubSet[ j++ ] = subMesh;
5810 aPythonDump << " ]";
5812 theResOrder[ listIndx++ ] = aResSubSet;
5814 // correct number of lists
5815 theResOrder.length( listIndx );
5818 // finilise python dump
5819 aPythonDump << " ]";
5820 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5824 //================================================================================
5826 // Implementation of SMESH_MeshPartDS
5828 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5829 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5831 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5832 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5834 _meshDS = mesh_i->GetImpl().GetMeshDS();
5836 SetPersistentId( _meshDS->GetPersistentId() );
5838 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5840 // <meshPart> is the whole mesh
5841 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5843 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5844 myGroupSet = _meshDS->GetGroups();
5849 SMESH::long_array_var anIDs = meshPart->GetIDs();
5850 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5851 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5853 for (int i=0; i < anIDs->length(); i++)
5854 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5855 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5860 for (int i=0; i < anIDs->length(); i++)
5861 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5862 if ( _elements[ e->GetType() ].insert( e ).second )
5865 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5866 while ( nIt->more() )
5868 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5869 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5876 _meshDS = 0; // to enforce iteration on _elements and _nodes
5879 // -------------------------------------------------------------------------------------
5880 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5881 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5884 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5885 for ( ; partIt != meshPart.end(); ++partIt )
5886 if ( const SMDS_MeshElement * e = *partIt )
5887 if ( _elements[ e->GetType() ].insert( e ).second )
5890 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5891 while ( nIt->more() )
5893 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5894 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5900 // -------------------------------------------------------------------------------------
5901 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5903 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5905 typedef SMDS_SetIterator
5906 <const SMDS_MeshElement*,
5907 TIDSortedElemSet::const_iterator,
5908 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5909 SMDS_MeshElement::GeomFilter
5912 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5914 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5915 _elements[type].end(),
5916 SMDS_MeshElement::GeomFilter( geomType )));
5918 // -------------------------------------------------------------------------------------
5919 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5921 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5923 typedef SMDS_SetIterator
5924 <const SMDS_MeshElement*,
5925 TIDSortedElemSet::const_iterator,
5926 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5927 SMDS_MeshElement::EntityFilter
5930 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5932 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5933 _elements[type].end(),
5934 SMDS_MeshElement::EntityFilter( entity )));
5936 // -------------------------------------------------------------------------------------
5937 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5939 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5940 if ( type == SMDSAbs_All && !_meshDS )
5942 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5944 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5945 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5947 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5949 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5950 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5952 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5953 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5955 // -------------------------------------------------------------------------------------
5956 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5957 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5959 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5960 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5961 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5963 // -------------------------------------------------------------------------------------
5964 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5965 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5966 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5967 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5968 #undef _GET_ITER_DEFINE
5970 // END Implementation of SMESH_MeshPartDS
5972 //================================================================================