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 gr_i->changeLocalId( id );
1916 g->GetGroupDS()->SetColor( data._color );
1920 // update _mapSubMesh
1921 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1922 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1923 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1927 //=============================================================================
1929 * \brief Update objects depending on changed geom groups
1931 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1932 * issue 0020210: Update of a smesh group after modification of the associated geom group
1934 //=============================================================================
1936 void SMESH_Mesh_i::CheckGeomGroupModif()
1938 if ( !_impl->HasShapeToMesh() ) return;
1940 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1941 if ( study->_is_nil() ) return;
1943 CORBA::Long nbEntities = NbNodes() + NbElements();
1945 // Check if group contents changed
1947 typedef map< string, TopoDS_Shape > TEntry2Geom;
1948 TEntry2Geom newGroupContents;
1950 list<TGeomGroupData>::iterator
1951 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1952 for ( ; data != dataEnd; ++data )
1954 pair< TEntry2Geom::iterator, bool > it_new =
1955 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1956 bool processedGroup = !it_new.second;
1957 TopoDS_Shape& newShape = it_new.first->second;
1958 if ( !processedGroup )
1959 newShape = newGroupShape( *data );
1960 if ( newShape.IsNull() )
1961 continue; // no changes
1964 _preMeshInfo->ForgetOrLoad();
1966 if ( processedGroup ) { // update group indices
1967 list<TGeomGroupData>::iterator data2 = data;
1968 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1969 data->_indices = data2->_indices;
1972 // Update SMESH objects according to new GEOM group contents
1974 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1975 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
1977 int oldID = submesh->GetId();
1978 if ( !_mapSubMeshIor.count( oldID ))
1980 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
1982 // update hypotheses
1983 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
1984 list <const SMESHDS_Hypothesis * >::iterator hypIt;
1985 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
1987 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
1988 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
1990 // care of submeshes
1991 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
1992 int newID = newSubmesh->GetId();
1993 if ( newID != oldID ) {
1994 _mapSubMesh [ newID ] = newSubmesh;
1995 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
1996 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
1997 _mapSubMesh. erase(oldID);
1998 _mapSubMesh_i. erase(oldID);
1999 _mapSubMeshIor.erase(oldID);
2000 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2005 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2006 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2007 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2009 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2011 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2012 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2013 ds->SetShape( newShape );
2018 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2019 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2021 // Remove groups and submeshes basing on removed sub-shapes
2023 TopTools_MapOfShape newShapeMap;
2024 TopoDS_Iterator shapeIt( newShape );
2025 for ( ; shapeIt.More(); shapeIt.Next() )
2026 newShapeMap.Add( shapeIt.Value() );
2028 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2029 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2031 if ( newShapeMap.Contains( shapeIt.Value() ))
2033 TopTools_IndexedMapOfShape oldShapeMap;
2034 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2035 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2037 const TopoDS_Shape& oldShape = oldShapeMap(i);
2038 int oldInd = meshDS->ShapeToIndex( oldShape );
2040 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2041 if ( i_smIor != _mapSubMeshIor.end() ) {
2042 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2045 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2046 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2048 // check if a group bases on oldInd shape
2049 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2050 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2051 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2052 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2054 RemoveGroup( i_grp->second ); // several groups can base on same shape
2055 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2060 // Reassign hypotheses and update groups after setting the new shape to mesh
2062 // collect anassigned hypotheses
2063 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2064 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2065 TShapeHypList assignedHyps;
2066 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2068 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2069 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2070 if ( !hyps.empty() ) {
2071 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2072 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2073 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2076 // collect shapes supporting groups
2077 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2078 TShapeTypeList groupData;
2079 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2080 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2081 for ( ; grIt != groups.end(); ++grIt )
2083 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2085 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2087 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2088 _impl->ShapeToMesh( newShape );
2090 // reassign hypotheses
2091 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2092 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2094 TIndexedShape& geom = indS_hyps->first;
2095 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2096 int oldID = geom._index;
2097 int newID = meshDS->ShapeToIndex( geom._shape );
2098 if ( oldID == 1 ) { // main shape
2100 geom._shape = newShape;
2104 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2105 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2106 // care of submeshes
2107 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2108 if ( newID != oldID ) {
2109 _mapSubMesh [ newID ] = newSubmesh;
2110 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2111 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2112 _mapSubMesh. erase(oldID);
2113 _mapSubMesh_i. erase(oldID);
2114 _mapSubMeshIor.erase(oldID);
2115 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2119 TShapeTypeList::iterator geomType = groupData.begin();
2120 for ( ; geomType != groupData.end(); ++geomType )
2122 const TIndexedShape& geom = geomType->first;
2123 int oldID = geom._index;
2124 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2127 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2128 CORBA::String_var name = groupSO->GetName();
2130 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2132 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2133 group_i->changeLocalId( newID );
2136 break; // everything has been updated
2139 } // loop on group data
2143 CORBA::Long newNbEntities = NbNodes() + NbElements();
2144 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2145 if ( newNbEntities != nbEntities )
2147 // Add all SObjects with icons to soToUpdateIcons
2148 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2150 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2151 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2152 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2154 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2155 i_gr != _mapGroups.end(); ++i_gr ) // groups
2156 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2159 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2160 for ( ; so != soToUpdateIcons.end(); ++so )
2161 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2164 //=============================================================================
2166 * \brief Create standalone group from a group on geometry or filter
2168 //=============================================================================
2170 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2171 throw (SALOME::SALOME_Exception)
2173 SMESH::SMESH_Group_var aGroup;
2178 _preMeshInfo->FullLoadFromFile();
2180 if ( theGroup->_is_nil() )
2181 return aGroup._retn();
2183 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2185 return aGroup._retn();
2187 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2189 const int anId = aGroupToRem->GetLocalID();
2190 if ( !_impl->ConvertToStandalone( anId ) )
2191 return aGroup._retn();
2192 removeGeomGroupData( theGroup );
2194 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2196 // remove old instance of group from own map
2197 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2198 _mapGroups.erase( anId );
2200 SALOMEDS::StudyBuilder_var builder;
2201 SALOMEDS::SObject_wrap aGroupSO;
2202 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2203 if ( !aStudy->_is_nil() ) {
2204 builder = aStudy->NewBuilder();
2205 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2206 if ( !aGroupSO->_is_nil() )
2208 // remove reference to geometry
2209 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2210 for ( ; chItr->More(); chItr->Next() )
2211 // Remove group's child SObject
2212 builder->RemoveObject( chItr->Value() );
2214 // Update Python script
2215 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2216 << ".ConvertToStandalone( " << aGroupSO << " )";
2218 // change icon of Group on Filter
2221 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2222 const int isEmpty = ( elemTypes->length() == 0 );
2225 SALOMEDS::GenericAttribute_wrap anAttr =
2226 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2227 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2228 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2234 // remember new group in own map
2235 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2236 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2238 // register CORBA object for persistence
2239 _gen_i->RegisterObject( aGroup );
2241 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2242 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2243 //aGroup->Register();
2244 aGroupToRem->UnRegister();
2246 SMESH_CATCH( SMESH::throwCorbaException );
2248 return aGroup._retn();
2251 //=============================================================================
2255 //=============================================================================
2257 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2259 if(MYDEBUG) MESSAGE( "createSubMesh" );
2260 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2261 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2262 const int subMeshId = mySubMesh->GetId();
2264 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2265 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2267 _mapSubMesh [subMeshId] = mySubMesh;
2268 _mapSubMesh_i [subMeshId] = subMeshServant;
2269 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2271 subMeshServant->Register();
2273 // register CORBA object for persistence
2274 int nextId = _gen_i->RegisterObject( subMesh );
2275 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2276 else { nextId = 0; } // avoid "unused variable" warning
2278 // to track changes of GEOM groups
2279 addGeomGroupData( theSubShapeObject, subMesh );
2281 return subMesh._retn();
2284 //=======================================================================
2285 //function : getSubMesh
2287 //=======================================================================
2289 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2291 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2292 if ( it == _mapSubMeshIor.end() )
2293 return SMESH::SMESH_subMesh::_nil();
2295 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2298 //=============================================================================
2302 //=============================================================================
2304 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2305 GEOM::GEOM_Object_ptr theSubShapeObject )
2307 bool isHypChanged = false;
2308 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2309 return isHypChanged;
2311 const int subMeshId = theSubMesh->GetId();
2313 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2315 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2317 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2320 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2321 isHypChanged = !hyps.empty();
2322 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2323 for ( ; hyp != hyps.end(); ++hyp )
2324 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2331 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2332 isHypChanged = ( aHypList->length() > 0 );
2333 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2334 removeHypothesis( theSubShapeObject, aHypList[i] );
2337 catch( const SALOME::SALOME_Exception& ) {
2338 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2340 removeGeomGroupData( theSubShapeObject );
2344 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2345 if ( id_smi != _mapSubMesh_i.end() )
2346 id_smi->second->UnRegister();
2348 // remove a CORBA object
2349 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2350 if ( id_smptr != _mapSubMeshIor.end() )
2351 SMESH::SMESH_subMesh_var( id_smptr->second );
2353 _mapSubMesh.erase(subMeshId);
2354 _mapSubMesh_i.erase(subMeshId);
2355 _mapSubMeshIor.erase(subMeshId);
2357 return isHypChanged;
2360 //=============================================================================
2364 //=============================================================================
2366 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2367 const char* theName,
2368 const TopoDS_Shape& theShape,
2369 const SMESH_PredicatePtr& thePredicate )
2371 std::string newName;
2372 if ( !theName || strlen( theName ) == 0 )
2374 std::set< std::string > presentNames;
2375 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2376 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2378 CORBA::String_var name = i_gr->second->GetName();
2379 presentNames.insert( name.in() );
2382 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2383 } while ( !presentNames.insert( newName ).second );
2384 theName = newName.c_str();
2387 SMESH::SMESH_GroupBase_var aGroup;
2388 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2390 SMESH_GroupBase_i* aGroupImpl;
2391 if ( !theShape.IsNull() )
2392 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2393 else if ( thePredicate )
2394 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2396 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2398 aGroup = aGroupImpl->_this();
2399 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2400 aGroupImpl->Register();
2402 // register CORBA object for persistence
2403 int nextId = _gen_i->RegisterObject( aGroup );
2404 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2405 else { nextId = 0; } // avoid "unused variable" warning in release mode
2407 // to track changes of GEOM groups
2408 if ( !theShape.IsNull() ) {
2409 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2410 addGeomGroupData( geom, aGroup );
2413 return aGroup._retn();
2416 //=============================================================================
2418 * SMESH_Mesh_i::removeGroup
2420 * Should be called by ~SMESH_Group_i()
2422 //=============================================================================
2424 void SMESH_Mesh_i::removeGroup( const int theId )
2426 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2427 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2428 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2429 _mapGroups.erase( theId );
2430 removeGeomGroupData( group );
2431 if ( !_impl->RemoveGroup( theId ))
2433 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2434 RemoveGroup( group );
2436 group->UnRegister();
2440 //=============================================================================
2444 //=============================================================================
2446 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2447 throw(SALOME::SALOME_Exception)
2449 SMESH::log_array_var aLog;
2453 _preMeshInfo->FullLoadFromFile();
2455 list < SMESHDS_Command * >logDS = _impl->GetLog();
2456 aLog = new SMESH::log_array;
2458 int lg = logDS.size();
2461 list < SMESHDS_Command * >::iterator its = logDS.begin();
2462 while(its != logDS.end()){
2463 SMESHDS_Command *com = *its;
2464 int comType = com->GetType();
2466 int lgcom = com->GetNumber();
2468 const list < int >&intList = com->GetIndexes();
2469 int inum = intList.size();
2471 list < int >::const_iterator ii = intList.begin();
2472 const list < double >&coordList = com->GetCoords();
2473 int rnum = coordList.size();
2475 list < double >::const_iterator ir = coordList.begin();
2476 aLog[indexLog].commandType = comType;
2477 aLog[indexLog].number = lgcom;
2478 aLog[indexLog].coords.length(rnum);
2479 aLog[indexLog].indexes.length(inum);
2480 for(int i = 0; i < rnum; i++){
2481 aLog[indexLog].coords[i] = *ir;
2482 //MESSAGE(" "<<i<<" "<<ir.Value());
2485 for(int i = 0; i < inum; i++){
2486 aLog[indexLog].indexes[i] = *ii;
2487 //MESSAGE(" "<<i<<" "<<ii.Value());
2496 SMESH_CATCH( SMESH::throwCorbaException );
2498 return aLog._retn();
2502 //=============================================================================
2506 //=============================================================================
2508 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2512 SMESH_CATCH( SMESH::throwCorbaException );
2515 //=============================================================================
2519 //=============================================================================
2521 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2526 //=============================================================================
2530 //=============================================================================
2532 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2537 //=============================================================================
2540 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2541 // issue 0020918: groups removal is caused by hyp modification
2542 // issue 0021208: to forget not loaded mesh data at hyp modification
2543 struct TCallUp_i : public SMESH_Mesh::TCallUp
2545 SMESH_Mesh_i* _mesh;
2546 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2547 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2548 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2549 virtual void Load () { _mesh->Load(); }
2553 //================================================================================
2555 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2557 //================================================================================
2559 void SMESH_Mesh_i::onHypothesisModified()
2562 _preMeshInfo->ForgetOrLoad();
2565 //=============================================================================
2569 //=============================================================================
2571 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2573 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2576 _impl->SetCallUp( new TCallUp_i(this));
2579 //=============================================================================
2583 //=============================================================================
2585 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2587 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2591 //=============================================================================
2593 * Return mesh editor
2595 //=============================================================================
2597 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2598 throw (SALOME::SALOME_Exception)
2600 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2604 _preMeshInfo->FullLoadFromFile();
2606 // Create MeshEditor
2608 _editor = new SMESH_MeshEditor_i( this, false );
2609 aMeshEdVar = _editor->_this();
2611 // Update Python script
2612 TPythonDump() << _editor << " = "
2613 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2615 SMESH_CATCH( SMESH::throwCorbaException );
2617 return aMeshEdVar._retn();
2620 //=============================================================================
2622 * Return mesh edition previewer
2624 //=============================================================================
2626 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2627 throw (SALOME::SALOME_Exception)
2629 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2633 _preMeshInfo->FullLoadFromFile();
2635 if ( !_previewEditor )
2636 _previewEditor = new SMESH_MeshEditor_i( this, true );
2637 aMeshEdVar = _previewEditor->_this();
2639 SMESH_CATCH( SMESH::throwCorbaException );
2641 return aMeshEdVar._retn();
2644 //================================================================================
2646 * \brief Return true if the mesh has been edited since a last total re-compute
2647 * and those modifications may prevent successful partial re-compute
2649 //================================================================================
2651 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2653 Unexpect aCatch(SALOME_SalomeException);
2654 return _impl->HasModificationsToDiscard();
2657 //================================================================================
2659 * \brief Returns a random unique color
2661 //================================================================================
2663 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2665 const int MAX_ATTEMPTS = 100;
2667 double tolerance = 0.5;
2668 SALOMEDS::Color col;
2672 // generate random color
2673 double red = (double)rand() / RAND_MAX;
2674 double green = (double)rand() / RAND_MAX;
2675 double blue = (double)rand() / RAND_MAX;
2676 // check existence in the list of the existing colors
2677 bool matched = false;
2678 std::list<SALOMEDS::Color>::const_iterator it;
2679 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2680 SALOMEDS::Color color = *it;
2681 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2682 matched = tol < tolerance;
2684 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2685 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2693 //=============================================================================
2695 * Sets auto-color mode. If it is on, groups get unique random colors
2697 //=============================================================================
2699 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2701 Unexpect aCatch(SALOME_SalomeException);
2702 _impl->SetAutoColor(theAutoColor);
2704 TPythonDump pyDump; // not to dump group->SetColor() from below code
2705 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2707 std::list<SALOMEDS::Color> aReservedColors;
2708 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2709 for ( ; it != _mapGroups.end(); it++ ) {
2710 if ( CORBA::is_nil( it->second )) continue;
2711 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2712 it->second->SetColor( aColor );
2713 aReservedColors.push_back( aColor );
2717 //=============================================================================
2719 * Returns true if auto-color mode is on
2721 //=============================================================================
2723 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2725 Unexpect aCatch(SALOME_SalomeException);
2726 return _impl->GetAutoColor();
2729 //=============================================================================
2731 * Checks if there are groups with equal names
2733 //=============================================================================
2735 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2737 return _impl->HasDuplicatedGroupNamesMED();
2740 //================================================================================
2742 * \brief Care of a file before exporting mesh into it
2744 //================================================================================
2746 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2748 TCollection_AsciiString aFullName ((char*)file);
2749 OSD_Path aPath (aFullName);
2750 OSD_File aFile (aPath);
2751 if (aFile.Exists()) {
2752 // existing filesystem node
2753 if (aFile.KindOfFile() == OSD_FILE) {
2754 if (aFile.IsWriteable()) {
2759 if (aFile.Failed()) {
2760 TCollection_AsciiString msg ("File ");
2761 msg += aFullName + " cannot be replaced.";
2762 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2765 TCollection_AsciiString msg ("File ");
2766 msg += aFullName + " cannot be overwritten.";
2767 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2770 TCollection_AsciiString msg ("Location ");
2771 msg += aFullName + " is not a file.";
2772 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2775 // nonexisting file; check if it can be created
2777 aFile.Build(OSD_WriteOnly, OSD_Protection());
2778 if (aFile.Failed()) {
2779 TCollection_AsciiString msg ("You cannot create the file ");
2780 msg += aFullName + ". Check the directory existance and access rights.";
2781 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2789 //================================================================================
2791 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2792 * \param file - file name
2793 * \param overwrite - to erase the file or not
2794 * \retval string - mesh name
2796 //================================================================================
2798 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2799 CORBA::Boolean overwrite)
2802 PrepareForWriting(file, overwrite);
2803 string aMeshName = "Mesh";
2804 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2805 if ( !aStudy->_is_nil() ) {
2806 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2807 if ( !aMeshSO->_is_nil() ) {
2808 CORBA::String_var name = aMeshSO->GetName();
2810 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2811 if ( !aStudy->GetProperties()->IsLocked() )
2813 SALOMEDS::GenericAttribute_wrap anAttr;
2814 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2815 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2816 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2817 ASSERT(!aFileName->_is_nil());
2818 aFileName->SetValue(file);
2819 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2820 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2821 ASSERT(!aFileType->_is_nil());
2822 aFileType->SetValue("FICHIERMED");
2826 // Update Python script
2827 // set name of mesh before export
2828 TPythonDump() << _gen_i << ".SetName("
2829 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2831 // check names of groups
2837 //================================================================================
2839 * \brief Export to med file
2841 //================================================================================
2843 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2844 CORBA::Boolean auto_groups,
2845 SMESH::MED_VERSION theVersion,
2846 CORBA::Boolean overwrite,
2847 CORBA::Boolean autoDimension)
2848 throw(SALOME::SALOME_Exception)
2852 _preMeshInfo->FullLoadFromFile();
2854 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2855 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2857 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2858 << file << "', " << auto_groups << ", "
2859 << theVersion << ", " << overwrite << ", "
2860 << autoDimension << " )";
2862 SMESH_CATCH( SMESH::throwCorbaException );
2865 //================================================================================
2867 * \brief Export a mesh to a med file
2869 //================================================================================
2871 void SMESH_Mesh_i::ExportToMED (const char* file,
2872 CORBA::Boolean auto_groups,
2873 SMESH::MED_VERSION theVersion)
2874 throw(SALOME::SALOME_Exception)
2876 ExportToMEDX(file,auto_groups,theVersion,true);
2879 //================================================================================
2881 * \brief Export a mesh to a med file
2883 //================================================================================
2885 void SMESH_Mesh_i::ExportMED (const char* file,
2886 CORBA::Boolean auto_groups)
2887 throw(SALOME::SALOME_Exception)
2889 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2892 //================================================================================
2894 * \brief Export a mesh to a SAUV file
2896 //================================================================================
2898 void SMESH_Mesh_i::ExportSAUV (const char* file,
2899 CORBA::Boolean auto_groups)
2900 throw(SALOME::SALOME_Exception)
2902 Unexpect aCatch(SALOME_SalomeException);
2904 _preMeshInfo->FullLoadFromFile();
2906 string aMeshName = prepareMeshNameAndGroups(file, true);
2907 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2908 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2909 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2913 //================================================================================
2915 * \brief Export a mesh to a DAT file
2917 //================================================================================
2919 void SMESH_Mesh_i::ExportDAT (const char *file)
2920 throw(SALOME::SALOME_Exception)
2922 Unexpect aCatch(SALOME_SalomeException);
2924 _preMeshInfo->FullLoadFromFile();
2926 // Update Python script
2927 // check names of groups
2929 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2932 PrepareForWriting(file);
2933 _impl->ExportDAT(file);
2936 //================================================================================
2938 * \brief Export a mesh to an UNV file
2940 //================================================================================
2942 void SMESH_Mesh_i::ExportUNV (const char *file)
2943 throw(SALOME::SALOME_Exception)
2945 Unexpect aCatch(SALOME_SalomeException);
2947 _preMeshInfo->FullLoadFromFile();
2949 // Update Python script
2950 // check names of groups
2952 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2955 PrepareForWriting(file);
2956 _impl->ExportUNV(file);
2959 //================================================================================
2961 * \brief Export a mesh to an STL file
2963 //================================================================================
2965 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2966 throw(SALOME::SALOME_Exception)
2968 Unexpect aCatch(SALOME_SalomeException);
2970 _preMeshInfo->FullLoadFromFile();
2972 // Update Python script
2973 // check names of groups
2975 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2976 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2979 PrepareForWriting(file);
2980 _impl->ExportSTL(file, isascii);
2983 //================================================================================
2985 * \brief Export a part of mesh to a med file
2987 //================================================================================
2989 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
2991 CORBA::Boolean auto_groups,
2992 SMESH::MED_VERSION version,
2993 CORBA::Boolean overwrite,
2994 CORBA::Boolean autoDimension,
2995 const GEOM::ListOfFields& fields,
2996 const char* geomAssocFields)
2997 throw (SALOME::SALOME_Exception)
3001 _preMeshInfo->FullLoadFromFile();
3004 bool have0dField = false;
3005 if ( fields.length() > 0 )
3007 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3008 if ( shapeToMesh->_is_nil() )
3009 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3011 for ( size_t i = 0; i < fields.length(); ++i )
3013 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3014 THROW_SALOME_CORBA_EXCEPTION
3015 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3016 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3017 if ( fieldShape->_is_nil() )
3018 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3019 if ( !fieldShape->IsSame( shapeToMesh ) )
3020 THROW_SALOME_CORBA_EXCEPTION
3021 ( "Field defined not on shape", SALOME::BAD_PARAM);
3022 if ( fields[i]->GetDimension() == 0 )
3025 if ( geomAssocFields )
3026 for ( int i = 0; geomAssocFields[i]; ++i )
3027 switch ( geomAssocFields[i] ) {
3028 case 'v':case 'e':case 'f':case 's': break;
3029 case 'V':case 'E':case 'F':case 'S': break;
3030 default: THROW_SALOME_CORBA_EXCEPTION
3031 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3035 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3039 string aMeshName = "Mesh";
3040 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3041 if ( CORBA::is_nil( meshPart ) ||
3042 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3044 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3045 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3046 version, 0, autoDimension, have0dField);
3047 meshDS = _impl->GetMeshDS();
3052 _preMeshInfo->FullLoadFromFile();
3054 PrepareForWriting(file, overwrite);
3056 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3057 if ( !aStudy->_is_nil() ) {
3058 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3059 if ( !SO->_is_nil() ) {
3060 CORBA::String_var name = SO->GetName();
3064 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3065 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3066 version, partDS, autoDimension, have0dField);
3067 meshDS = tmpDSDeleter._obj = partDS;
3072 if ( _impl->HasShapeToMesh() )
3074 DriverMED_W_Field fieldWriter;
3075 fieldWriter.SetFile( file );
3076 fieldWriter.SetMeshName( aMeshName );
3077 fieldWriter.AddODOnVertices( have0dField );
3079 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3083 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3084 goList->length( fields.length() );
3085 for ( size_t i = 0; i < fields.length(); ++i )
3087 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3090 TPythonDump() << _this() << ".ExportPartToMED( "
3091 << meshPart << ", r'" << file << "', "
3092 << auto_groups << ", " << version << ", " << overwrite << ", "
3093 << autoDimension << ", " << goList
3094 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3096 SMESH_CATCH( SMESH::throwCorbaException );
3099 //================================================================================
3101 * Write GEOM fields to MED file
3103 //================================================================================
3105 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3106 SMESHDS_Mesh* meshDS,
3107 const GEOM::ListOfFields& fields,
3108 const char* geomAssocFields)
3110 #define METH "SMESH_Mesh_i::exportMEDFields() "
3112 if (( fields.length() < 1 ) &&
3113 ( !geomAssocFields || !geomAssocFields[0] ))
3116 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3117 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3118 std::vector< int > subIdsByDim[ 4 ];
3119 const double noneDblValue = 0.;
3120 const double noneIntValue = 0;
3122 for ( size_t iF = 0; iF < fields.length(); ++iF )
3126 int dim = fields[ iF ]->GetDimension();
3127 SMDSAbs_ElementType elemType;
3128 TopAbs_ShapeEnum shapeType;
3130 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3131 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3132 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3133 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3135 continue; // skip fields on whole shape
3137 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3138 if ( dataType == GEOM::FDT_String )
3140 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3141 if ( stepIDs->length() < 1 )
3143 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3144 if ( comps->length() < 1 )
3146 CORBA::String_var name = fields[ iF ]->GetName();
3148 if ( !fieldWriter.Set( meshDS,
3152 ( dataType == GEOM::FDT_Int )))
3155 for ( size_t iC = 0; iC < comps->length(); ++iC )
3156 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3158 // find sub-shape IDs
3160 std::vector< int >& subIds = subIdsByDim[ dim ];
3161 if ( subIds.empty() )
3162 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3163 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3164 subIds.push_back( id );
3168 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3172 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3174 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3175 if ( step->_is_nil() )
3178 CORBA::Long stamp = step->GetStamp();
3179 CORBA::Long id = step->GetID();
3180 fieldWriter.SetDtIt( int( stamp ), int( id ));
3182 // fill dblVals or intVals
3185 case GEOM::FDT_Double:
3187 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3188 if ( dblStep->_is_nil() ) continue;
3189 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3190 if ( vv->length() != subIds.size() )
3191 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3192 for ( size_t i = 0; i < vv->length(); ++i )
3193 dblVals[ subIds[ i ]] = vv[ i ];
3198 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3199 if ( intStep->_is_nil() ) continue;
3200 GEOM::ListOfLong_var vv = intStep->GetValues();
3201 if ( vv->length() != subIds.size() )
3202 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3203 for ( size_t i = 0; i < vv->length(); ++i )
3204 intVals[ subIds[ i ]] = (int) vv[ i ];
3207 case GEOM::FDT_Bool:
3209 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3210 if ( boolStep->_is_nil() ) continue;
3211 GEOM::short_array_var vv = boolStep->GetValues();
3212 if ( vv->length() != subIds.size() )
3213 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3214 for ( size_t i = 0; i < vv->length(); ++i )
3215 intVals[ subIds[ i ]] = (int) vv[ i ];
3221 // pass values to fieldWriter
3222 elemIt = fieldWriter.GetOrderedElems();
3223 if ( dataType == GEOM::FDT_Double )
3224 while ( elemIt->more() )
3226 const SMDS_MeshElement* e = elemIt->next();
3227 const int shapeID = e->getshapeId();
3228 if ( shapeID < 1 || shapeID >= dblVals.size() )
3229 fieldWriter.AddValue( noneDblValue );
3231 fieldWriter.AddValue( dblVals[ shapeID ]);
3234 while ( elemIt->more() )
3236 const SMDS_MeshElement* e = elemIt->next();
3237 const int shapeID = e->getshapeId();
3238 if ( shapeID < 1 || shapeID >= intVals.size() )
3239 fieldWriter.AddValue( noneIntValue );
3241 fieldWriter.AddValue( intVals[ shapeID ]);
3245 fieldWriter.Perform();
3246 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3247 if ( res && res->IsKO() )
3249 if ( res->myComment.empty() )
3250 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3252 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3258 if ( !geomAssocFields || !geomAssocFields[0] )
3261 // write geomAssocFields
3263 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3264 shapeDim[ TopAbs_COMPOUND ] = 3;
3265 shapeDim[ TopAbs_COMPSOLID ] = 3;
3266 shapeDim[ TopAbs_SOLID ] = 3;
3267 shapeDim[ TopAbs_SHELL ] = 2;
3268 shapeDim[ TopAbs_FACE ] = 2;
3269 shapeDim[ TopAbs_WIRE ] = 1;
3270 shapeDim[ TopAbs_EDGE ] = 1;
3271 shapeDim[ TopAbs_VERTEX ] = 0;
3272 shapeDim[ TopAbs_SHAPE ] = 3;
3274 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3276 std::vector< std::string > compNames;
3277 switch ( geomAssocFields[ iF ]) {
3279 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
3280 compNames.push_back( "dim" );
3283 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
3286 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
3289 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
3293 compNames.push_back( "id" );
3294 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3295 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3297 fieldWriter.SetDtIt( -1, -1 );
3299 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3303 if ( compNames.size() == 2 ) // _vertices_
3304 while ( elemIt->more() )
3306 const SMDS_MeshElement* e = elemIt->next();
3307 const int shapeID = e->getshapeId();
3310 fieldWriter.AddValue( -1 );
3311 fieldWriter.AddValue( -1 );
3315 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3316 fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
3317 fieldWriter.AddValue( shapeID );
3321 while ( elemIt->more() )
3323 const SMDS_MeshElement* e = elemIt->next();
3324 const int shapeID = e->getshapeId();
3326 fieldWriter.AddValue( -1 );
3328 fieldWriter.AddValue( shapeID );
3332 fieldWriter.Perform();
3333 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3334 if ( res && res->IsKO() )
3336 if ( res->myComment.empty() )
3337 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3339 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3342 } // loop on geomAssocFields
3347 //================================================================================
3349 * \brief Export a part of mesh to a DAT file
3351 //================================================================================
3353 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3355 throw (SALOME::SALOME_Exception)
3357 Unexpect aCatch(SALOME_SalomeException);
3359 _preMeshInfo->FullLoadFromFile();
3361 PrepareForWriting(file);
3363 SMESH_MeshPartDS partDS( meshPart );
3364 _impl->ExportDAT(file,&partDS);
3366 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3367 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3369 //================================================================================
3371 * \brief Export a part of mesh to an UNV file
3373 //================================================================================
3375 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3377 throw (SALOME::SALOME_Exception)
3379 Unexpect aCatch(SALOME_SalomeException);
3381 _preMeshInfo->FullLoadFromFile();
3383 PrepareForWriting(file);
3385 SMESH_MeshPartDS partDS( meshPart );
3386 _impl->ExportUNV(file, &partDS);
3388 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3389 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3391 //================================================================================
3393 * \brief Export a part of mesh to an STL file
3395 //================================================================================
3397 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3399 ::CORBA::Boolean isascii)
3400 throw (SALOME::SALOME_Exception)
3402 Unexpect aCatch(SALOME_SalomeException);
3404 _preMeshInfo->FullLoadFromFile();
3406 PrepareForWriting(file);
3408 SMESH_MeshPartDS partDS( meshPart );
3409 _impl->ExportSTL(file, isascii, &partDS);
3411 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3412 << meshPart<< ", r'" << file << "', " << isascii << ")";
3415 //================================================================================
3417 * \brief Export a part of mesh to an STL file
3419 //================================================================================
3421 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3423 CORBA::Boolean overwrite)
3424 throw (SALOME::SALOME_Exception)
3427 Unexpect aCatch(SALOME_SalomeException);
3429 _preMeshInfo->FullLoadFromFile();
3431 PrepareForWriting(file,overwrite);
3433 SMESH_MeshPartDS partDS( meshPart );
3434 _impl->ExportCGNS(file, &partDS);
3436 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3437 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3439 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3443 //================================================================================
3445 * \brief Export a part of mesh to a GMF file
3447 //================================================================================
3449 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3451 bool withRequiredGroups)
3452 throw (SALOME::SALOME_Exception)
3454 Unexpect aCatch(SALOME_SalomeException);
3456 _preMeshInfo->FullLoadFromFile();
3458 PrepareForWriting(file,/*overwrite=*/true);
3460 SMESH_MeshPartDS partDS( meshPart );
3461 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3463 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3464 << meshPart<< ", r'"
3466 << withRequiredGroups << ")";
3469 //=============================================================================
3471 * Return computation progress [0.,1]
3473 //=============================================================================
3475 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3479 return _impl->GetComputeProgress();
3481 SMESH_CATCH( SMESH::doNothing );
3485 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3487 Unexpect aCatch(SALOME_SalomeException);
3489 return _preMeshInfo->NbNodes();
3491 return _impl->NbNodes();
3494 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3496 Unexpect aCatch(SALOME_SalomeException);
3498 return _preMeshInfo->NbElements();
3500 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3503 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3505 Unexpect aCatch(SALOME_SalomeException);
3507 return _preMeshInfo->Nb0DElements();
3509 return _impl->Nb0DElements();
3512 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3514 Unexpect aCatch(SALOME_SalomeException);
3516 return _preMeshInfo->NbBalls();
3518 return _impl->NbBalls();
3521 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3523 Unexpect aCatch(SALOME_SalomeException);
3525 return _preMeshInfo->NbEdges();
3527 return _impl->NbEdges();
3530 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3531 throw(SALOME::SALOME_Exception)
3533 Unexpect aCatch(SALOME_SalomeException);
3535 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3537 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3540 //=============================================================================
3542 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3544 Unexpect aCatch(SALOME_SalomeException);
3546 return _preMeshInfo->NbFaces();
3548 return _impl->NbFaces();
3551 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3553 Unexpect aCatch(SALOME_SalomeException);
3555 return _preMeshInfo->NbTriangles();
3557 return _impl->NbTriangles();
3560 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3562 Unexpect aCatch(SALOME_SalomeException);
3564 return _preMeshInfo->NbBiQuadTriangles();
3566 return _impl->NbBiQuadTriangles();
3569 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3571 Unexpect aCatch(SALOME_SalomeException);
3573 return _preMeshInfo->NbQuadrangles();
3575 return _impl->NbQuadrangles();
3578 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3580 Unexpect aCatch(SALOME_SalomeException);
3582 return _preMeshInfo->NbBiQuadQuadrangles();
3584 return _impl->NbBiQuadQuadrangles();
3587 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3589 Unexpect aCatch(SALOME_SalomeException);
3591 return _preMeshInfo->NbPolygons();
3593 return _impl->NbPolygons();
3596 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3597 throw(SALOME::SALOME_Exception)
3599 Unexpect aCatch(SALOME_SalomeException);
3601 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3603 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3606 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3607 throw(SALOME::SALOME_Exception)
3609 Unexpect aCatch(SALOME_SalomeException);
3611 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3613 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3616 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3617 throw(SALOME::SALOME_Exception)
3619 Unexpect aCatch(SALOME_SalomeException);
3621 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3623 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3626 //=============================================================================
3628 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3630 Unexpect aCatch(SALOME_SalomeException);
3632 return _preMeshInfo->NbVolumes();
3634 return _impl->NbVolumes();
3637 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3639 Unexpect aCatch(SALOME_SalomeException);
3641 return _preMeshInfo->NbTetras();
3643 return _impl->NbTetras();
3646 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3648 Unexpect aCatch(SALOME_SalomeException);
3650 return _preMeshInfo->NbHexas();
3652 return _impl->NbHexas();
3655 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3657 Unexpect aCatch(SALOME_SalomeException);
3659 return _preMeshInfo->NbTriQuadHexas();
3661 return _impl->NbTriQuadraticHexas();
3664 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3666 Unexpect aCatch(SALOME_SalomeException);
3668 return _preMeshInfo->NbPyramids();
3670 return _impl->NbPyramids();
3673 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3675 Unexpect aCatch(SALOME_SalomeException);
3677 return _preMeshInfo->NbPrisms();
3679 return _impl->NbPrisms();
3682 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3684 Unexpect aCatch(SALOME_SalomeException);
3686 return _preMeshInfo->NbHexPrisms();
3688 return _impl->NbHexagonalPrisms();
3691 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3693 Unexpect aCatch(SALOME_SalomeException);
3695 return _preMeshInfo->NbPolyhedrons();
3697 return _impl->NbPolyhedrons();
3700 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3701 throw(SALOME::SALOME_Exception)
3703 Unexpect aCatch(SALOME_SalomeException);
3705 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3707 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3710 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3711 throw(SALOME::SALOME_Exception)
3713 Unexpect aCatch(SALOME_SalomeException);
3715 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3717 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3720 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3721 throw(SALOME::SALOME_Exception)
3723 Unexpect aCatch(SALOME_SalomeException);
3725 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3727 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3730 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3731 throw(SALOME::SALOME_Exception)
3733 Unexpect aCatch(SALOME_SalomeException);
3735 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3737 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3740 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3741 throw(SALOME::SALOME_Exception)
3743 Unexpect aCatch(SALOME_SalomeException);
3745 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3747 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3750 //=============================================================================
3752 * Returns nb of published sub-meshes
3754 //=============================================================================
3756 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3758 Unexpect aCatch(SALOME_SalomeException);
3759 return _mapSubMesh_i.size();
3762 //=============================================================================
3764 * Dumps mesh into a string
3766 //=============================================================================
3768 char* SMESH_Mesh_i::Dump()
3772 return CORBA::string_dup( os.str().c_str() );
3775 //=============================================================================
3777 * Method of SMESH_IDSource interface
3779 //=============================================================================
3781 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3783 return GetElementsId();
3786 //=============================================================================
3788 * Returns ids of all elements
3790 //=============================================================================
3792 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3793 throw (SALOME::SALOME_Exception)
3795 Unexpect aCatch(SALOME_SalomeException);
3797 _preMeshInfo->FullLoadFromFile();
3799 SMESH::long_array_var aResult = new SMESH::long_array();
3800 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3802 if ( aSMESHDS_Mesh == NULL )
3803 return aResult._retn();
3805 long nbElements = NbElements();
3806 aResult->length( nbElements );
3807 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3808 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3809 aResult[i] = anIt->next()->GetID();
3811 return aResult._retn();
3815 //=============================================================================
3817 * Returns ids of all elements of given type
3819 //=============================================================================
3821 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3822 throw (SALOME::SALOME_Exception)
3824 Unexpect aCatch(SALOME_SalomeException);
3826 _preMeshInfo->FullLoadFromFile();
3828 SMESH::long_array_var aResult = new SMESH::long_array();
3829 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3831 if ( aSMESHDS_Mesh == NULL )
3832 return aResult._retn();
3834 long nbElements = NbElements();
3836 // No sense in returning ids of elements along with ids of nodes:
3837 // when theElemType == SMESH::ALL, return node ids only if
3838 // there are no elements
3839 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3840 return GetNodesId();
3842 aResult->length( nbElements );
3846 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3847 while ( i < nbElements && anIt->more() )
3848 aResult[i++] = anIt->next()->GetID();
3850 aResult->length( i );
3852 return aResult._retn();
3855 //=============================================================================
3857 * Returns ids of all nodes
3859 //=============================================================================
3861 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3862 throw (SALOME::SALOME_Exception)
3864 Unexpect aCatch(SALOME_SalomeException);
3866 _preMeshInfo->FullLoadFromFile();
3868 SMESH::long_array_var aResult = new SMESH::long_array();
3869 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3871 if ( aSMESHDS_Mesh == NULL )
3872 return aResult._retn();
3874 long nbNodes = NbNodes();
3875 aResult->length( nbNodes );
3876 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3877 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3878 aResult[i] = anIt->next()->GetID();
3880 return aResult._retn();
3883 //=============================================================================
3887 //=============================================================================
3889 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3890 throw (SALOME::SALOME_Exception)
3892 SMESH::ElementType type;
3896 _preMeshInfo->FullLoadFromFile();
3898 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3900 SMESH_CATCH( SMESH::throwCorbaException );
3905 //=============================================================================
3909 //=============================================================================
3911 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3912 throw (SALOME::SALOME_Exception)
3915 _preMeshInfo->FullLoadFromFile();
3917 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3919 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3921 return ( SMESH::EntityType ) e->GetEntityType();
3924 //=============================================================================
3928 //=============================================================================
3930 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3931 throw (SALOME::SALOME_Exception)
3934 _preMeshInfo->FullLoadFromFile();
3936 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3938 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3940 return ( SMESH::GeometryType ) e->GetGeomType();
3943 //=============================================================================
3945 * Returns ID of elements for given submesh
3947 //=============================================================================
3948 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3949 throw (SALOME::SALOME_Exception)
3951 SMESH::long_array_var aResult = new SMESH::long_array();
3955 _preMeshInfo->FullLoadFromFile();
3957 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3958 if(!SM) return aResult._retn();
3960 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3961 if(!SDSM) return aResult._retn();
3963 aResult->length(SDSM->NbElements());
3965 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3967 while ( eIt->more() ) {
3968 aResult[i++] = eIt->next()->GetID();
3971 SMESH_CATCH( SMESH::throwCorbaException );
3973 return aResult._retn();
3976 //=============================================================================
3978 * Returns ID of nodes for given submesh
3979 * If param all==true - returns all nodes, else -
3980 * returns only nodes on shapes.
3982 //=============================================================================
3984 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
3986 throw (SALOME::SALOME_Exception)
3988 SMESH::long_array_var aResult = new SMESH::long_array();
3992 _preMeshInfo->FullLoadFromFile();
3994 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3995 if(!SM) return aResult._retn();
3997 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3998 if(!SDSM) return aResult._retn();
4001 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4002 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4003 while ( nIt->more() ) {
4004 const SMDS_MeshNode* elem = nIt->next();
4005 theElems.insert( elem->GetID() );
4008 else { // all nodes of submesh elements
4009 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4010 while ( eIt->more() ) {
4011 const SMDS_MeshElement* anElem = eIt->next();
4012 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4013 while ( nIt->more() ) {
4014 const SMDS_MeshElement* elem = nIt->next();
4015 theElems.insert( elem->GetID() );
4020 aResult->length(theElems.size());
4021 set<int>::iterator itElem;
4023 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4024 aResult[i++] = *itElem;
4026 SMESH_CATCH( SMESH::throwCorbaException );
4028 return aResult._retn();
4031 //=============================================================================
4033 * Returns type of elements for given submesh
4035 //=============================================================================
4037 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4038 throw (SALOME::SALOME_Exception)
4040 SMESH::ElementType type;
4044 _preMeshInfo->FullLoadFromFile();
4046 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4047 if(!SM) return SMESH::ALL;
4049 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4050 if(!SDSM) return SMESH::ALL;
4052 if(SDSM->NbElements()==0)
4053 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4055 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4056 const SMDS_MeshElement* anElem = eIt->next();
4058 type = ( SMESH::ElementType ) anElem->GetType();
4060 SMESH_CATCH( SMESH::throwCorbaException );
4066 //=============================================================================
4068 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4070 //=============================================================================
4072 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4075 _preMeshInfo->FullLoadFromFile();
4077 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4079 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4084 //=============================================================================
4086 * Get XYZ coordinates of node as list of double
4087 * If there is not node for given ID - returns empty list
4089 //=============================================================================
4091 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4094 _preMeshInfo->FullLoadFromFile();
4096 SMESH::double_array_var aResult = new SMESH::double_array();
4097 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4098 if ( aSMESHDS_Mesh == NULL )
4099 return aResult._retn();
4102 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4104 return aResult._retn();
4108 aResult[0] = aNode->X();
4109 aResult[1] = aNode->Y();
4110 aResult[2] = aNode->Z();
4111 return aResult._retn();
4115 //=============================================================================
4117 * For given node returns list of IDs of inverse elements
4118 * If there is not node for given ID - returns empty list
4120 //=============================================================================
4122 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4125 _preMeshInfo->FullLoadFromFile();
4127 SMESH::long_array_var aResult = new SMESH::long_array();
4128 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4129 if ( aSMESHDS_Mesh == NULL )
4130 return aResult._retn();
4133 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4135 return aResult._retn();
4137 // find inverse elements
4138 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4139 TColStd_SequenceOfInteger IDs;
4140 while(eIt->more()) {
4141 const SMDS_MeshElement* elem = eIt->next();
4142 IDs.Append(elem->GetID());
4144 if(IDs.Length()>0) {
4145 aResult->length(IDs.Length());
4147 for(; i<=IDs.Length(); i++) {
4148 aResult[i-1] = IDs.Value(i);
4151 return aResult._retn();
4154 //=============================================================================
4156 * \brief Return position of a node on shape
4158 //=============================================================================
4160 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4163 _preMeshInfo->FullLoadFromFile();
4165 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4166 aNodePosition->shapeID = 0;
4167 aNodePosition->shapeType = GEOM::SHAPE;
4169 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4170 if ( !mesh ) return aNodePosition;
4172 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4174 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4176 aNodePosition->shapeID = aNode->getshapeId();
4177 switch ( pos->GetTypeOfPosition() ) {
4179 aNodePosition->shapeType = GEOM::EDGE;
4180 aNodePosition->params.length(1);
4181 aNodePosition->params[0] =
4182 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4185 aNodePosition->shapeType = GEOM::FACE;
4186 aNodePosition->params.length(2);
4187 aNodePosition->params[0] =
4188 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4189 aNodePosition->params[1] =
4190 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4192 case SMDS_TOP_VERTEX:
4193 aNodePosition->shapeType = GEOM::VERTEX;
4195 case SMDS_TOP_3DSPACE:
4196 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4197 aNodePosition->shapeType = GEOM::SOLID;
4198 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4199 aNodePosition->shapeType = GEOM::SHELL;
4205 return aNodePosition;
4208 //=============================================================================
4210 * \brief Return position of an element on shape
4212 //=============================================================================
4214 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4217 _preMeshInfo->FullLoadFromFile();
4219 SMESH::ElementPosition anElementPosition;
4220 anElementPosition.shapeID = 0;
4221 anElementPosition.shapeType = GEOM::SHAPE;
4223 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4224 if ( !mesh ) return anElementPosition;
4226 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4228 anElementPosition.shapeID = anElem->getshapeId();
4229 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4230 if ( !aSp.IsNull() ) {
4231 switch ( aSp.ShapeType() ) {
4233 anElementPosition.shapeType = GEOM::EDGE;
4236 anElementPosition.shapeType = GEOM::FACE;
4239 anElementPosition.shapeType = GEOM::VERTEX;
4242 anElementPosition.shapeType = GEOM::SOLID;
4245 anElementPosition.shapeType = GEOM::SHELL;
4251 return anElementPosition;
4254 //=============================================================================
4256 * If given element is node returns IDs of shape from position
4257 * If there is not node for given ID - returns -1
4259 //=============================================================================
4261 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4264 _preMeshInfo->FullLoadFromFile();
4266 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4267 if ( aSMESHDS_Mesh == NULL )
4271 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4273 return aNode->getshapeId();
4280 //=============================================================================
4282 * For given element returns ID of result shape after
4283 * ::FindShape() from SMESH_MeshEditor
4284 * If there is not element for given ID - returns -1
4286 //=============================================================================
4288 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4291 _preMeshInfo->FullLoadFromFile();
4293 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4294 if ( aSMESHDS_Mesh == NULL )
4297 // try to find element
4298 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4302 ::SMESH_MeshEditor aMeshEditor(_impl);
4303 int index = aMeshEditor.FindShape( elem );
4311 //=============================================================================
4313 * Returns number of nodes for given element
4314 * If there is not element for given ID - returns -1
4316 //=============================================================================
4318 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4321 _preMeshInfo->FullLoadFromFile();
4323 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4324 if ( aSMESHDS_Mesh == NULL ) return -1;
4325 // try to find element
4326 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4327 if(!elem) return -1;
4328 return elem->NbNodes();
4332 //=============================================================================
4334 * Returns ID of node by given index for given element
4335 * If there is not element for given ID - returns -1
4336 * If there is not node for given index - returns -2
4338 //=============================================================================
4340 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4343 _preMeshInfo->FullLoadFromFile();
4345 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4346 if ( aSMESHDS_Mesh == NULL ) return -1;
4347 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4348 if(!elem) return -1;
4349 if( index>=elem->NbNodes() || index<0 ) return -1;
4350 return elem->GetNode(index)->GetID();
4353 //=============================================================================
4355 * Returns IDs of nodes of given element
4357 //=============================================================================
4359 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4362 _preMeshInfo->FullLoadFromFile();
4364 SMESH::long_array_var aResult = new SMESH::long_array();
4365 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4367 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4369 aResult->length( elem->NbNodes() );
4370 for ( int i = 0; i < elem->NbNodes(); ++i )
4371 aResult[ i ] = elem->GetNode( i )->GetID();
4374 return aResult._retn();
4377 //=============================================================================
4379 * Returns true if given node is medium node
4380 * in given quadratic element
4382 //=============================================================================
4384 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4387 _preMeshInfo->FullLoadFromFile();
4389 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4390 if ( aSMESHDS_Mesh == NULL ) return false;
4392 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4393 if(!aNode) return false;
4394 // try to find element
4395 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4396 if(!elem) return false;
4398 return elem->IsMediumNode(aNode);
4402 //=============================================================================
4404 * Returns true if given node is medium node
4405 * in one of quadratic elements
4407 //=============================================================================
4409 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4410 SMESH::ElementType theElemType)
4413 _preMeshInfo->FullLoadFromFile();
4415 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4416 if ( aSMESHDS_Mesh == NULL ) return false;
4419 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4420 if(!aNode) return false;
4422 SMESH_MesherHelper aHelper( *(_impl) );
4424 SMDSAbs_ElementType aType;
4425 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4426 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4427 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4428 else aType = SMDSAbs_All;
4430 return aHelper.IsMedium(aNode,aType);
4434 //=============================================================================
4436 * Returns number of edges for given element
4438 //=============================================================================
4440 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4443 _preMeshInfo->FullLoadFromFile();
4445 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4446 if ( aSMESHDS_Mesh == NULL ) return -1;
4447 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4448 if(!elem) return -1;
4449 return elem->NbEdges();
4453 //=============================================================================
4455 * Returns number of faces for given element
4457 //=============================================================================
4459 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4462 _preMeshInfo->FullLoadFromFile();
4464 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4465 if ( aSMESHDS_Mesh == NULL ) return -1;
4466 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4467 if(!elem) return -1;
4468 return elem->NbFaces();
4471 //=======================================================================
4472 //function : GetElemFaceNodes
4473 //purpose : Returns nodes of given face (counted from zero) for given element.
4474 //=======================================================================
4476 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4477 CORBA::Short faceIndex)
4480 _preMeshInfo->FullLoadFromFile();
4482 SMESH::long_array_var aResult = new SMESH::long_array();
4483 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4485 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4487 SMDS_VolumeTool vtool( elem );
4488 if ( faceIndex < vtool.NbFaces() )
4490 aResult->length( vtool.NbFaceNodes( faceIndex ));
4491 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4492 for ( int i = 0; i < aResult->length(); ++i )
4493 aResult[ i ] = nn[ i ]->GetID();
4497 return aResult._retn();
4500 //=======================================================================
4501 //function : GetElemFaceNodes
4502 //purpose : Returns three components of normal of given mesh face.
4503 //=======================================================================
4505 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4506 CORBA::Boolean normalized)
4509 _preMeshInfo->FullLoadFromFile();
4511 SMESH::double_array_var aResult = new SMESH::double_array();
4513 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4516 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4518 aResult->length( 3 );
4519 aResult[ 0 ] = normal.X();
4520 aResult[ 1 ] = normal.Y();
4521 aResult[ 2 ] = normal.Z();
4524 return aResult._retn();
4527 //=======================================================================
4528 //function : FindElementByNodes
4529 //purpose : Returns an element based on all given nodes.
4530 //=======================================================================
4532 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4535 _preMeshInfo->FullLoadFromFile();
4537 CORBA::Long elemID(0);
4538 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4540 vector< const SMDS_MeshNode * > nn( nodes.length() );
4541 for ( int i = 0; i < nodes.length(); ++i )
4542 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4545 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4546 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4547 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4548 _impl->NbVolumes( ORDER_QUADRATIC )))
4549 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4551 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4556 //=============================================================================
4558 * Returns true if given element is polygon
4560 //=============================================================================
4562 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4565 _preMeshInfo->FullLoadFromFile();
4567 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4568 if ( aSMESHDS_Mesh == NULL ) return false;
4569 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4570 if(!elem) return false;
4571 return elem->IsPoly();
4575 //=============================================================================
4577 * Returns true if given element is quadratic
4579 //=============================================================================
4581 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4584 _preMeshInfo->FullLoadFromFile();
4586 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4587 if ( aSMESHDS_Mesh == NULL ) return false;
4588 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4589 if(!elem) return false;
4590 return elem->IsQuadratic();
4593 //=============================================================================
4595 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4597 //=============================================================================
4599 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4602 _preMeshInfo->FullLoadFromFile();
4604 if ( const SMDS_BallElement* ball =
4605 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4606 return ball->GetDiameter();
4611 //=============================================================================
4613 * Returns bary center for given element
4615 //=============================================================================
4617 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4620 _preMeshInfo->FullLoadFromFile();
4622 SMESH::double_array_var aResult = new SMESH::double_array();
4623 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4624 if ( aSMESHDS_Mesh == NULL )
4625 return aResult._retn();
4627 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4629 return aResult._retn();
4631 if(elem->GetType()==SMDSAbs_Volume) {
4632 SMDS_VolumeTool aTool;
4633 if(aTool.Set(elem)) {
4635 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4640 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4642 double x=0., y=0., z=0.;
4643 for(; anIt->more(); ) {
4645 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4659 return aResult._retn();
4662 //================================================================================
4664 * \brief Create a group of elements preventing computation of a sub-shape
4666 //================================================================================
4668 SMESH::ListOfGroups*
4669 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4670 const char* theGroupName )
4671 throw ( SALOME::SALOME_Exception )
4673 Unexpect aCatch(SALOME_SalomeException);
4675 if ( !theGroupName || strlen( theGroupName) == 0 )
4676 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4678 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4680 // submesh by subshape id
4681 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4682 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4685 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4686 if ( error && !error->myBadElements.empty())
4688 // sort bad elements by type
4689 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4690 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4691 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4692 for ( ; elemIt != elemEnd; ++elemIt )
4694 const SMDS_MeshElement* elem = *elemIt;
4695 if ( !elem ) continue;
4697 if ( elem->GetID() < 1 )
4699 // elem is a temporary element, make a real element
4700 vector< const SMDS_MeshNode* > nodes;
4701 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4702 while ( nIt->more() && elem )
4704 nodes.push_back( nIt->next() );
4705 if ( nodes.back()->GetID() < 1 )
4706 elem = 0; // a temporary element on temporary nodes
4710 ::SMESH_MeshEditor editor( _impl );
4711 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4715 elemsByType[ elem->GetType() ].push_back( elem );
4718 // how many groups to create?
4720 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4721 nbTypes += int( !elemsByType[ i ].empty() );
4722 groups->length( nbTypes );
4725 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4727 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4728 if ( elems.empty() ) continue;
4730 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4731 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4733 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4734 SMESH::SMESH_Mesh_var mesh = _this();
4735 SALOMEDS::SObject_wrap aSO =
4736 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4737 GEOM::GEOM_Object::_nil(), theGroupName);
4738 aSO->_is_nil(); // avoid "unused variable" warning
4740 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4741 if ( !grp_i ) continue;
4743 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4744 for ( size_t iE = 0; iE < elems.size(); ++iE )
4745 grpDS->SMDSGroup().Add( elems[ iE ]);
4750 return groups._retn();
4753 //=============================================================================
4755 * Create and publish group servants if any groups were imported or created anyhow
4757 //=============================================================================
4759 void SMESH_Mesh_i::CreateGroupServants()
4761 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4762 SMESH::SMESH_Mesh_var aMesh = _this();
4765 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4766 while ( groupIt->more() )
4768 ::SMESH_Group* group = groupIt->next();
4769 int anId = group->GetGroupDS()->GetID();
4771 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4772 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4774 addedIDs.insert( anId );
4776 SMESH_GroupBase_i* aGroupImpl;
4778 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4779 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4781 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4782 shape = groupOnGeom->GetShape();
4785 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4788 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4789 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4790 aGroupImpl->Register();
4792 // register CORBA object for persistence
4793 int nextId = _gen_i->RegisterObject( groupVar );
4794 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4795 else { nextId = 0; } // avoid "unused variable" warning in release mode
4797 // publishing the groups in the study
4798 if ( !aStudy->_is_nil() ) {
4799 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4800 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4803 if ( !addedIDs.empty() )
4806 set<int>::iterator id = addedIDs.begin();
4807 for ( ; id != addedIDs.end(); ++id )
4809 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4810 int i = std::distance( _mapGroups.begin(), it );
4811 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4816 //=============================================================================
4818 * \brief Return groups cantained in _mapGroups by their IDs
4820 //=============================================================================
4822 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4824 int nbGroups = groupIDs.size();
4825 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4826 aList->length( nbGroups );
4828 list<int>::const_iterator ids = groupIDs.begin();
4829 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4831 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4832 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4833 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4835 aList->length( nbGroups );
4836 return aList._retn();
4839 //=============================================================================
4841 * \brief Return information about imported file
4843 //=============================================================================
4845 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4847 SMESH::MedFileInfo_var res( _medFileInfo );
4848 if ( !res.operator->() ) {
4849 res = new SMESH::MedFileInfo;
4851 res->fileSize = res->major = res->minor = res->release = -1;
4856 //=============================================================================
4858 * \brief Pass names of mesh groups from study to mesh DS
4860 //=============================================================================
4862 void SMESH_Mesh_i::checkGroupNames()
4864 int nbGrp = NbGroups();
4868 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4869 if ( aStudy->_is_nil() )
4870 return; // nothing to do
4872 SMESH::ListOfGroups* grpList = 0;
4873 // avoid dump of "GetGroups"
4875 // store python dump into a local variable inside local scope
4876 SMESH::TPythonDump pDump; // do not delete this line of code
4877 grpList = GetGroups();
4880 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4881 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4884 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4885 if ( aGrpSO->_is_nil() )
4887 // correct name of the mesh group if necessary
4888 const char* guiName = aGrpSO->GetName();
4889 if ( strcmp(guiName, aGrp->GetName()) )
4890 aGrp->SetName( guiName );
4894 //=============================================================================
4896 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4898 //=============================================================================
4899 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4901 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4905 //=============================================================================
4907 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4909 //=============================================================================
4911 char* SMESH_Mesh_i::GetParameters()
4913 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4916 //=============================================================================
4918 * \brief Returns list of notebook variables used for last Mesh operation
4920 //=============================================================================
4921 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4923 SMESH::string_array_var aResult = new SMESH::string_array();
4924 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4926 CORBA::String_var aParameters = GetParameters();
4927 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4928 if ( !aStudy->_is_nil()) {
4929 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4930 if(aSections->length() > 0) {
4931 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4932 aResult->length(aVars.length());
4933 for(int i = 0;i < aVars.length();i++)
4934 aResult[i] = CORBA::string_dup( aVars[i]);
4938 return aResult._retn();
4941 //=======================================================================
4942 //function : GetTypes
4943 //purpose : Returns types of elements it contains
4944 //=======================================================================
4946 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4949 return _preMeshInfo->GetTypes();
4951 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4955 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4956 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4957 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4958 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4959 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4960 types->length( nbTypes );
4962 return types._retn();
4965 //=======================================================================
4966 //function : GetMesh
4967 //purpose : Returns self
4968 //=======================================================================
4970 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4972 return SMESH::SMESH_Mesh::_duplicate( _this() );
4975 //=======================================================================
4976 //function : IsMeshInfoCorrect
4977 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4978 // * happen if mesh data is not yet fully loaded from the file of study.
4979 //=======================================================================
4981 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4983 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4986 //=============================================================================
4988 * \brief Returns number of mesh elements per each \a EntityType
4990 //=============================================================================
4992 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
4995 return _preMeshInfo->GetMeshInfo();
4997 SMESH::long_array_var aRes = new SMESH::long_array();
4998 aRes->length(SMESH::Entity_Last);
4999 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5001 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5003 return aRes._retn();
5004 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5005 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5006 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5007 return aRes._retn();
5010 //=============================================================================
5012 * \brief Returns number of mesh elements per each \a ElementType
5014 //=============================================================================
5016 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5018 SMESH::long_array_var aRes = new SMESH::long_array();
5019 aRes->length(SMESH::NB_ELEMENT_TYPES);
5020 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5023 const SMDS_MeshInfo* meshInfo = 0;
5025 meshInfo = _preMeshInfo;
5026 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5027 meshInfo = & meshDS->GetMeshInfo();
5030 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5031 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5033 return aRes._retn();
5036 //=============================================================================
5038 * Collect statistic of mesh elements given by iterator
5040 //=============================================================================
5042 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5043 SMESH::long_array& theInfo)
5045 if (!theItr) return;
5046 while (theItr->more())
5047 theInfo[ theItr->next()->GetEntityType() ]++;
5050 //=============================================================================
5051 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5052 * SMESH::ElementType type) */
5054 using namespace SMESH::Controls;
5055 //-----------------------------------------------------------------------------
5056 struct PredicateIterator : public SMDS_ElemIterator
5058 SMDS_ElemIteratorPtr _elemIter;
5059 PredicatePtr _predicate;
5060 const SMDS_MeshElement* _elem;
5062 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5063 PredicatePtr predicate):
5064 _elemIter(iterator), _predicate(predicate)
5072 virtual const SMDS_MeshElement* next()
5074 const SMDS_MeshElement* res = _elem;
5076 while ( _elemIter->more() && !_elem )
5078 _elem = _elemIter->next();
5079 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5086 //-----------------------------------------------------------------------------
5087 struct IDSourceIterator : public SMDS_ElemIterator
5089 const CORBA::Long* _idPtr;
5090 const CORBA::Long* _idEndPtr;
5091 SMESH::long_array_var _idArray;
5092 const SMDS_Mesh* _mesh;
5093 const SMDSAbs_ElementType _type;
5094 const SMDS_MeshElement* _elem;
5096 IDSourceIterator( const SMDS_Mesh* mesh,
5097 const CORBA::Long* ids,
5099 SMDSAbs_ElementType type):
5100 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5102 if ( _idPtr && nbIds && _mesh )
5105 IDSourceIterator( const SMDS_Mesh* mesh,
5106 SMESH::long_array* idArray,
5107 SMDSAbs_ElementType type):
5108 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5110 if ( idArray && _mesh )
5112 _idPtr = &_idArray[0];
5113 _idEndPtr = _idPtr + _idArray->length();
5121 virtual const SMDS_MeshElement* next()
5123 const SMDS_MeshElement* res = _elem;
5125 while ( _idPtr < _idEndPtr && !_elem )
5127 if ( _type == SMDSAbs_Node )
5129 _elem = _mesh->FindNode( *_idPtr++ );
5131 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5132 _elem->GetType() != _type )
5140 //-----------------------------------------------------------------------------
5142 struct NodeOfElemIterator : public SMDS_ElemIterator
5144 TColStd_MapOfInteger _checkedNodeIDs;
5145 SMDS_ElemIteratorPtr _elemIter;
5146 SMDS_ElemIteratorPtr _nodeIter;
5147 const SMDS_MeshElement* _node;
5149 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5151 if ( _elemIter && _elemIter->more() )
5153 _nodeIter = _elemIter->next()->nodesIterator();
5161 virtual const SMDS_MeshElement* next()
5163 const SMDS_MeshElement* res = _node;
5165 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5167 if ( _nodeIter->more() )
5169 _node = _nodeIter->next();
5170 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5175 _nodeIter = _elemIter->next()->nodesIterator();
5183 //=============================================================================
5185 * Return iterator on elements of given type in given object
5187 //=============================================================================
5189 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5190 SMESH::ElementType theType)
5192 SMDS_ElemIteratorPtr elemIt;
5193 bool typeOK = false;
5194 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5196 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5197 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5198 if ( !mesh_i ) return elemIt;
5199 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5201 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5203 elemIt = meshDS->elementsIterator( elemType );
5206 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5208 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5211 elemIt = sm->GetElements();
5212 if ( elemType != SMDSAbs_Node )
5214 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5215 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5219 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5221 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5222 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5224 elemIt = groupDS->GetElements();
5225 typeOK = ( groupDS->GetType() == elemType );
5228 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5230 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5232 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5233 if ( pred_i && pred_i->GetPredicate() )
5235 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5236 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5237 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5238 typeOK = ( filterType == elemType );
5244 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5245 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5246 if ( isNodes && elemType != SMDSAbs_Node )
5248 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5251 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5252 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5256 SMESH::long_array_var ids = theObject->GetIDs();
5257 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5259 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5262 if ( elemIt && elemIt->more() && !typeOK )
5264 if ( elemType == SMDSAbs_Node )
5266 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5270 elemIt = SMDS_ElemIteratorPtr();
5276 //=============================================================================
5277 namespace // Finding concurrent hypotheses
5278 //=============================================================================
5282 * \brief mapping of mesh dimension into shape type
5284 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5286 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5288 case 0: aType = TopAbs_VERTEX; break;
5289 case 1: aType = TopAbs_EDGE; break;
5290 case 2: aType = TopAbs_FACE; break;
5292 default:aType = TopAbs_SOLID; break;
5297 //-----------------------------------------------------------------------------
5299 * \brief Internal structure used to find concurent submeshes
5301 * It represents a pair < submesh, concurent dimension >, where
5302 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5303 * with another submesh. In other words, it is dimension of a hypothesis assigned
5310 int _dim; //!< a dimension the algo can build (concurrent dimension)
5311 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5312 TopTools_MapOfShape _shapeMap;
5313 SMESH_subMesh* _subMesh;
5314 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5316 //-----------------------------------------------------------------------------
5317 // Return the algorithm
5318 const SMESH_Algo* GetAlgo() const
5319 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5321 //-----------------------------------------------------------------------------
5323 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5325 const TopoDS_Shape& theShape)
5327 _subMesh = (SMESH_subMesh*)theSubMesh;
5328 SetShape( theDim, theShape );
5331 //-----------------------------------------------------------------------------
5333 void SetShape(const int theDim,
5334 const TopoDS_Shape& theShape)
5337 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5338 if (_dim >= _ownDim)
5339 _shapeMap.Add( theShape );
5341 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5342 for( ; anExp.More(); anExp.Next() )
5343 _shapeMap.Add( anExp.Current() );
5347 //-----------------------------------------------------------------------------
5348 //! Check sharing of sub-shapes
5349 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5350 const TopTools_MapOfShape& theToFind,
5351 const TopAbs_ShapeEnum theType)
5353 bool isShared = false;
5354 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5355 for (; !isShared && anItr.More(); anItr.Next() )
5357 const TopoDS_Shape aSubSh = anItr.Key();
5358 // check for case when concurrent dimensions are same
5359 isShared = theToFind.Contains( aSubSh );
5360 // check for sub-shape with concurrent dimension
5361 TopExp_Explorer anExp( aSubSh, theType );
5362 for ( ; !isShared && anExp.More(); anExp.Next() )
5363 isShared = theToFind.Contains( anExp.Current() );
5368 //-----------------------------------------------------------------------------
5369 //! check algorithms
5370 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5371 const SMESHDS_Hypothesis* theA2)
5373 if ( !theA1 || !theA2 ||
5374 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5375 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5376 return false; // one of the hypothesis is not algorithm
5377 // check algorithm names (should be equal)
5378 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5382 //-----------------------------------------------------------------------------
5383 //! Check if sub-shape hypotheses are concurrent
5384 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5386 if ( _subMesh == theOther->_subMesh )
5387 return false; // same sub-shape - should not be
5389 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5390 // any of the two submeshes is not on COMPOUND shape )
5391 // -> no concurrency
5392 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5393 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5394 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5395 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5396 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5399 // bool checkSubShape = ( _dim >= theOther->_dim )
5400 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5401 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5402 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5403 if ( !checkSubShape )
5406 // check algorithms to be same
5407 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5408 return true; // different algorithms -> concurrency !
5410 // check hypothesises for concurrence (skip first as algorithm)
5412 // pointers should be same, because it is referened from mesh hypothesis partition
5413 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5414 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5415 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5416 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5418 // the submeshes are concurrent if their algorithms has different parameters
5419 return nbSame != theOther->_hypotheses.size() - 1;
5422 // Return true if algorithm of this SMESH_DimHyp is used if no
5423 // sub-mesh order is imposed by the user
5424 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5426 // NeedDiscreteBoundary() algo has a higher priority
5427 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5428 theOther->GetAlgo()->NeedDiscreteBoundary() )
5429 return !this->GetAlgo()->NeedDiscreteBoundary();
5431 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5434 }; // end of SMESH_DimHyp
5435 //-----------------------------------------------------------------------------
5437 typedef list<const SMESH_DimHyp*> TDimHypList;
5439 //-----------------------------------------------------------------------------
5441 void addDimHypInstance(const int theDim,
5442 const TopoDS_Shape& theShape,
5443 const SMESH_Algo* theAlgo,
5444 const SMESH_subMesh* theSubMesh,
5445 const list <const SMESHDS_Hypothesis*>& theHypList,
5446 TDimHypList* theDimHypListArr )
5448 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5449 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5450 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5451 dimHyp->_hypotheses.push_front(theAlgo);
5452 listOfdimHyp.push_back( dimHyp );
5455 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5456 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5457 theHypList.begin(), theHypList.end() );
5460 //-----------------------------------------------------------------------------
5461 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5462 TDimHypList& theListOfConcurr)
5464 if ( theListOfConcurr.empty() )
5466 theListOfConcurr.push_back( theDimHyp );
5470 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5471 while ( hypIt != theListOfConcurr.end() &&
5472 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5474 theListOfConcurr.insert( hypIt, theDimHyp );
5478 //-----------------------------------------------------------------------------
5479 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5480 const TDimHypList& theListOfDimHyp,
5481 TDimHypList& theListOfConcurrHyp,
5482 set<int>& theSetOfConcurrId )
5484 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5485 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5487 const SMESH_DimHyp* curDimHyp = *rIt;
5488 if ( curDimHyp == theDimHyp )
5489 break; // meet own dimHyp pointer in same dimension
5491 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5492 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5494 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5499 //-----------------------------------------------------------------------------
5500 void unionLists(TListOfInt& theListOfId,
5501 TListOfListOfInt& theListOfListOfId,
5504 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5505 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5507 continue; //skip already treated lists
5508 // check if other list has any same submesh object
5509 TListOfInt& otherListOfId = *it;
5510 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5511 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5514 // union two lists (from source into target)
5515 TListOfInt::iterator it2 = otherListOfId.begin();
5516 for ( ; it2 != otherListOfId.end(); it2++ ) {
5517 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5518 theListOfId.push_back(*it2);
5520 // clear source list
5521 otherListOfId.clear();
5524 //-----------------------------------------------------------------------------
5526 //! free memory allocated for dimension-hypothesis objects
5527 void removeDimHyps( TDimHypList* theArrOfList )
5529 for (int i = 0; i < 4; i++ ) {
5530 TDimHypList& listOfdimHyp = theArrOfList[i];
5531 TDimHypList::const_iterator it = listOfdimHyp.begin();
5532 for ( ; it != listOfdimHyp.end(); it++ )
5537 //-----------------------------------------------------------------------------
5539 * \brief find common submeshes with given submesh
5540 * \param theSubMeshList list of already collected submesh to check
5541 * \param theSubMesh given submesh to intersect with other
5542 * \param theCommonSubMeshes collected common submeshes
5544 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5545 const SMESH_subMesh* theSubMesh,
5546 set<const SMESH_subMesh*>& theCommon )
5550 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5551 for ( ; it != theSubMeshList.end(); it++ )
5552 theSubMesh->FindIntersection( *it, theCommon );
5553 theSubMeshList.push_back( theSubMesh );
5554 //theCommon.insert( theSubMesh );
5557 //-----------------------------------------------------------------------------
5558 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5560 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5561 for ( ; listsIt != smLists.end(); ++listsIt )
5563 const TListOfInt& smIDs = *listsIt;
5564 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5572 //=============================================================================
5574 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5576 //=============================================================================
5578 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5580 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5581 if ( isSubMeshInList( submeshID, anOrder ))
5584 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5585 return isSubMeshInList( submeshID, allConurrent );
5588 //=============================================================================
5590 * \brief Return submesh objects list in meshing order
5592 //=============================================================================
5594 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5596 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5598 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5600 return aResult._retn();
5602 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5603 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5604 anOrder.splice( anOrder.end(), allConurrent );
5607 TListOfListOfInt::iterator listIt = anOrder.begin();
5608 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5609 unionLists( *listIt, anOrder, listIndx + 1 );
5611 // convert submesh ids into interface instances
5612 // and dump command into python
5613 convertMeshOrder( anOrder, aResult, false );
5615 return aResult._retn();
5618 //=============================================================================
5620 * \brief Finds concurrent sub-meshes
5622 //=============================================================================
5624 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5626 TListOfListOfInt anOrder;
5627 ::SMESH_Mesh& mesh = GetImpl();
5629 // collect submeshes and detect concurrent algorithms and hypothesises
5630 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5632 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5633 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5634 ::SMESH_subMesh* sm = (*i_sm).second;
5636 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5638 // list of assigned hypothesises
5639 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5640 // Find out dimensions where the submesh can be concurrent.
5641 // We define the dimensions by algo of each of hypotheses in hypList
5642 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5643 for( ; hypIt != hypList.end(); hypIt++ ) {
5644 SMESH_Algo* anAlgo = 0;
5645 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5646 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5647 // hyp it-self is algo
5648 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5650 // try to find algorithm with help of sub-shapes
5651 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5652 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5653 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5656 continue; // no algorithm assigned to a current submesh
5658 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5659 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5661 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5662 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5663 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5665 } // end iterations on submesh
5667 // iterate on created dimension-hypotheses and check for concurrents
5668 for ( int i = 0; i < 4; i++ ) {
5669 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5670 // check for concurrents in own and other dimensions (step-by-step)
5671 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5672 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5673 const SMESH_DimHyp* dimHyp = *dhIt;
5674 TDimHypList listOfConcurr;
5675 set<int> setOfConcurrIds;
5676 // looking for concurrents and collect into own list
5677 for ( int j = i; j < 4; j++ )
5678 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5679 // check if any concurrents found
5680 if ( listOfConcurr.size() > 0 ) {
5681 // add own submesh to list of concurrent
5682 addInOrderOfPriority( dimHyp, listOfConcurr );
5683 list<int> listOfConcurrIds;
5684 TDimHypList::iterator hypIt = listOfConcurr.begin();
5685 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5686 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5687 anOrder.push_back( listOfConcurrIds );
5692 removeDimHyps(dimHypListArr);
5694 // now, minimise the number of concurrent groups
5695 // Here we assume that lists of submeshes can have same submesh
5696 // in case of multi-dimension algorithms, as result
5697 // list with common submesh has to be united into one list
5699 TListOfListOfInt::iterator listIt = anOrder.begin();
5700 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5701 unionLists( *listIt, anOrder, listIndx + 1 );
5707 //=============================================================================
5709 * \brief Set submesh object order
5710 * \param theSubMeshArray submesh array order
5712 //=============================================================================
5714 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5717 _preMeshInfo->ForgetOrLoad();
5720 ::SMESH_Mesh& mesh = GetImpl();
5722 TPythonDump aPythonDump; // prevent dump of called methods
5723 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5725 TListOfListOfInt subMeshOrder;
5726 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5728 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5729 TListOfInt subMeshIds;
5730 aPythonDump << "[ ";
5731 // Collect subMeshes which should be clear
5732 // do it list-by-list, because modification of submesh order
5733 // take effect between concurrent submeshes only
5734 set<const SMESH_subMesh*> subMeshToClear;
5735 list<const SMESH_subMesh*> subMeshList;
5736 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5738 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5740 aPythonDump << ", ";
5741 aPythonDump << subMesh;
5742 subMeshIds.push_back( subMesh->GetId() );
5743 // detect common parts of submeshes
5744 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5745 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5747 aPythonDump << " ]";
5748 subMeshOrder.push_back( subMeshIds );
5750 // clear collected submeshes
5751 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5752 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5753 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5754 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5756 aPythonDump << " ])";
5758 mesh.SetMeshOrder( subMeshOrder );
5764 //=============================================================================
5766 * \brief Convert submesh ids into submesh interfaces
5768 //=============================================================================
5770 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5771 SMESH::submesh_array_array& theResOrder,
5772 const bool theIsDump)
5774 int nbSet = theIdsOrder.size();
5775 TPythonDump aPythonDump; // prevent dump of called methods
5777 aPythonDump << "[ ";
5778 theResOrder.length(nbSet);
5779 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5781 for( ; it != theIdsOrder.end(); it++ ) {
5782 // translate submesh identificators into submesh objects
5783 // takeing into account real number of concurrent lists
5784 const TListOfInt& aSubOrder = (*it);
5785 if (!aSubOrder.size())
5788 aPythonDump << "[ ";
5789 // convert shape indeces into interfaces
5790 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5791 aResSubSet->length(aSubOrder.size());
5792 TListOfInt::const_iterator subIt = aSubOrder.begin();
5794 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5795 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5797 SMESH::SMESH_subMesh_var subMesh =
5798 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5801 aPythonDump << ", ";
5802 aPythonDump << subMesh;
5804 aResSubSet[ j++ ] = subMesh;
5807 aPythonDump << " ]";
5809 theResOrder[ listIndx++ ] = aResSubSet;
5811 // correct number of lists
5812 theResOrder.length( listIndx );
5815 // finilise python dump
5816 aPythonDump << " ]";
5817 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5821 //================================================================================
5823 // Implementation of SMESH_MeshPartDS
5825 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5826 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5828 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5829 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5831 _meshDS = mesh_i->GetImpl().GetMeshDS();
5833 SetPersistentId( _meshDS->GetPersistentId() );
5835 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5837 // <meshPart> is the whole mesh
5838 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5840 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5841 myGroupSet = _meshDS->GetGroups();
5846 SMESH::long_array_var anIDs = meshPart->GetIDs();
5847 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5848 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5850 for (int i=0; i < anIDs->length(); i++)
5851 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5852 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5857 for (int i=0; i < anIDs->length(); i++)
5858 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5859 if ( _elements[ e->GetType() ].insert( e ).second )
5862 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5863 while ( nIt->more() )
5865 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5866 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5873 _meshDS = 0; // to enforce iteration on _elements and _nodes
5876 // -------------------------------------------------------------------------------------
5877 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5878 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5881 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5882 for ( ; partIt != meshPart.end(); ++partIt )
5883 if ( const SMDS_MeshElement * e = *partIt )
5884 if ( _elements[ e->GetType() ].insert( e ).second )
5887 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5888 while ( nIt->more() )
5890 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5891 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5897 // -------------------------------------------------------------------------------------
5898 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5900 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5902 typedef SMDS_SetIterator
5903 <const SMDS_MeshElement*,
5904 TIDSortedElemSet::const_iterator,
5905 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5906 SMDS_MeshElement::GeomFilter
5909 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5911 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5912 _elements[type].end(),
5913 SMDS_MeshElement::GeomFilter( geomType )));
5915 // -------------------------------------------------------------------------------------
5916 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5918 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5920 typedef SMDS_SetIterator
5921 <const SMDS_MeshElement*,
5922 TIDSortedElemSet::const_iterator,
5923 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5924 SMDS_MeshElement::EntityFilter
5927 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5929 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5930 _elements[type].end(),
5931 SMDS_MeshElement::EntityFilter( entity )));
5933 // -------------------------------------------------------------------------------------
5934 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5936 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5937 if ( type == SMDSAbs_All && !_meshDS )
5939 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5941 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5942 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5944 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5946 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5947 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5949 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5950 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5952 // -------------------------------------------------------------------------------------
5953 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5954 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5956 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5957 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5958 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5960 // -------------------------------------------------------------------------------------
5961 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5962 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5963 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5964 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5965 #undef _GET_ITER_DEFINE
5967 // END Implementation of SMESH_MeshPartDS
5969 //================================================================================