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 );
1712 // shape index in SMESHDS
1713 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1714 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1717 //================================================================================
1719 * Remove GEOM group data relating to removed smesh object
1721 //================================================================================
1723 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1725 list<TGeomGroupData>::iterator
1726 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1727 for ( ; data != dataEnd; ++data ) {
1728 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1729 _geomGroupData.erase( data );
1735 //================================================================================
1737 * \brief Return new group contents if it has been changed and update group data
1739 //================================================================================
1741 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1743 TopoDS_Shape newShape;
1746 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1747 if ( study->_is_nil() ) return newShape; // means "not changed"
1748 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1749 if ( !groupSO->_is_nil() )
1751 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1752 if ( CORBA::is_nil( groupObj )) return newShape;
1753 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1755 // get indices of group items
1756 set<int> curIndices;
1757 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1758 GEOM::GEOM_IGroupOperations_wrap groupOp =
1759 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1760 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1761 for ( int i = 0; i < ids->length(); ++i )
1762 curIndices.insert( ids[i] );
1764 if ( groupData._indices == curIndices )
1765 return newShape; // group not changed
1768 groupData._indices = curIndices;
1770 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1771 if ( !geomClient ) return newShape;
1772 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1773 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1774 newShape = _gen_i->GeomObjectToShape( geomGroup );
1777 if ( newShape.IsNull() ) {
1778 // geom group becomes empty - return empty compound
1779 TopoDS_Compound compound;
1780 BRep_Builder().MakeCompound(compound);
1781 newShape = compound;
1788 //-----------------------------------------------------------------------------
1790 * \brief Storage of shape and index used in CheckGeomGroupModif()
1792 struct TIndexedShape
1795 TopoDS_Shape _shape;
1796 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1798 //-----------------------------------------------------------------------------
1800 * \brief Data to re-create a group on geometry
1802 struct TGroupOnGeomData
1806 SMDSAbs_ElementType _type;
1808 Quantity_Color _color;
1812 //=============================================================================
1814 * \brief Update data if geometry changes
1818 //=============================================================================
1820 void SMESH_Mesh_i::CheckGeomModif()
1822 if ( !_impl->HasShapeToMesh() ) return;
1824 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1825 if ( study->_is_nil() ) return;
1827 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1828 if ( mainGO->_is_nil() ) return;
1830 if ( mainGO->GetType() == GEOM_GROUP ||
1831 mainGO->GetTick() == _mainShapeTick )
1833 CheckGeomGroupModif();
1837 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1838 if ( !geomClient ) return;
1839 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1840 if ( geomGen->_is_nil() ) return;
1842 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1843 geomClient->RemoveShapeFromBuffer( ior.in() );
1845 // Update data taking into account that
1846 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1849 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1850 if ( newShape.IsNull() )
1853 _mainShapeTick = mainGO->GetTick();
1855 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1857 // store data of groups on geometry
1858 vector< TGroupOnGeomData > groupsData;
1859 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1860 groupsData.reserve( groups.size() );
1861 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1862 for ( ; g != groups.end(); ++g )
1863 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1865 TGroupOnGeomData data;
1866 data._oldID = group->GetID();
1867 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1868 data._type = group->GetType();
1869 data._name = group->GetStoreName();
1870 data._color = group->GetColor();
1871 groupsData.push_back( data );
1873 // store assigned hypotheses
1874 vector< pair< int, THypList > > ids2Hyps;
1875 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1876 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1878 const TopoDS_Shape& s = s2hyps.Key();
1879 const THypList& hyps = s2hyps.ChangeValue();
1880 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1883 // change shape to mesh
1884 int oldNbSubShapes = meshDS->MaxShapeIndex();
1885 _impl->ShapeToMesh( TopoDS_Shape() );
1886 _impl->ShapeToMesh( newShape );
1888 // re-add shapes of geom groups
1889 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1890 for ( ; data != _geomGroupData.end(); ++data )
1892 TopoDS_Shape newShape = newGroupShape( *data );
1893 if ( !newShape.IsNull() )
1895 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
1897 TopoDS_Compound compound;
1898 BRep_Builder().MakeCompound( compound );
1899 BRep_Builder().Add( compound, newShape );
1900 newShape = compound;
1902 _impl->GetSubMesh( newShape );
1905 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
1906 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
1907 SALOME::INTERNAL_ERROR );
1909 // re-assign hypotheses
1910 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1912 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1913 const THypList& hyps = ids2Hyps[i].second;
1914 THypList::const_iterator h = hyps.begin();
1915 for ( ; h != hyps.end(); ++h )
1916 _impl->AddHypothesis( s, (*h)->GetID() );
1920 for ( size_t i = 0; i < groupsData.size(); ++i )
1922 const TGroupOnGeomData& data = groupsData[i];
1924 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1925 if ( i2g == _mapGroups.end() ) continue;
1927 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1928 if ( !gr_i ) continue;
1931 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1932 meshDS->IndexToShape( data._shapeID ));
1935 _mapGroups.erase( i2g );
1939 g->GetGroupDS()->SetColor( data._color );
1940 gr_i->changeLocalId( id );
1941 _mapGroups[ id ] = i2g->second;
1942 if ( data._oldID != id )
1943 _mapGroups.erase( i2g );
1947 // update _mapSubMesh
1948 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1949 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1950 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1954 //=============================================================================
1956 * \brief Update objects depending on changed geom groups
1958 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1959 * issue 0020210: Update of a smesh group after modification of the associated geom group
1961 //=============================================================================
1963 void SMESH_Mesh_i::CheckGeomGroupModif()
1965 if ( !_impl->HasShapeToMesh() ) return;
1967 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1968 if ( study->_is_nil() ) return;
1970 CORBA::Long nbEntities = NbNodes() + NbElements();
1972 // Check if group contents changed
1974 typedef map< string, TopoDS_Shape > TEntry2Geom;
1975 TEntry2Geom newGroupContents;
1977 list<TGeomGroupData>::iterator
1978 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1979 for ( ; data != dataEnd; ++data )
1981 pair< TEntry2Geom::iterator, bool > it_new =
1982 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1983 bool processedGroup = !it_new.second;
1984 TopoDS_Shape& newShape = it_new.first->second;
1985 if ( !processedGroup )
1986 newShape = newGroupShape( *data );
1987 if ( newShape.IsNull() )
1988 continue; // no changes
1991 _preMeshInfo->ForgetOrLoad();
1993 if ( processedGroup ) { // update group indices
1994 list<TGeomGroupData>::iterator data2 = data;
1995 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1996 data->_indices = data2->_indices;
1999 // Update SMESH objects according to new GEOM group contents
2001 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2002 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2004 int oldID = submesh->GetId();
2005 if ( !_mapSubMeshIor.count( oldID ))
2007 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2009 // update hypotheses
2010 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2011 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2012 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2014 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2015 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2017 // care of submeshes
2018 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2019 int newID = newSubmesh->GetId();
2020 if ( newID != oldID ) {
2021 _mapSubMesh [ newID ] = newSubmesh;
2022 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2023 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2024 _mapSubMesh. erase(oldID);
2025 _mapSubMesh_i. erase(oldID);
2026 _mapSubMeshIor.erase(oldID);
2027 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2032 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2033 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2034 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2036 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2038 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2039 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2040 ds->SetShape( newShape );
2045 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2046 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2048 // Remove groups and submeshes basing on removed sub-shapes
2050 TopTools_MapOfShape newShapeMap;
2051 TopoDS_Iterator shapeIt( newShape );
2052 for ( ; shapeIt.More(); shapeIt.Next() )
2053 newShapeMap.Add( shapeIt.Value() );
2055 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2056 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2058 if ( newShapeMap.Contains( shapeIt.Value() ))
2060 TopTools_IndexedMapOfShape oldShapeMap;
2061 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2062 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2064 const TopoDS_Shape& oldShape = oldShapeMap(i);
2065 int oldInd = meshDS->ShapeToIndex( oldShape );
2067 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2068 if ( i_smIor != _mapSubMeshIor.end() ) {
2069 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2072 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2073 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2075 // check if a group bases on oldInd shape
2076 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2077 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2078 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2079 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2081 RemoveGroup( i_grp->second ); // several groups can base on same shape
2082 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2087 // Reassign hypotheses and update groups after setting the new shape to mesh
2089 // collect anassigned hypotheses
2090 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2091 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2092 TShapeHypList assignedHyps;
2093 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2095 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2096 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2097 if ( !hyps.empty() ) {
2098 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2099 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2100 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2103 // collect shapes supporting groups
2104 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2105 TShapeTypeList groupData;
2106 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2107 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2108 for ( ; grIt != groups.end(); ++grIt )
2110 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2112 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2114 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2115 _impl->ShapeToMesh( newShape );
2117 // reassign hypotheses
2118 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2119 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2121 TIndexedShape& geom = indS_hyps->first;
2122 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2123 int oldID = geom._index;
2124 int newID = meshDS->ShapeToIndex( geom._shape );
2125 if ( oldID == 1 ) { // main shape
2127 geom._shape = newShape;
2131 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2132 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2133 // care of submeshes
2134 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2135 if ( newID != oldID ) {
2136 _mapSubMesh [ newID ] = newSubmesh;
2137 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2138 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2139 _mapSubMesh. erase(oldID);
2140 _mapSubMesh_i. erase(oldID);
2141 _mapSubMeshIor.erase(oldID);
2142 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2146 TShapeTypeList::iterator geomType = groupData.begin();
2147 for ( ; geomType != groupData.end(); ++geomType )
2149 const TIndexedShape& geom = geomType->first;
2150 int oldID = geom._index;
2151 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2154 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2155 CORBA::String_var name = groupSO->GetName();
2157 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2159 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2160 group_i->changeLocalId( newID );
2163 break; // everything has been updated
2166 } // loop on group data
2170 CORBA::Long newNbEntities = NbNodes() + NbElements();
2171 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2172 if ( newNbEntities != nbEntities )
2174 // Add all SObjects with icons to soToUpdateIcons
2175 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2177 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2178 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2179 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2181 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2182 i_gr != _mapGroups.end(); ++i_gr ) // groups
2183 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2186 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2187 for ( ; so != soToUpdateIcons.end(); ++so )
2188 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2191 //=============================================================================
2193 * \brief Create standalone group from a group on geometry or filter
2195 //=============================================================================
2197 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2198 throw (SALOME::SALOME_Exception)
2200 SMESH::SMESH_Group_var aGroup;
2205 _preMeshInfo->FullLoadFromFile();
2207 if ( theGroup->_is_nil() )
2208 return aGroup._retn();
2210 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2212 return aGroup._retn();
2214 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2216 const int anId = aGroupToRem->GetLocalID();
2217 if ( !_impl->ConvertToStandalone( anId ) )
2218 return aGroup._retn();
2219 removeGeomGroupData( theGroup );
2221 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2223 // remove old instance of group from own map
2224 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2225 _mapGroups.erase( anId );
2227 SALOMEDS::StudyBuilder_var builder;
2228 SALOMEDS::SObject_wrap aGroupSO;
2229 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2230 if ( !aStudy->_is_nil() ) {
2231 builder = aStudy->NewBuilder();
2232 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2233 if ( !aGroupSO->_is_nil() )
2235 // remove reference to geometry
2236 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2237 for ( ; chItr->More(); chItr->Next() )
2238 // Remove group's child SObject
2239 builder->RemoveObject( chItr->Value() );
2241 // Update Python script
2242 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2243 << ".ConvertToStandalone( " << aGroupSO << " )";
2245 // change icon of Group on Filter
2248 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2249 const int isEmpty = ( elemTypes->length() == 0 );
2252 SALOMEDS::GenericAttribute_wrap anAttr =
2253 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2254 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2255 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2261 // remember new group in own map
2262 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2263 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2265 // register CORBA object for persistence
2266 _gen_i->RegisterObject( aGroup );
2268 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2269 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2270 //aGroup->Register();
2271 aGroupToRem->UnRegister();
2273 SMESH_CATCH( SMESH::throwCorbaException );
2275 return aGroup._retn();
2278 //=============================================================================
2282 //=============================================================================
2284 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2286 if(MYDEBUG) MESSAGE( "createSubMesh" );
2287 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2288 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2289 const int subMeshId = mySubMesh->GetId();
2291 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2292 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2294 _mapSubMesh [subMeshId] = mySubMesh;
2295 _mapSubMesh_i [subMeshId] = subMeshServant;
2296 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2298 subMeshServant->Register();
2300 // register CORBA object for persistence
2301 int nextId = _gen_i->RegisterObject( subMesh );
2302 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2303 else { nextId = 0; } // avoid "unused variable" warning
2305 // to track changes of GEOM groups
2306 addGeomGroupData( theSubShapeObject, subMesh );
2308 return subMesh._retn();
2311 //=======================================================================
2312 //function : getSubMesh
2314 //=======================================================================
2316 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2318 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2319 if ( it == _mapSubMeshIor.end() )
2320 return SMESH::SMESH_subMesh::_nil();
2322 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2325 //=============================================================================
2329 //=============================================================================
2331 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2332 GEOM::GEOM_Object_ptr theSubShapeObject )
2334 bool isHypChanged = false;
2335 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2336 return isHypChanged;
2338 const int subMeshId = theSubMesh->GetId();
2340 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2342 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2344 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2347 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2348 isHypChanged = !hyps.empty();
2349 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2350 for ( ; hyp != hyps.end(); ++hyp )
2351 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2358 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2359 isHypChanged = ( aHypList->length() > 0 );
2360 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2361 removeHypothesis( theSubShapeObject, aHypList[i] );
2364 catch( const SALOME::SALOME_Exception& ) {
2365 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2367 removeGeomGroupData( theSubShapeObject );
2371 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2372 if ( id_smi != _mapSubMesh_i.end() )
2373 id_smi->second->UnRegister();
2375 // remove a CORBA object
2376 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2377 if ( id_smptr != _mapSubMeshIor.end() )
2378 SMESH::SMESH_subMesh_var( id_smptr->second );
2380 _mapSubMesh.erase(subMeshId);
2381 _mapSubMesh_i.erase(subMeshId);
2382 _mapSubMeshIor.erase(subMeshId);
2384 return isHypChanged;
2387 //=============================================================================
2391 //=============================================================================
2393 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2394 const char* theName,
2395 const TopoDS_Shape& theShape,
2396 const SMESH_PredicatePtr& thePredicate )
2398 std::string newName;
2399 if ( !theName || strlen( theName ) == 0 )
2401 std::set< std::string > presentNames;
2402 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2403 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2405 CORBA::String_var name = i_gr->second->GetName();
2406 presentNames.insert( name.in() );
2409 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2410 } while ( !presentNames.insert( newName ).second );
2411 theName = newName.c_str();
2414 SMESH::SMESH_GroupBase_var aGroup;
2415 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2417 SMESH_GroupBase_i* aGroupImpl;
2418 if ( !theShape.IsNull() )
2419 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2420 else if ( thePredicate )
2421 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2423 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2425 aGroup = aGroupImpl->_this();
2426 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2427 aGroupImpl->Register();
2429 // register CORBA object for persistence
2430 int nextId = _gen_i->RegisterObject( aGroup );
2431 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2432 else { nextId = 0; } // avoid "unused variable" warning in release mode
2434 // to track changes of GEOM groups
2435 if ( !theShape.IsNull() ) {
2436 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2437 addGeomGroupData( geom, aGroup );
2440 return aGroup._retn();
2443 //=============================================================================
2445 * SMESH_Mesh_i::removeGroup
2447 * Should be called by ~SMESH_Group_i()
2449 //=============================================================================
2451 void SMESH_Mesh_i::removeGroup( const int theId )
2453 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2454 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2455 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2456 _mapGroups.erase( theId );
2457 removeGeomGroupData( group );
2458 if ( !_impl->RemoveGroup( theId ))
2460 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2461 RemoveGroup( group );
2463 group->UnRegister();
2467 //=============================================================================
2471 //=============================================================================
2473 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2474 throw(SALOME::SALOME_Exception)
2476 SMESH::log_array_var aLog;
2480 _preMeshInfo->FullLoadFromFile();
2482 list < SMESHDS_Command * >logDS = _impl->GetLog();
2483 aLog = new SMESH::log_array;
2485 int lg = logDS.size();
2488 list < SMESHDS_Command * >::iterator its = logDS.begin();
2489 while(its != logDS.end()){
2490 SMESHDS_Command *com = *its;
2491 int comType = com->GetType();
2493 int lgcom = com->GetNumber();
2495 const list < int >&intList = com->GetIndexes();
2496 int inum = intList.size();
2498 list < int >::const_iterator ii = intList.begin();
2499 const list < double >&coordList = com->GetCoords();
2500 int rnum = coordList.size();
2502 list < double >::const_iterator ir = coordList.begin();
2503 aLog[indexLog].commandType = comType;
2504 aLog[indexLog].number = lgcom;
2505 aLog[indexLog].coords.length(rnum);
2506 aLog[indexLog].indexes.length(inum);
2507 for(int i = 0; i < rnum; i++){
2508 aLog[indexLog].coords[i] = *ir;
2509 //MESSAGE(" "<<i<<" "<<ir.Value());
2512 for(int i = 0; i < inum; i++){
2513 aLog[indexLog].indexes[i] = *ii;
2514 //MESSAGE(" "<<i<<" "<<ii.Value());
2523 SMESH_CATCH( SMESH::throwCorbaException );
2525 return aLog._retn();
2529 //=============================================================================
2533 //=============================================================================
2535 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2539 SMESH_CATCH( SMESH::throwCorbaException );
2542 //=============================================================================
2546 //=============================================================================
2548 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2553 //=============================================================================
2557 //=============================================================================
2559 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2564 //=============================================================================
2567 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2568 // issue 0020918: groups removal is caused by hyp modification
2569 // issue 0021208: to forget not loaded mesh data at hyp modification
2570 struct TCallUp_i : public SMESH_Mesh::TCallUp
2572 SMESH_Mesh_i* _mesh;
2573 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2574 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2575 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2576 virtual void Load () { _mesh->Load(); }
2580 //================================================================================
2582 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2584 //================================================================================
2586 void SMESH_Mesh_i::onHypothesisModified()
2589 _preMeshInfo->ForgetOrLoad();
2592 //=============================================================================
2596 //=============================================================================
2598 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2600 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2603 _impl->SetCallUp( new TCallUp_i(this));
2606 //=============================================================================
2610 //=============================================================================
2612 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2614 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2618 //=============================================================================
2620 * Return mesh editor
2622 //=============================================================================
2624 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2625 throw (SALOME::SALOME_Exception)
2627 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2631 _preMeshInfo->FullLoadFromFile();
2633 // Create MeshEditor
2635 _editor = new SMESH_MeshEditor_i( this, false );
2636 aMeshEdVar = _editor->_this();
2638 // Update Python script
2639 TPythonDump() << _editor << " = "
2640 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2642 SMESH_CATCH( SMESH::throwCorbaException );
2644 return aMeshEdVar._retn();
2647 //=============================================================================
2649 * Return mesh edition previewer
2651 //=============================================================================
2653 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2654 throw (SALOME::SALOME_Exception)
2656 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2660 _preMeshInfo->FullLoadFromFile();
2662 if ( !_previewEditor )
2663 _previewEditor = new SMESH_MeshEditor_i( this, true );
2664 aMeshEdVar = _previewEditor->_this();
2666 SMESH_CATCH( SMESH::throwCorbaException );
2668 return aMeshEdVar._retn();
2671 //================================================================================
2673 * \brief Return true if the mesh has been edited since a last total re-compute
2674 * and those modifications may prevent successful partial re-compute
2676 //================================================================================
2678 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2680 Unexpect aCatch(SALOME_SalomeException);
2681 return _impl->HasModificationsToDiscard();
2684 //================================================================================
2686 * \brief Returns a random unique color
2688 //================================================================================
2690 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2692 const int MAX_ATTEMPTS = 100;
2694 double tolerance = 0.5;
2695 SALOMEDS::Color col;
2699 // generate random color
2700 double red = (double)rand() / RAND_MAX;
2701 double green = (double)rand() / RAND_MAX;
2702 double blue = (double)rand() / RAND_MAX;
2703 // check existence in the list of the existing colors
2704 bool matched = false;
2705 std::list<SALOMEDS::Color>::const_iterator it;
2706 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2707 SALOMEDS::Color color = *it;
2708 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2709 matched = tol < tolerance;
2711 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2712 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2720 //=============================================================================
2722 * Sets auto-color mode. If it is on, groups get unique random colors
2724 //=============================================================================
2726 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2728 Unexpect aCatch(SALOME_SalomeException);
2729 _impl->SetAutoColor(theAutoColor);
2731 TPythonDump pyDump; // not to dump group->SetColor() from below code
2732 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2734 std::list<SALOMEDS::Color> aReservedColors;
2735 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2736 for ( ; it != _mapGroups.end(); it++ ) {
2737 if ( CORBA::is_nil( it->second )) continue;
2738 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2739 it->second->SetColor( aColor );
2740 aReservedColors.push_back( aColor );
2744 //=============================================================================
2746 * Returns true if auto-color mode is on
2748 //=============================================================================
2750 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2752 Unexpect aCatch(SALOME_SalomeException);
2753 return _impl->GetAutoColor();
2756 //=============================================================================
2758 * Checks if there are groups with equal names
2760 //=============================================================================
2762 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2764 return _impl->HasDuplicatedGroupNamesMED();
2767 //================================================================================
2769 * \brief Care of a file before exporting mesh into it
2771 //================================================================================
2773 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2775 TCollection_AsciiString aFullName ((char*)file);
2776 OSD_Path aPath (aFullName);
2777 OSD_File aFile (aPath);
2778 if (aFile.Exists()) {
2779 // existing filesystem node
2780 if (aFile.KindOfFile() == OSD_FILE) {
2781 if (aFile.IsWriteable()) {
2786 if (aFile.Failed()) {
2787 TCollection_AsciiString msg ("File ");
2788 msg += aFullName + " cannot be replaced.";
2789 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2792 TCollection_AsciiString msg ("File ");
2793 msg += aFullName + " cannot be overwritten.";
2794 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2797 TCollection_AsciiString msg ("Location ");
2798 msg += aFullName + " is not a file.";
2799 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2802 // nonexisting file; check if it can be created
2804 aFile.Build(OSD_WriteOnly, OSD_Protection());
2805 if (aFile.Failed()) {
2806 TCollection_AsciiString msg ("You cannot create the file ");
2807 msg += aFullName + ". Check the directory existance and access rights.";
2808 THROW_SALOME_CORBA_EXCEPTION(msg.ToCString(), SALOME::BAD_PARAM);
2816 //================================================================================
2818 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2819 * \param file - file name
2820 * \param overwrite - to erase the file or not
2821 * \retval string - mesh name
2823 //================================================================================
2825 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2826 CORBA::Boolean overwrite)
2829 PrepareForWriting(file, overwrite);
2830 string aMeshName = "Mesh";
2831 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2832 if ( !aStudy->_is_nil() ) {
2833 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2834 if ( !aMeshSO->_is_nil() ) {
2835 CORBA::String_var name = aMeshSO->GetName();
2837 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2838 if ( !aStudy->GetProperties()->IsLocked() )
2840 SALOMEDS::GenericAttribute_wrap anAttr;
2841 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2842 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2843 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2844 ASSERT(!aFileName->_is_nil());
2845 aFileName->SetValue(file);
2846 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2847 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2848 ASSERT(!aFileType->_is_nil());
2849 aFileType->SetValue("FICHIERMED");
2853 // Update Python script
2854 // set name of mesh before export
2855 TPythonDump() << _gen_i << ".SetName("
2856 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2858 // check names of groups
2864 //================================================================================
2866 * \brief Export to med file
2868 //================================================================================
2870 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2871 CORBA::Boolean auto_groups,
2872 SMESH::MED_VERSION theVersion,
2873 CORBA::Boolean overwrite,
2874 CORBA::Boolean autoDimension)
2875 throw(SALOME::SALOME_Exception)
2879 _preMeshInfo->FullLoadFromFile();
2881 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2882 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2884 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2885 << file << "', " << auto_groups << ", "
2886 << theVersion << ", " << overwrite << ", "
2887 << autoDimension << " )";
2889 SMESH_CATCH( SMESH::throwCorbaException );
2892 //================================================================================
2894 * \brief Export a mesh to a med file
2896 //================================================================================
2898 void SMESH_Mesh_i::ExportToMED (const char* file,
2899 CORBA::Boolean auto_groups,
2900 SMESH::MED_VERSION theVersion)
2901 throw(SALOME::SALOME_Exception)
2903 ExportToMEDX(file,auto_groups,theVersion,true);
2906 //================================================================================
2908 * \brief Export a mesh to a med file
2910 //================================================================================
2912 void SMESH_Mesh_i::ExportMED (const char* file,
2913 CORBA::Boolean auto_groups)
2914 throw(SALOME::SALOME_Exception)
2916 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2919 //================================================================================
2921 * \brief Export a mesh to a SAUV file
2923 //================================================================================
2925 void SMESH_Mesh_i::ExportSAUV (const char* file,
2926 CORBA::Boolean auto_groups)
2927 throw(SALOME::SALOME_Exception)
2929 Unexpect aCatch(SALOME_SalomeException);
2931 _preMeshInfo->FullLoadFromFile();
2933 string aMeshName = prepareMeshNameAndGroups(file, true);
2934 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2935 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2936 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2940 //================================================================================
2942 * \brief Export a mesh to a DAT file
2944 //================================================================================
2946 void SMESH_Mesh_i::ExportDAT (const char *file)
2947 throw(SALOME::SALOME_Exception)
2949 Unexpect aCatch(SALOME_SalomeException);
2951 _preMeshInfo->FullLoadFromFile();
2953 // Update Python script
2954 // check names of groups
2956 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2959 PrepareForWriting(file);
2960 _impl->ExportDAT(file);
2963 //================================================================================
2965 * \brief Export a mesh to an UNV file
2967 //================================================================================
2969 void SMESH_Mesh_i::ExportUNV (const char *file)
2970 throw(SALOME::SALOME_Exception)
2972 Unexpect aCatch(SALOME_SalomeException);
2974 _preMeshInfo->FullLoadFromFile();
2976 // Update Python script
2977 // check names of groups
2979 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2982 PrepareForWriting(file);
2983 _impl->ExportUNV(file);
2986 //================================================================================
2988 * \brief Export a mesh to an STL file
2990 //================================================================================
2992 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2993 throw(SALOME::SALOME_Exception)
2995 Unexpect aCatch(SALOME_SalomeException);
2997 _preMeshInfo->FullLoadFromFile();
2999 // Update Python script
3000 // check names of groups
3002 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3003 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3006 PrepareForWriting(file);
3007 _impl->ExportSTL(file, isascii);
3010 //================================================================================
3012 * \brief Export a part of mesh to a med file
3014 //================================================================================
3016 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3018 CORBA::Boolean auto_groups,
3019 SMESH::MED_VERSION version,
3020 CORBA::Boolean overwrite,
3021 CORBA::Boolean autoDimension,
3022 const GEOM::ListOfFields& fields,
3023 const char* geomAssocFields)
3024 throw (SALOME::SALOME_Exception)
3028 _preMeshInfo->FullLoadFromFile();
3031 bool have0dField = false;
3032 if ( fields.length() > 0 )
3034 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3035 if ( shapeToMesh->_is_nil() )
3036 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3038 for ( size_t i = 0; i < fields.length(); ++i )
3040 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3041 THROW_SALOME_CORBA_EXCEPTION
3042 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3043 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3044 if ( fieldShape->_is_nil() )
3045 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3046 if ( !fieldShape->IsSame( shapeToMesh ) )
3047 THROW_SALOME_CORBA_EXCEPTION
3048 ( "Field defined not on shape", SALOME::BAD_PARAM);
3049 if ( fields[i]->GetDimension() == 0 )
3052 if ( geomAssocFields )
3053 for ( int i = 0; geomAssocFields[i]; ++i )
3054 switch ( geomAssocFields[i] ) {
3055 case 'v':case 'e':case 'f':case 's': break;
3056 case 'V':case 'E':case 'F':case 'S': break;
3057 default: THROW_SALOME_CORBA_EXCEPTION
3058 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3062 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3066 string aMeshName = "Mesh";
3067 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3068 if ( CORBA::is_nil( meshPart ) ||
3069 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3071 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3072 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3073 version, 0, autoDimension, have0dField);
3074 meshDS = _impl->GetMeshDS();
3079 _preMeshInfo->FullLoadFromFile();
3081 PrepareForWriting(file, overwrite);
3083 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3084 if ( !aStudy->_is_nil() ) {
3085 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3086 if ( !SO->_is_nil() ) {
3087 CORBA::String_var name = SO->GetName();
3091 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3092 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3093 version, partDS, autoDimension, have0dField);
3094 meshDS = tmpDSDeleter._obj = partDS;
3099 if ( _impl->HasShapeToMesh() )
3101 DriverMED_W_Field fieldWriter;
3102 fieldWriter.SetFile( file );
3103 fieldWriter.SetMeshName( aMeshName );
3104 fieldWriter.AddODOnVertices( have0dField );
3106 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3110 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3111 goList->length( fields.length() );
3112 for ( size_t i = 0; i < fields.length(); ++i )
3114 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3117 TPythonDump() << _this() << ".ExportPartToMED( "
3118 << meshPart << ", r'" << file << "', "
3119 << auto_groups << ", " << version << ", " << overwrite << ", "
3120 << autoDimension << ", " << goList
3121 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3123 SMESH_CATCH( SMESH::throwCorbaException );
3126 //================================================================================
3128 * Write GEOM fields to MED file
3130 //================================================================================
3132 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3133 SMESHDS_Mesh* meshDS,
3134 const GEOM::ListOfFields& fields,
3135 const char* geomAssocFields)
3137 #define METH "SMESH_Mesh_i::exportMEDFields() "
3139 if (( fields.length() < 1 ) &&
3140 ( !geomAssocFields || !geomAssocFields[0] ))
3143 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3144 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3145 std::vector< int > subIdsByDim[ 4 ];
3146 const double noneDblValue = 0.;
3147 const double noneIntValue = 0;
3149 for ( size_t iF = 0; iF < fields.length(); ++iF )
3153 int dim = fields[ iF ]->GetDimension();
3154 SMDSAbs_ElementType elemType;
3155 TopAbs_ShapeEnum shapeType;
3157 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3158 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3159 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3160 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3162 continue; // skip fields on whole shape
3164 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3165 if ( dataType == GEOM::FDT_String )
3167 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3168 if ( stepIDs->length() < 1 )
3170 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3171 if ( comps->length() < 1 )
3173 CORBA::String_var name = fields[ iF ]->GetName();
3175 if ( !fieldWriter.Set( meshDS,
3179 ( dataType == GEOM::FDT_Int )))
3182 for ( size_t iC = 0; iC < comps->length(); ++iC )
3183 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3185 // find sub-shape IDs
3187 std::vector< int >& subIds = subIdsByDim[ dim ];
3188 if ( subIds.empty() )
3189 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3190 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3191 subIds.push_back( id );
3195 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3199 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3201 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3202 if ( step->_is_nil() )
3205 CORBA::Long stamp = step->GetStamp();
3206 CORBA::Long id = step->GetID();
3207 fieldWriter.SetDtIt( int( stamp ), int( id ));
3209 // fill dblVals or intVals
3212 case GEOM::FDT_Double:
3214 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3215 if ( dblStep->_is_nil() ) continue;
3216 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3217 if ( vv->length() != subIds.size() )
3218 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3219 for ( size_t i = 0; i < vv->length(); ++i )
3220 dblVals[ subIds[ i ]] = vv[ i ];
3225 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3226 if ( intStep->_is_nil() ) continue;
3227 GEOM::ListOfLong_var vv = intStep->GetValues();
3228 if ( vv->length() != subIds.size() )
3229 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3230 for ( size_t i = 0; i < vv->length(); ++i )
3231 intVals[ subIds[ i ]] = (int) vv[ i ];
3234 case GEOM::FDT_Bool:
3236 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3237 if ( boolStep->_is_nil() ) continue;
3238 GEOM::short_array_var vv = boolStep->GetValues();
3239 if ( vv->length() != subIds.size() )
3240 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3241 for ( size_t i = 0; i < vv->length(); ++i )
3242 intVals[ subIds[ i ]] = (int) vv[ i ];
3248 // pass values to fieldWriter
3249 elemIt = fieldWriter.GetOrderedElems();
3250 if ( dataType == GEOM::FDT_Double )
3251 while ( elemIt->more() )
3253 const SMDS_MeshElement* e = elemIt->next();
3254 const int shapeID = e->getshapeId();
3255 if ( shapeID < 1 || shapeID >= dblVals.size() )
3256 fieldWriter.AddValue( noneDblValue );
3258 fieldWriter.AddValue( dblVals[ shapeID ]);
3261 while ( elemIt->more() )
3263 const SMDS_MeshElement* e = elemIt->next();
3264 const int shapeID = e->getshapeId();
3265 if ( shapeID < 1 || shapeID >= intVals.size() )
3266 fieldWriter.AddValue( noneIntValue );
3268 fieldWriter.AddValue( intVals[ shapeID ]);
3272 fieldWriter.Perform();
3273 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3274 if ( res && res->IsKO() )
3276 if ( res->myComment.empty() )
3277 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3279 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3285 if ( !geomAssocFields || !geomAssocFields[0] )
3288 // write geomAssocFields
3290 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3291 shapeDim[ TopAbs_COMPOUND ] = 3;
3292 shapeDim[ TopAbs_COMPSOLID ] = 3;
3293 shapeDim[ TopAbs_SOLID ] = 3;
3294 shapeDim[ TopAbs_SHELL ] = 2;
3295 shapeDim[ TopAbs_FACE ] = 2;
3296 shapeDim[ TopAbs_WIRE ] = 1;
3297 shapeDim[ TopAbs_EDGE ] = 1;
3298 shapeDim[ TopAbs_VERTEX ] = 0;
3299 shapeDim[ TopAbs_SHAPE ] = 3;
3301 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3303 std::vector< std::string > compNames;
3304 switch ( geomAssocFields[ iF ]) {
3306 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/true );
3307 compNames.push_back( "dim" );
3310 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/true );
3313 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/true );
3316 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/true );
3320 compNames.push_back( "id" );
3321 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3322 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3324 fieldWriter.SetDtIt( -1, -1 );
3326 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3330 if ( compNames.size() == 2 ) // _vertices_
3331 while ( elemIt->more() )
3333 const SMDS_MeshElement* e = elemIt->next();
3334 const int shapeID = e->getshapeId();
3337 fieldWriter.AddValue( -1 );
3338 fieldWriter.AddValue( -1 );
3342 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3343 fieldWriter.AddValue( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]);
3344 fieldWriter.AddValue( shapeID );
3348 while ( elemIt->more() )
3350 const SMDS_MeshElement* e = elemIt->next();
3351 const int shapeID = e->getshapeId();
3353 fieldWriter.AddValue( -1 );
3355 fieldWriter.AddValue( shapeID );
3359 fieldWriter.Perform();
3360 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3361 if ( res && res->IsKO() )
3363 if ( res->myComment.empty() )
3364 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3366 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3369 } // loop on geomAssocFields
3374 //================================================================================
3376 * \brief Export a part of mesh to a DAT file
3378 //================================================================================
3380 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3382 throw (SALOME::SALOME_Exception)
3384 Unexpect aCatch(SALOME_SalomeException);
3386 _preMeshInfo->FullLoadFromFile();
3388 PrepareForWriting(file);
3390 SMESH_MeshPartDS partDS( meshPart );
3391 _impl->ExportDAT(file,&partDS);
3393 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3394 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3396 //================================================================================
3398 * \brief Export a part of mesh to an UNV file
3400 //================================================================================
3402 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3404 throw (SALOME::SALOME_Exception)
3406 Unexpect aCatch(SALOME_SalomeException);
3408 _preMeshInfo->FullLoadFromFile();
3410 PrepareForWriting(file);
3412 SMESH_MeshPartDS partDS( meshPart );
3413 _impl->ExportUNV(file, &partDS);
3415 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3416 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3418 //================================================================================
3420 * \brief Export a part of mesh to an STL file
3422 //================================================================================
3424 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3426 ::CORBA::Boolean isascii)
3427 throw (SALOME::SALOME_Exception)
3429 Unexpect aCatch(SALOME_SalomeException);
3431 _preMeshInfo->FullLoadFromFile();
3433 PrepareForWriting(file);
3435 SMESH_MeshPartDS partDS( meshPart );
3436 _impl->ExportSTL(file, isascii, &partDS);
3438 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3439 << meshPart<< ", r'" << file << "', " << isascii << ")";
3442 //================================================================================
3444 * \brief Export a part of mesh to an STL file
3446 //================================================================================
3448 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3450 CORBA::Boolean overwrite)
3451 throw (SALOME::SALOME_Exception)
3454 Unexpect aCatch(SALOME_SalomeException);
3456 _preMeshInfo->FullLoadFromFile();
3458 PrepareForWriting(file,overwrite);
3460 SMESH_MeshPartDS partDS( meshPart );
3461 _impl->ExportCGNS(file, &partDS);
3463 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3464 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3466 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3470 //================================================================================
3472 * \brief Export a part of mesh to a GMF file
3474 //================================================================================
3476 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3478 bool withRequiredGroups)
3479 throw (SALOME::SALOME_Exception)
3481 Unexpect aCatch(SALOME_SalomeException);
3483 _preMeshInfo->FullLoadFromFile();
3485 PrepareForWriting(file,/*overwrite=*/true);
3487 SMESH_MeshPartDS partDS( meshPart );
3488 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3490 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3491 << meshPart<< ", r'"
3493 << withRequiredGroups << ")";
3496 //=============================================================================
3498 * Return computation progress [0.,1]
3500 //=============================================================================
3502 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3506 return _impl->GetComputeProgress();
3508 SMESH_CATCH( SMESH::doNothing );
3512 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3514 Unexpect aCatch(SALOME_SalomeException);
3516 return _preMeshInfo->NbNodes();
3518 return _impl->NbNodes();
3521 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3523 Unexpect aCatch(SALOME_SalomeException);
3525 return _preMeshInfo->NbElements();
3527 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3530 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3532 Unexpect aCatch(SALOME_SalomeException);
3534 return _preMeshInfo->Nb0DElements();
3536 return _impl->Nb0DElements();
3539 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3541 Unexpect aCatch(SALOME_SalomeException);
3543 return _preMeshInfo->NbBalls();
3545 return _impl->NbBalls();
3548 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3550 Unexpect aCatch(SALOME_SalomeException);
3552 return _preMeshInfo->NbEdges();
3554 return _impl->NbEdges();
3557 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3558 throw(SALOME::SALOME_Exception)
3560 Unexpect aCatch(SALOME_SalomeException);
3562 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3564 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3567 //=============================================================================
3569 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3571 Unexpect aCatch(SALOME_SalomeException);
3573 return _preMeshInfo->NbFaces();
3575 return _impl->NbFaces();
3578 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3580 Unexpect aCatch(SALOME_SalomeException);
3582 return _preMeshInfo->NbTriangles();
3584 return _impl->NbTriangles();
3587 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3589 Unexpect aCatch(SALOME_SalomeException);
3591 return _preMeshInfo->NbBiQuadTriangles();
3593 return _impl->NbBiQuadTriangles();
3596 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3598 Unexpect aCatch(SALOME_SalomeException);
3600 return _preMeshInfo->NbQuadrangles();
3602 return _impl->NbQuadrangles();
3605 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3607 Unexpect aCatch(SALOME_SalomeException);
3609 return _preMeshInfo->NbBiQuadQuadrangles();
3611 return _impl->NbBiQuadQuadrangles();
3614 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3616 Unexpect aCatch(SALOME_SalomeException);
3618 return _preMeshInfo->NbPolygons();
3620 return _impl->NbPolygons();
3623 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3624 throw(SALOME::SALOME_Exception)
3626 Unexpect aCatch(SALOME_SalomeException);
3628 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3630 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3633 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3634 throw(SALOME::SALOME_Exception)
3636 Unexpect aCatch(SALOME_SalomeException);
3638 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3640 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3643 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3644 throw(SALOME::SALOME_Exception)
3646 Unexpect aCatch(SALOME_SalomeException);
3648 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3650 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3653 //=============================================================================
3655 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3657 Unexpect aCatch(SALOME_SalomeException);
3659 return _preMeshInfo->NbVolumes();
3661 return _impl->NbVolumes();
3664 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3666 Unexpect aCatch(SALOME_SalomeException);
3668 return _preMeshInfo->NbTetras();
3670 return _impl->NbTetras();
3673 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3675 Unexpect aCatch(SALOME_SalomeException);
3677 return _preMeshInfo->NbHexas();
3679 return _impl->NbHexas();
3682 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3684 Unexpect aCatch(SALOME_SalomeException);
3686 return _preMeshInfo->NbTriQuadHexas();
3688 return _impl->NbTriQuadraticHexas();
3691 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3693 Unexpect aCatch(SALOME_SalomeException);
3695 return _preMeshInfo->NbPyramids();
3697 return _impl->NbPyramids();
3700 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3702 Unexpect aCatch(SALOME_SalomeException);
3704 return _preMeshInfo->NbPrisms();
3706 return _impl->NbPrisms();
3709 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3711 Unexpect aCatch(SALOME_SalomeException);
3713 return _preMeshInfo->NbHexPrisms();
3715 return _impl->NbHexagonalPrisms();
3718 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3720 Unexpect aCatch(SALOME_SalomeException);
3722 return _preMeshInfo->NbPolyhedrons();
3724 return _impl->NbPolyhedrons();
3727 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3728 throw(SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3734 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3737 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3738 throw(SALOME::SALOME_Exception)
3740 Unexpect aCatch(SALOME_SalomeException);
3742 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3744 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3747 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3748 throw(SALOME::SALOME_Exception)
3750 Unexpect aCatch(SALOME_SalomeException);
3752 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3754 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3757 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3758 throw(SALOME::SALOME_Exception)
3760 Unexpect aCatch(SALOME_SalomeException);
3762 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3764 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3767 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3768 throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3774 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3777 //=============================================================================
3779 * Returns nb of published sub-meshes
3781 //=============================================================================
3783 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3785 Unexpect aCatch(SALOME_SalomeException);
3786 return _mapSubMesh_i.size();
3789 //=============================================================================
3791 * Dumps mesh into a string
3793 //=============================================================================
3795 char* SMESH_Mesh_i::Dump()
3799 return CORBA::string_dup( os.str().c_str() );
3802 //=============================================================================
3804 * Method of SMESH_IDSource interface
3806 //=============================================================================
3808 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3810 return GetElementsId();
3813 //=============================================================================
3815 * Returns ids of all elements
3817 //=============================================================================
3819 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3820 throw (SALOME::SALOME_Exception)
3822 Unexpect aCatch(SALOME_SalomeException);
3824 _preMeshInfo->FullLoadFromFile();
3826 SMESH::long_array_var aResult = new SMESH::long_array();
3827 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3829 if ( aSMESHDS_Mesh == NULL )
3830 return aResult._retn();
3832 long nbElements = NbElements();
3833 aResult->length( nbElements );
3834 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3835 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3836 aResult[i] = anIt->next()->GetID();
3838 return aResult._retn();
3842 //=============================================================================
3844 * Returns ids of all elements of given type
3846 //=============================================================================
3848 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3849 throw (SALOME::SALOME_Exception)
3851 Unexpect aCatch(SALOME_SalomeException);
3853 _preMeshInfo->FullLoadFromFile();
3855 SMESH::long_array_var aResult = new SMESH::long_array();
3856 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3858 if ( aSMESHDS_Mesh == NULL )
3859 return aResult._retn();
3861 long nbElements = NbElements();
3863 // No sense in returning ids of elements along with ids of nodes:
3864 // when theElemType == SMESH::ALL, return node ids only if
3865 // there are no elements
3866 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3867 return GetNodesId();
3869 aResult->length( nbElements );
3873 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3874 while ( i < nbElements && anIt->more() )
3875 aResult[i++] = anIt->next()->GetID();
3877 aResult->length( i );
3879 return aResult._retn();
3882 //=============================================================================
3884 * Returns ids of all nodes
3886 //=============================================================================
3888 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3889 throw (SALOME::SALOME_Exception)
3891 Unexpect aCatch(SALOME_SalomeException);
3893 _preMeshInfo->FullLoadFromFile();
3895 SMESH::long_array_var aResult = new SMESH::long_array();
3896 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3898 if ( aSMESHDS_Mesh == NULL )
3899 return aResult._retn();
3901 long nbNodes = NbNodes();
3902 aResult->length( nbNodes );
3903 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3904 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3905 aResult[i] = anIt->next()->GetID();
3907 return aResult._retn();
3910 //=============================================================================
3914 //=============================================================================
3916 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3917 throw (SALOME::SALOME_Exception)
3919 SMESH::ElementType type;
3923 _preMeshInfo->FullLoadFromFile();
3925 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3927 SMESH_CATCH( SMESH::throwCorbaException );
3932 //=============================================================================
3936 //=============================================================================
3938 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3939 throw (SALOME::SALOME_Exception)
3942 _preMeshInfo->FullLoadFromFile();
3944 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3946 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3948 return ( SMESH::EntityType ) e->GetEntityType();
3951 //=============================================================================
3955 //=============================================================================
3957 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3958 throw (SALOME::SALOME_Exception)
3961 _preMeshInfo->FullLoadFromFile();
3963 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3965 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3967 return ( SMESH::GeometryType ) e->GetGeomType();
3970 //=============================================================================
3972 * Returns ID of elements for given submesh
3974 //=============================================================================
3975 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3976 throw (SALOME::SALOME_Exception)
3978 SMESH::long_array_var aResult = new SMESH::long_array();
3982 _preMeshInfo->FullLoadFromFile();
3984 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3985 if(!SM) return aResult._retn();
3987 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3988 if(!SDSM) return aResult._retn();
3990 aResult->length(SDSM->NbElements());
3992 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3994 while ( eIt->more() ) {
3995 aResult[i++] = eIt->next()->GetID();
3998 SMESH_CATCH( SMESH::throwCorbaException );
4000 return aResult._retn();
4003 //=============================================================================
4005 * Returns ID of nodes for given submesh
4006 * If param all==true - returns all nodes, else -
4007 * returns only nodes on shapes.
4009 //=============================================================================
4011 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4013 throw (SALOME::SALOME_Exception)
4015 SMESH::long_array_var aResult = new SMESH::long_array();
4019 _preMeshInfo->FullLoadFromFile();
4021 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4022 if(!SM) return aResult._retn();
4024 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4025 if(!SDSM) return aResult._retn();
4028 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4029 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4030 while ( nIt->more() ) {
4031 const SMDS_MeshNode* elem = nIt->next();
4032 theElems.insert( elem->GetID() );
4035 else { // all nodes of submesh elements
4036 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4037 while ( eIt->more() ) {
4038 const SMDS_MeshElement* anElem = eIt->next();
4039 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4040 while ( nIt->more() ) {
4041 const SMDS_MeshElement* elem = nIt->next();
4042 theElems.insert( elem->GetID() );
4047 aResult->length(theElems.size());
4048 set<int>::iterator itElem;
4050 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4051 aResult[i++] = *itElem;
4053 SMESH_CATCH( SMESH::throwCorbaException );
4055 return aResult._retn();
4058 //=============================================================================
4060 * Returns type of elements for given submesh
4062 //=============================================================================
4064 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4065 throw (SALOME::SALOME_Exception)
4067 SMESH::ElementType type;
4071 _preMeshInfo->FullLoadFromFile();
4073 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4074 if(!SM) return SMESH::ALL;
4076 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4077 if(!SDSM) return SMESH::ALL;
4079 if(SDSM->NbElements()==0)
4080 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4082 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4083 const SMDS_MeshElement* anElem = eIt->next();
4085 type = ( SMESH::ElementType ) anElem->GetType();
4087 SMESH_CATCH( SMESH::throwCorbaException );
4093 //=============================================================================
4095 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4097 //=============================================================================
4099 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4102 _preMeshInfo->FullLoadFromFile();
4104 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4106 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4111 //=============================================================================
4113 * Get XYZ coordinates of node as list of double
4114 * If there is not node for given ID - returns empty list
4116 //=============================================================================
4118 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4121 _preMeshInfo->FullLoadFromFile();
4123 SMESH::double_array_var aResult = new SMESH::double_array();
4124 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4125 if ( aSMESHDS_Mesh == NULL )
4126 return aResult._retn();
4129 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4131 return aResult._retn();
4135 aResult[0] = aNode->X();
4136 aResult[1] = aNode->Y();
4137 aResult[2] = aNode->Z();
4138 return aResult._retn();
4142 //=============================================================================
4144 * For given node returns list of IDs of inverse elements
4145 * If there is not node for given ID - returns empty list
4147 //=============================================================================
4149 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4152 _preMeshInfo->FullLoadFromFile();
4154 SMESH::long_array_var aResult = new SMESH::long_array();
4155 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4156 if ( aSMESHDS_Mesh == NULL )
4157 return aResult._retn();
4160 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4162 return aResult._retn();
4164 // find inverse elements
4165 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4166 TColStd_SequenceOfInteger IDs;
4167 while(eIt->more()) {
4168 const SMDS_MeshElement* elem = eIt->next();
4169 IDs.Append(elem->GetID());
4171 if(IDs.Length()>0) {
4172 aResult->length(IDs.Length());
4174 for(; i<=IDs.Length(); i++) {
4175 aResult[i-1] = IDs.Value(i);
4178 return aResult._retn();
4181 //=============================================================================
4183 * \brief Return position of a node on shape
4185 //=============================================================================
4187 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4190 _preMeshInfo->FullLoadFromFile();
4192 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4193 aNodePosition->shapeID = 0;
4194 aNodePosition->shapeType = GEOM::SHAPE;
4196 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4197 if ( !mesh ) return aNodePosition;
4199 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4201 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4203 aNodePosition->shapeID = aNode->getshapeId();
4204 switch ( pos->GetTypeOfPosition() ) {
4206 aNodePosition->shapeType = GEOM::EDGE;
4207 aNodePosition->params.length(1);
4208 aNodePosition->params[0] =
4209 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4212 aNodePosition->shapeType = GEOM::FACE;
4213 aNodePosition->params.length(2);
4214 aNodePosition->params[0] =
4215 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4216 aNodePosition->params[1] =
4217 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4219 case SMDS_TOP_VERTEX:
4220 aNodePosition->shapeType = GEOM::VERTEX;
4222 case SMDS_TOP_3DSPACE:
4223 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4224 aNodePosition->shapeType = GEOM::SOLID;
4225 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4226 aNodePosition->shapeType = GEOM::SHELL;
4232 return aNodePosition;
4235 //=============================================================================
4237 * \brief Return position of an element on shape
4239 //=============================================================================
4241 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4244 _preMeshInfo->FullLoadFromFile();
4246 SMESH::ElementPosition anElementPosition;
4247 anElementPosition.shapeID = 0;
4248 anElementPosition.shapeType = GEOM::SHAPE;
4250 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4251 if ( !mesh ) return anElementPosition;
4253 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4255 anElementPosition.shapeID = anElem->getshapeId();
4256 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4257 if ( !aSp.IsNull() ) {
4258 switch ( aSp.ShapeType() ) {
4260 anElementPosition.shapeType = GEOM::EDGE;
4263 anElementPosition.shapeType = GEOM::FACE;
4266 anElementPosition.shapeType = GEOM::VERTEX;
4269 anElementPosition.shapeType = GEOM::SOLID;
4272 anElementPosition.shapeType = GEOM::SHELL;
4278 return anElementPosition;
4281 //=============================================================================
4283 * If given element is node returns IDs of shape from position
4284 * If there is not node for given ID - returns -1
4286 //=============================================================================
4288 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4291 _preMeshInfo->FullLoadFromFile();
4293 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4294 if ( aSMESHDS_Mesh == NULL )
4298 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4300 return aNode->getshapeId();
4307 //=============================================================================
4309 * For given element returns ID of result shape after
4310 * ::FindShape() from SMESH_MeshEditor
4311 * If there is not element for given ID - returns -1
4313 //=============================================================================
4315 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4318 _preMeshInfo->FullLoadFromFile();
4320 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4321 if ( aSMESHDS_Mesh == NULL )
4324 // try to find element
4325 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4329 ::SMESH_MeshEditor aMeshEditor(_impl);
4330 int index = aMeshEditor.FindShape( elem );
4338 //=============================================================================
4340 * Returns number of nodes for given element
4341 * If there is not element for given ID - returns -1
4343 //=============================================================================
4345 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4348 _preMeshInfo->FullLoadFromFile();
4350 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4351 if ( aSMESHDS_Mesh == NULL ) return -1;
4352 // try to find element
4353 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4354 if(!elem) return -1;
4355 return elem->NbNodes();
4359 //=============================================================================
4361 * Returns ID of node by given index for given element
4362 * If there is not element for given ID - returns -1
4363 * If there is not node for given index - returns -2
4365 //=============================================================================
4367 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4370 _preMeshInfo->FullLoadFromFile();
4372 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4373 if ( aSMESHDS_Mesh == NULL ) return -1;
4374 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4375 if(!elem) return -1;
4376 if( index>=elem->NbNodes() || index<0 ) return -1;
4377 return elem->GetNode(index)->GetID();
4380 //=============================================================================
4382 * Returns IDs of nodes of given element
4384 //=============================================================================
4386 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4389 _preMeshInfo->FullLoadFromFile();
4391 SMESH::long_array_var aResult = new SMESH::long_array();
4392 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4394 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4396 aResult->length( elem->NbNodes() );
4397 for ( int i = 0; i < elem->NbNodes(); ++i )
4398 aResult[ i ] = elem->GetNode( i )->GetID();
4401 return aResult._retn();
4404 //=============================================================================
4406 * Returns true if given node is medium node
4407 * in given quadratic element
4409 //=============================================================================
4411 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4414 _preMeshInfo->FullLoadFromFile();
4416 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4417 if ( aSMESHDS_Mesh == NULL ) return false;
4419 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4420 if(!aNode) return false;
4421 // try to find element
4422 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4423 if(!elem) return false;
4425 return elem->IsMediumNode(aNode);
4429 //=============================================================================
4431 * Returns true if given node is medium node
4432 * in one of quadratic elements
4434 //=============================================================================
4436 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4437 SMESH::ElementType theElemType)
4440 _preMeshInfo->FullLoadFromFile();
4442 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4443 if ( aSMESHDS_Mesh == NULL ) return false;
4446 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4447 if(!aNode) return false;
4449 SMESH_MesherHelper aHelper( *(_impl) );
4451 SMDSAbs_ElementType aType;
4452 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4453 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4454 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4455 else aType = SMDSAbs_All;
4457 return aHelper.IsMedium(aNode,aType);
4461 //=============================================================================
4463 * Returns number of edges for given element
4465 //=============================================================================
4467 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4470 _preMeshInfo->FullLoadFromFile();
4472 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4473 if ( aSMESHDS_Mesh == NULL ) return -1;
4474 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4475 if(!elem) return -1;
4476 return elem->NbEdges();
4480 //=============================================================================
4482 * Returns number of faces for given element
4484 //=============================================================================
4486 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4489 _preMeshInfo->FullLoadFromFile();
4491 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4492 if ( aSMESHDS_Mesh == NULL ) return -1;
4493 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4494 if(!elem) return -1;
4495 return elem->NbFaces();
4498 //=======================================================================
4499 //function : GetElemFaceNodes
4500 //purpose : Returns nodes of given face (counted from zero) for given element.
4501 //=======================================================================
4503 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4504 CORBA::Short faceIndex)
4507 _preMeshInfo->FullLoadFromFile();
4509 SMESH::long_array_var aResult = new SMESH::long_array();
4510 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4512 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4514 SMDS_VolumeTool vtool( elem );
4515 if ( faceIndex < vtool.NbFaces() )
4517 aResult->length( vtool.NbFaceNodes( faceIndex ));
4518 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4519 for ( int i = 0; i < aResult->length(); ++i )
4520 aResult[ i ] = nn[ i ]->GetID();
4524 return aResult._retn();
4527 //=======================================================================
4528 //function : GetElemFaceNodes
4529 //purpose : Returns three components of normal of given mesh face.
4530 //=======================================================================
4532 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4533 CORBA::Boolean normalized)
4536 _preMeshInfo->FullLoadFromFile();
4538 SMESH::double_array_var aResult = new SMESH::double_array();
4540 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4543 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4545 aResult->length( 3 );
4546 aResult[ 0 ] = normal.X();
4547 aResult[ 1 ] = normal.Y();
4548 aResult[ 2 ] = normal.Z();
4551 return aResult._retn();
4554 //=======================================================================
4555 //function : FindElementByNodes
4556 //purpose : Returns an element based on all given nodes.
4557 //=======================================================================
4559 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4562 _preMeshInfo->FullLoadFromFile();
4564 CORBA::Long elemID(0);
4565 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4567 vector< const SMDS_MeshNode * > nn( nodes.length() );
4568 for ( int i = 0; i < nodes.length(); ++i )
4569 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4572 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4573 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4574 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4575 _impl->NbVolumes( ORDER_QUADRATIC )))
4576 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4578 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4583 //=============================================================================
4585 * Returns true if given element is polygon
4587 //=============================================================================
4589 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4592 _preMeshInfo->FullLoadFromFile();
4594 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4595 if ( aSMESHDS_Mesh == NULL ) return false;
4596 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4597 if(!elem) return false;
4598 return elem->IsPoly();
4602 //=============================================================================
4604 * Returns true if given element is quadratic
4606 //=============================================================================
4608 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4611 _preMeshInfo->FullLoadFromFile();
4613 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4614 if ( aSMESHDS_Mesh == NULL ) return false;
4615 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4616 if(!elem) return false;
4617 return elem->IsQuadratic();
4620 //=============================================================================
4622 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4624 //=============================================================================
4626 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4629 _preMeshInfo->FullLoadFromFile();
4631 if ( const SMDS_BallElement* ball =
4632 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4633 return ball->GetDiameter();
4638 //=============================================================================
4640 * Returns bary center for given element
4642 //=============================================================================
4644 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4647 _preMeshInfo->FullLoadFromFile();
4649 SMESH::double_array_var aResult = new SMESH::double_array();
4650 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4651 if ( aSMESHDS_Mesh == NULL )
4652 return aResult._retn();
4654 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4656 return aResult._retn();
4658 if(elem->GetType()==SMDSAbs_Volume) {
4659 SMDS_VolumeTool aTool;
4660 if(aTool.Set(elem)) {
4662 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4667 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4669 double x=0., y=0., z=0.;
4670 for(; anIt->more(); ) {
4672 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4686 return aResult._retn();
4689 //================================================================================
4691 * \brief Create a group of elements preventing computation of a sub-shape
4693 //================================================================================
4695 SMESH::ListOfGroups*
4696 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4697 const char* theGroupName )
4698 throw ( SALOME::SALOME_Exception )
4700 Unexpect aCatch(SALOME_SalomeException);
4702 if ( !theGroupName || strlen( theGroupName) == 0 )
4703 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4705 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4707 // submesh by subshape id
4708 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4709 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4712 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4713 if ( error && !error->myBadElements.empty())
4715 // sort bad elements by type
4716 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4717 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4718 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4719 for ( ; elemIt != elemEnd; ++elemIt )
4721 const SMDS_MeshElement* elem = *elemIt;
4722 if ( !elem ) continue;
4724 if ( elem->GetID() < 1 )
4726 // elem is a temporary element, make a real element
4727 vector< const SMDS_MeshNode* > nodes;
4728 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4729 while ( nIt->more() && elem )
4731 nodes.push_back( nIt->next() );
4732 if ( nodes.back()->GetID() < 1 )
4733 elem = 0; // a temporary element on temporary nodes
4737 ::SMESH_MeshEditor editor( _impl );
4738 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4742 elemsByType[ elem->GetType() ].push_back( elem );
4745 // how many groups to create?
4747 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4748 nbTypes += int( !elemsByType[ i ].empty() );
4749 groups->length( nbTypes );
4752 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4754 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4755 if ( elems.empty() ) continue;
4757 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4758 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4760 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4761 SMESH::SMESH_Mesh_var mesh = _this();
4762 SALOMEDS::SObject_wrap aSO =
4763 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4764 GEOM::GEOM_Object::_nil(), theGroupName);
4765 aSO->_is_nil(); // avoid "unused variable" warning
4767 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4768 if ( !grp_i ) continue;
4770 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4771 for ( size_t iE = 0; iE < elems.size(); ++iE )
4772 grpDS->SMDSGroup().Add( elems[ iE ]);
4777 return groups._retn();
4780 //=============================================================================
4782 * Create and publish group servants if any groups were imported or created anyhow
4784 //=============================================================================
4786 void SMESH_Mesh_i::CreateGroupServants()
4788 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4789 SMESH::SMESH_Mesh_var aMesh = _this();
4792 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4793 while ( groupIt->more() )
4795 ::SMESH_Group* group = groupIt->next();
4796 int anId = group->GetGroupDS()->GetID();
4798 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4799 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4801 addedIDs.insert( anId );
4803 SMESH_GroupBase_i* aGroupImpl;
4805 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4806 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4808 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4809 shape = groupOnGeom->GetShape();
4812 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4815 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4816 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4817 aGroupImpl->Register();
4819 // register CORBA object for persistence
4820 int nextId = _gen_i->RegisterObject( groupVar );
4821 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4822 else { nextId = 0; } // avoid "unused variable" warning in release mode
4824 // publishing the groups in the study
4825 if ( !aStudy->_is_nil() ) {
4826 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4827 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4830 if ( !addedIDs.empty() )
4833 set<int>::iterator id = addedIDs.begin();
4834 for ( ; id != addedIDs.end(); ++id )
4836 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4837 int i = std::distance( _mapGroups.begin(), it );
4838 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4843 //=============================================================================
4845 * \brief Return groups cantained in _mapGroups by their IDs
4847 //=============================================================================
4849 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4851 int nbGroups = groupIDs.size();
4852 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4853 aList->length( nbGroups );
4855 list<int>::const_iterator ids = groupIDs.begin();
4856 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4858 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4859 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4860 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4862 aList->length( nbGroups );
4863 return aList._retn();
4866 //=============================================================================
4868 * \brief Return information about imported file
4870 //=============================================================================
4872 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4874 SMESH::MedFileInfo_var res( _medFileInfo );
4875 if ( !res.operator->() ) {
4876 res = new SMESH::MedFileInfo;
4878 res->fileSize = res->major = res->minor = res->release = -1;
4883 //=============================================================================
4885 * \brief Pass names of mesh groups from study to mesh DS
4887 //=============================================================================
4889 void SMESH_Mesh_i::checkGroupNames()
4891 int nbGrp = NbGroups();
4895 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4896 if ( aStudy->_is_nil() )
4897 return; // nothing to do
4899 SMESH::ListOfGroups* grpList = 0;
4900 // avoid dump of "GetGroups"
4902 // store python dump into a local variable inside local scope
4903 SMESH::TPythonDump pDump; // do not delete this line of code
4904 grpList = GetGroups();
4907 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4908 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4911 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4912 if ( aGrpSO->_is_nil() )
4914 // correct name of the mesh group if necessary
4915 const char* guiName = aGrpSO->GetName();
4916 if ( strcmp(guiName, aGrp->GetName()) )
4917 aGrp->SetName( guiName );
4921 //=============================================================================
4923 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4925 //=============================================================================
4926 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4928 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4932 //=============================================================================
4934 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4936 //=============================================================================
4938 char* SMESH_Mesh_i::GetParameters()
4940 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4943 //=============================================================================
4945 * \brief Returns list of notebook variables used for last Mesh operation
4947 //=============================================================================
4948 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4950 SMESH::string_array_var aResult = new SMESH::string_array();
4951 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4953 CORBA::String_var aParameters = GetParameters();
4954 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4955 if ( !aStudy->_is_nil()) {
4956 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4957 if(aSections->length() > 0) {
4958 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4959 aResult->length(aVars.length());
4960 for(int i = 0;i < aVars.length();i++)
4961 aResult[i] = CORBA::string_dup( aVars[i]);
4965 return aResult._retn();
4968 //=======================================================================
4969 //function : GetTypes
4970 //purpose : Returns types of elements it contains
4971 //=======================================================================
4973 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4976 return _preMeshInfo->GetTypes();
4978 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4982 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4983 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4984 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4985 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4986 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4987 types->length( nbTypes );
4989 return types._retn();
4992 //=======================================================================
4993 //function : GetMesh
4994 //purpose : Returns self
4995 //=======================================================================
4997 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4999 return SMESH::SMESH_Mesh::_duplicate( _this() );
5002 //=======================================================================
5003 //function : IsMeshInfoCorrect
5004 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5005 // * happen if mesh data is not yet fully loaded from the file of study.
5006 //=======================================================================
5008 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5010 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5013 //=============================================================================
5015 * \brief Returns number of mesh elements per each \a EntityType
5017 //=============================================================================
5019 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5022 return _preMeshInfo->GetMeshInfo();
5024 SMESH::long_array_var aRes = new SMESH::long_array();
5025 aRes->length(SMESH::Entity_Last);
5026 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5028 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5030 return aRes._retn();
5031 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5032 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5033 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5034 return aRes._retn();
5037 //=============================================================================
5039 * \brief Returns number of mesh elements per each \a ElementType
5041 //=============================================================================
5043 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5045 SMESH::long_array_var aRes = new SMESH::long_array();
5046 aRes->length(SMESH::NB_ELEMENT_TYPES);
5047 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5050 const SMDS_MeshInfo* meshInfo = 0;
5052 meshInfo = _preMeshInfo;
5053 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5054 meshInfo = & meshDS->GetMeshInfo();
5057 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5058 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5060 return aRes._retn();
5063 //=============================================================================
5065 * Collect statistic of mesh elements given by iterator
5067 //=============================================================================
5069 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5070 SMESH::long_array& theInfo)
5072 if (!theItr) return;
5073 while (theItr->more())
5074 theInfo[ theItr->next()->GetEntityType() ]++;
5077 //=============================================================================
5078 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5079 * SMESH::ElementType type) */
5081 using namespace SMESH::Controls;
5082 //-----------------------------------------------------------------------------
5083 struct PredicateIterator : public SMDS_ElemIterator
5085 SMDS_ElemIteratorPtr _elemIter;
5086 PredicatePtr _predicate;
5087 const SMDS_MeshElement* _elem;
5089 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5090 PredicatePtr predicate):
5091 _elemIter(iterator), _predicate(predicate)
5099 virtual const SMDS_MeshElement* next()
5101 const SMDS_MeshElement* res = _elem;
5103 while ( _elemIter->more() && !_elem )
5105 _elem = _elemIter->next();
5106 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5113 //-----------------------------------------------------------------------------
5114 struct IDSourceIterator : public SMDS_ElemIterator
5116 const CORBA::Long* _idPtr;
5117 const CORBA::Long* _idEndPtr;
5118 SMESH::long_array_var _idArray;
5119 const SMDS_Mesh* _mesh;
5120 const SMDSAbs_ElementType _type;
5121 const SMDS_MeshElement* _elem;
5123 IDSourceIterator( const SMDS_Mesh* mesh,
5124 const CORBA::Long* ids,
5126 SMDSAbs_ElementType type):
5127 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5129 if ( _idPtr && nbIds && _mesh )
5132 IDSourceIterator( const SMDS_Mesh* mesh,
5133 SMESH::long_array* idArray,
5134 SMDSAbs_ElementType type):
5135 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5137 if ( idArray && _mesh )
5139 _idPtr = &_idArray[0];
5140 _idEndPtr = _idPtr + _idArray->length();
5148 virtual const SMDS_MeshElement* next()
5150 const SMDS_MeshElement* res = _elem;
5152 while ( _idPtr < _idEndPtr && !_elem )
5154 if ( _type == SMDSAbs_Node )
5156 _elem = _mesh->FindNode( *_idPtr++ );
5158 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5159 _elem->GetType() != _type )
5167 //-----------------------------------------------------------------------------
5169 struct NodeOfElemIterator : public SMDS_ElemIterator
5171 TColStd_MapOfInteger _checkedNodeIDs;
5172 SMDS_ElemIteratorPtr _elemIter;
5173 SMDS_ElemIteratorPtr _nodeIter;
5174 const SMDS_MeshElement* _node;
5176 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5178 if ( _elemIter && _elemIter->more() )
5180 _nodeIter = _elemIter->next()->nodesIterator();
5188 virtual const SMDS_MeshElement* next()
5190 const SMDS_MeshElement* res = _node;
5192 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5194 if ( _nodeIter->more() )
5196 _node = _nodeIter->next();
5197 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5202 _nodeIter = _elemIter->next()->nodesIterator();
5210 //=============================================================================
5212 * Return iterator on elements of given type in given object
5214 //=============================================================================
5216 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5217 SMESH::ElementType theType)
5219 SMDS_ElemIteratorPtr elemIt;
5220 bool typeOK = false;
5221 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5223 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5224 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5225 if ( !mesh_i ) return elemIt;
5226 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5228 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5230 elemIt = meshDS->elementsIterator( elemType );
5233 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5235 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5238 elemIt = sm->GetElements();
5239 if ( elemType != SMDSAbs_Node )
5241 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5242 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5246 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5248 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5249 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5251 elemIt = groupDS->GetElements();
5252 typeOK = ( groupDS->GetType() == elemType );
5255 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5257 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5259 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5260 if ( pred_i && pred_i->GetPredicate() )
5262 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5263 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5264 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5265 typeOK = ( filterType == elemType );
5271 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5272 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5273 if ( isNodes && elemType != SMDSAbs_Node )
5275 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5278 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5279 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5283 SMESH::long_array_var ids = theObject->GetIDs();
5284 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5286 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5289 if ( elemIt && elemIt->more() && !typeOK )
5291 if ( elemType == SMDSAbs_Node )
5293 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5297 elemIt = SMDS_ElemIteratorPtr();
5303 //=============================================================================
5304 namespace // Finding concurrent hypotheses
5305 //=============================================================================
5309 * \brief mapping of mesh dimension into shape type
5311 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5313 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5315 case 0: aType = TopAbs_VERTEX; break;
5316 case 1: aType = TopAbs_EDGE; break;
5317 case 2: aType = TopAbs_FACE; break;
5319 default:aType = TopAbs_SOLID; break;
5324 //-----------------------------------------------------------------------------
5326 * \brief Internal structure used to find concurent submeshes
5328 * It represents a pair < submesh, concurent dimension >, where
5329 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5330 * with another submesh. In other words, it is dimension of a hypothesis assigned
5337 int _dim; //!< a dimension the algo can build (concurrent dimension)
5338 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5339 TopTools_MapOfShape _shapeMap;
5340 SMESH_subMesh* _subMesh;
5341 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5343 //-----------------------------------------------------------------------------
5344 // Return the algorithm
5345 const SMESH_Algo* GetAlgo() const
5346 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5348 //-----------------------------------------------------------------------------
5350 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5352 const TopoDS_Shape& theShape)
5354 _subMesh = (SMESH_subMesh*)theSubMesh;
5355 SetShape( theDim, theShape );
5358 //-----------------------------------------------------------------------------
5360 void SetShape(const int theDim,
5361 const TopoDS_Shape& theShape)
5364 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5365 if (_dim >= _ownDim)
5366 _shapeMap.Add( theShape );
5368 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5369 for( ; anExp.More(); anExp.Next() )
5370 _shapeMap.Add( anExp.Current() );
5374 //-----------------------------------------------------------------------------
5375 //! Check sharing of sub-shapes
5376 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5377 const TopTools_MapOfShape& theToFind,
5378 const TopAbs_ShapeEnum theType)
5380 bool isShared = false;
5381 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5382 for (; !isShared && anItr.More(); anItr.Next() )
5384 const TopoDS_Shape aSubSh = anItr.Key();
5385 // check for case when concurrent dimensions are same
5386 isShared = theToFind.Contains( aSubSh );
5387 // check for sub-shape with concurrent dimension
5388 TopExp_Explorer anExp( aSubSh, theType );
5389 for ( ; !isShared && anExp.More(); anExp.Next() )
5390 isShared = theToFind.Contains( anExp.Current() );
5395 //-----------------------------------------------------------------------------
5396 //! check algorithms
5397 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5398 const SMESHDS_Hypothesis* theA2)
5400 if ( !theA1 || !theA2 ||
5401 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5402 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5403 return false; // one of the hypothesis is not algorithm
5404 // check algorithm names (should be equal)
5405 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5409 //-----------------------------------------------------------------------------
5410 //! Check if sub-shape hypotheses are concurrent
5411 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5413 if ( _subMesh == theOther->_subMesh )
5414 return false; // same sub-shape - should not be
5416 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5417 // any of the two submeshes is not on COMPOUND shape )
5418 // -> no concurrency
5419 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5420 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5421 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5422 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5423 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5426 // bool checkSubShape = ( _dim >= theOther->_dim )
5427 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5428 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5429 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5430 if ( !checkSubShape )
5433 // check algorithms to be same
5434 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5435 return true; // different algorithms -> concurrency !
5437 // check hypothesises for concurrence (skip first as algorithm)
5439 // pointers should be same, because it is referened from mesh hypothesis partition
5440 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5441 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5442 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5443 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5445 // the submeshes are concurrent if their algorithms has different parameters
5446 return nbSame != theOther->_hypotheses.size() - 1;
5449 // Return true if algorithm of this SMESH_DimHyp is used if no
5450 // sub-mesh order is imposed by the user
5451 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5453 // NeedDiscreteBoundary() algo has a higher priority
5454 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5455 theOther->GetAlgo()->NeedDiscreteBoundary() )
5456 return !this->GetAlgo()->NeedDiscreteBoundary();
5458 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5461 }; // end of SMESH_DimHyp
5462 //-----------------------------------------------------------------------------
5464 typedef list<const SMESH_DimHyp*> TDimHypList;
5466 //-----------------------------------------------------------------------------
5468 void addDimHypInstance(const int theDim,
5469 const TopoDS_Shape& theShape,
5470 const SMESH_Algo* theAlgo,
5471 const SMESH_subMesh* theSubMesh,
5472 const list <const SMESHDS_Hypothesis*>& theHypList,
5473 TDimHypList* theDimHypListArr )
5475 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5476 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5477 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5478 dimHyp->_hypotheses.push_front(theAlgo);
5479 listOfdimHyp.push_back( dimHyp );
5482 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5483 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5484 theHypList.begin(), theHypList.end() );
5487 //-----------------------------------------------------------------------------
5488 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5489 TDimHypList& theListOfConcurr)
5491 if ( theListOfConcurr.empty() )
5493 theListOfConcurr.push_back( theDimHyp );
5497 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5498 while ( hypIt != theListOfConcurr.end() &&
5499 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5501 theListOfConcurr.insert( hypIt, theDimHyp );
5505 //-----------------------------------------------------------------------------
5506 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5507 const TDimHypList& theListOfDimHyp,
5508 TDimHypList& theListOfConcurrHyp,
5509 set<int>& theSetOfConcurrId )
5511 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5512 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5514 const SMESH_DimHyp* curDimHyp = *rIt;
5515 if ( curDimHyp == theDimHyp )
5516 break; // meet own dimHyp pointer in same dimension
5518 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5519 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5521 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5526 //-----------------------------------------------------------------------------
5527 void unionLists(TListOfInt& theListOfId,
5528 TListOfListOfInt& theListOfListOfId,
5531 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5532 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5534 continue; //skip already treated lists
5535 // check if other list has any same submesh object
5536 TListOfInt& otherListOfId = *it;
5537 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5538 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5541 // union two lists (from source into target)
5542 TListOfInt::iterator it2 = otherListOfId.begin();
5543 for ( ; it2 != otherListOfId.end(); it2++ ) {
5544 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5545 theListOfId.push_back(*it2);
5547 // clear source list
5548 otherListOfId.clear();
5551 //-----------------------------------------------------------------------------
5553 //! free memory allocated for dimension-hypothesis objects
5554 void removeDimHyps( TDimHypList* theArrOfList )
5556 for (int i = 0; i < 4; i++ ) {
5557 TDimHypList& listOfdimHyp = theArrOfList[i];
5558 TDimHypList::const_iterator it = listOfdimHyp.begin();
5559 for ( ; it != listOfdimHyp.end(); it++ )
5564 //-----------------------------------------------------------------------------
5566 * \brief find common submeshes with given submesh
5567 * \param theSubMeshList list of already collected submesh to check
5568 * \param theSubMesh given submesh to intersect with other
5569 * \param theCommonSubMeshes collected common submeshes
5571 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5572 const SMESH_subMesh* theSubMesh,
5573 set<const SMESH_subMesh*>& theCommon )
5577 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5578 for ( ; it != theSubMeshList.end(); it++ )
5579 theSubMesh->FindIntersection( *it, theCommon );
5580 theSubMeshList.push_back( theSubMesh );
5581 //theCommon.insert( theSubMesh );
5584 //-----------------------------------------------------------------------------
5585 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5587 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5588 for ( ; listsIt != smLists.end(); ++listsIt )
5590 const TListOfInt& smIDs = *listsIt;
5591 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5599 //=============================================================================
5601 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5603 //=============================================================================
5605 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5607 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5608 if ( isSubMeshInList( submeshID, anOrder ))
5611 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5612 return isSubMeshInList( submeshID, allConurrent );
5615 //=============================================================================
5617 * \brief Return submesh objects list in meshing order
5619 //=============================================================================
5621 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5623 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5625 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5627 return aResult._retn();
5629 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5630 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5631 anOrder.splice( anOrder.end(), allConurrent );
5634 TListOfListOfInt::iterator listIt = anOrder.begin();
5635 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5636 unionLists( *listIt, anOrder, listIndx + 1 );
5638 // convert submesh ids into interface instances
5639 // and dump command into python
5640 convertMeshOrder( anOrder, aResult, false );
5642 return aResult._retn();
5645 //=============================================================================
5647 * \brief Finds concurrent sub-meshes
5649 //=============================================================================
5651 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5653 TListOfListOfInt anOrder;
5654 ::SMESH_Mesh& mesh = GetImpl();
5656 // collect submeshes and detect concurrent algorithms and hypothesises
5657 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5659 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5660 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5661 ::SMESH_subMesh* sm = (*i_sm).second;
5663 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5665 // list of assigned hypothesises
5666 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5667 // Find out dimensions where the submesh can be concurrent.
5668 // We define the dimensions by algo of each of hypotheses in hypList
5669 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5670 for( ; hypIt != hypList.end(); hypIt++ ) {
5671 SMESH_Algo* anAlgo = 0;
5672 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5673 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5674 // hyp it-self is algo
5675 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5677 // try to find algorithm with help of sub-shapes
5678 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5679 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5680 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5683 continue; // no algorithm assigned to a current submesh
5685 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5686 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5688 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5689 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5690 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5692 } // end iterations on submesh
5694 // iterate on created dimension-hypotheses and check for concurrents
5695 for ( int i = 0; i < 4; i++ ) {
5696 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5697 // check for concurrents in own and other dimensions (step-by-step)
5698 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5699 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5700 const SMESH_DimHyp* dimHyp = *dhIt;
5701 TDimHypList listOfConcurr;
5702 set<int> setOfConcurrIds;
5703 // looking for concurrents and collect into own list
5704 for ( int j = i; j < 4; j++ )
5705 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5706 // check if any concurrents found
5707 if ( listOfConcurr.size() > 0 ) {
5708 // add own submesh to list of concurrent
5709 addInOrderOfPriority( dimHyp, listOfConcurr );
5710 list<int> listOfConcurrIds;
5711 TDimHypList::iterator hypIt = listOfConcurr.begin();
5712 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5713 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5714 anOrder.push_back( listOfConcurrIds );
5719 removeDimHyps(dimHypListArr);
5721 // now, minimise the number of concurrent groups
5722 // Here we assume that lists of submeshes can have same submesh
5723 // in case of multi-dimension algorithms, as result
5724 // list with common submesh has to be united into one list
5726 TListOfListOfInt::iterator listIt = anOrder.begin();
5727 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5728 unionLists( *listIt, anOrder, listIndx + 1 );
5734 //=============================================================================
5736 * \brief Set submesh object order
5737 * \param theSubMeshArray submesh array order
5739 //=============================================================================
5741 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5744 _preMeshInfo->ForgetOrLoad();
5747 ::SMESH_Mesh& mesh = GetImpl();
5749 TPythonDump aPythonDump; // prevent dump of called methods
5750 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5752 TListOfListOfInt subMeshOrder;
5753 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5755 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5756 TListOfInt subMeshIds;
5757 aPythonDump << "[ ";
5758 // Collect subMeshes which should be clear
5759 // do it list-by-list, because modification of submesh order
5760 // take effect between concurrent submeshes only
5761 set<const SMESH_subMesh*> subMeshToClear;
5762 list<const SMESH_subMesh*> subMeshList;
5763 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5765 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5767 aPythonDump << ", ";
5768 aPythonDump << subMesh;
5769 subMeshIds.push_back( subMesh->GetId() );
5770 // detect common parts of submeshes
5771 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5772 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5774 aPythonDump << " ]";
5775 subMeshOrder.push_back( subMeshIds );
5777 // clear collected submeshes
5778 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5779 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5780 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5781 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5783 aPythonDump << " ])";
5785 mesh.SetMeshOrder( subMeshOrder );
5791 //=============================================================================
5793 * \brief Convert submesh ids into submesh interfaces
5795 //=============================================================================
5797 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5798 SMESH::submesh_array_array& theResOrder,
5799 const bool theIsDump)
5801 int nbSet = theIdsOrder.size();
5802 TPythonDump aPythonDump; // prevent dump of called methods
5804 aPythonDump << "[ ";
5805 theResOrder.length(nbSet);
5806 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5808 for( ; it != theIdsOrder.end(); it++ ) {
5809 // translate submesh identificators into submesh objects
5810 // takeing into account real number of concurrent lists
5811 const TListOfInt& aSubOrder = (*it);
5812 if (!aSubOrder.size())
5815 aPythonDump << "[ ";
5816 // convert shape indeces into interfaces
5817 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5818 aResSubSet->length(aSubOrder.size());
5819 TListOfInt::const_iterator subIt = aSubOrder.begin();
5821 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5822 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5824 SMESH::SMESH_subMesh_var subMesh =
5825 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5828 aPythonDump << ", ";
5829 aPythonDump << subMesh;
5831 aResSubSet[ j++ ] = subMesh;
5834 aPythonDump << " ]";
5836 theResOrder[ listIndx++ ] = aResSubSet;
5838 // correct number of lists
5839 theResOrder.length( listIndx );
5842 // finilise python dump
5843 aPythonDump << " ]";
5844 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5848 //================================================================================
5850 // Implementation of SMESH_MeshPartDS
5852 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5853 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5855 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5856 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5858 _meshDS = mesh_i->GetImpl().GetMeshDS();
5860 SetPersistentId( _meshDS->GetPersistentId() );
5862 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5864 // <meshPart> is the whole mesh
5865 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5867 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5868 myGroupSet = _meshDS->GetGroups();
5873 SMESH::long_array_var anIDs = meshPart->GetIDs();
5874 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5875 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5877 for (int i=0; i < anIDs->length(); i++)
5878 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5879 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5884 for (int i=0; i < anIDs->length(); i++)
5885 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5886 if ( _elements[ e->GetType() ].insert( e ).second )
5889 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5890 while ( nIt->more() )
5892 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5893 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5900 _meshDS = 0; // to enforce iteration on _elements and _nodes
5903 // -------------------------------------------------------------------------------------
5904 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5905 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5908 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5909 for ( ; partIt != meshPart.end(); ++partIt )
5910 if ( const SMDS_MeshElement * e = *partIt )
5911 if ( _elements[ e->GetType() ].insert( e ).second )
5914 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5915 while ( nIt->more() )
5917 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5918 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5924 // -------------------------------------------------------------------------------------
5925 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5927 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5929 typedef SMDS_SetIterator
5930 <const SMDS_MeshElement*,
5931 TIDSortedElemSet::const_iterator,
5932 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5933 SMDS_MeshElement::GeomFilter
5936 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5938 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5939 _elements[type].end(),
5940 SMDS_MeshElement::GeomFilter( geomType )));
5942 // -------------------------------------------------------------------------------------
5943 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5945 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5947 typedef SMDS_SetIterator
5948 <const SMDS_MeshElement*,
5949 TIDSortedElemSet::const_iterator,
5950 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5951 SMDS_MeshElement::EntityFilter
5954 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5956 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5957 _elements[type].end(),
5958 SMDS_MeshElement::EntityFilter( entity )));
5960 // -------------------------------------------------------------------------------------
5961 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5963 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5964 if ( type == SMDSAbs_All && !_meshDS )
5966 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5968 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5969 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5971 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5973 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5974 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5976 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5977 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5979 // -------------------------------------------------------------------------------------
5980 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5981 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5983 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5984 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5985 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
5987 // -------------------------------------------------------------------------------------
5988 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
5989 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
5990 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
5991 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
5992 #undef _GET_ITER_DEFINE
5994 // END Implementation of SMESH_MeshPartDS
5996 //================================================================================