1 // Copyright (C) 2007-2015 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_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cashed shapes if no more meshes remain; (the cash is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
236 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 if ( aShapeObj->_is_nil() )
239 // S was removed from GEOM_Client by newGroupShape() called by other mesh;
240 // find GEOM_Object by entry (IPAL52735)
241 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
242 for ( ; data != _geomGroupData.end(); ++data )
243 if ( data->_smeshObject->_is_equivalent( _this() ))
245 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
246 if ( study->_is_nil() ) break;
247 SALOMEDS::SObject_wrap so = study->FindObjectID( data->_groupEntry.c_str() );
248 CORBA::Object_var obj = _gen_i->SObjectToObject( so );
249 aShapeObj = GEOM::GEOM_Object::_narrow( obj );
255 catch(SALOME_Exception & S_ex) {
256 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
258 return aShapeObj._retn();
261 //================================================================================
263 * \brief Return false if the mesh is not yet fully loaded from the study file
265 //================================================================================
267 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
269 Unexpect aCatch(SALOME_SalomeException);
270 return !_preMeshInfo;
273 //================================================================================
275 * \brief Load full mesh data from the study file
277 //================================================================================
279 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
281 Unexpect aCatch(SALOME_SalomeException);
283 _preMeshInfo->FullLoadFromFile();
286 //================================================================================
288 * \brief Remove all nodes and elements
290 //================================================================================
292 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
294 Unexpect aCatch(SALOME_SalomeException);
296 _preMeshInfo->ForgetAllData();
300 //CheckGeomGroupModif(); // issue 20145
302 catch(SALOME_Exception & S_ex) {
303 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
305 _impl->GetMeshDS()->Modified();
307 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
310 //================================================================================
312 * \brief Remove all nodes and elements for indicated shape
314 //================================================================================
316 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
317 throw (SALOME::SALOME_Exception)
319 Unexpect aCatch(SALOME_SalomeException);
321 _preMeshInfo->FullLoadFromFile();
324 _impl->ClearSubMesh( ShapeID );
326 catch(SALOME_Exception & S_ex) {
327 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
329 _impl->GetMeshDS()->Modified();
331 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
334 //=============================================================================
336 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
338 //=============================================================================
340 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
342 SMESH::DriverMED_ReadStatus res;
345 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
346 res = SMESH::DRS_OK; break;
347 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
348 res = SMESH::DRS_EMPTY; break;
349 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
350 res = SMESH::DRS_WARN_RENUMBER; break;
351 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
352 res = SMESH::DRS_WARN_SKIP_ELEM; break;
353 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
354 res = SMESH::DRS_WARN_DESCENDING; break;
355 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
357 res = SMESH::DRS_FAIL; break;
362 //=============================================================================
364 * Convert ::SMESH_ComputeError to SMESH::ComputeError
366 //=============================================================================
368 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
370 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
371 errVar->subShapeID = -1;
372 errVar->hasBadMesh = false;
374 if ( !errorPtr || errorPtr->IsOK() )
376 errVar->code = SMESH::COMPERR_OK;
380 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
381 errVar->comment = errorPtr->myComment.c_str();
383 return errVar._retn();
386 //=============================================================================
390 * Imports mesh data from MED file
392 //=============================================================================
394 SMESH::DriverMED_ReadStatus
395 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
396 throw ( SALOME::SALOME_Exception )
398 Unexpect aCatch(SALOME_SalomeException);
401 status = _impl->MEDToMesh( theFileName, theMeshName );
403 catch( SALOME_Exception& S_ex ) {
404 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
407 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
410 CreateGroupServants();
412 int major, minor, release;
413 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
414 major = minor = release = -1;
415 _medFileInfo = new SMESH::MedFileInfo();
416 _medFileInfo->fileName = theFileName;
417 _medFileInfo->fileSize = 0;
418 _medFileInfo->major = major;
419 _medFileInfo->minor = minor;
420 _medFileInfo->release = release;
421 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
423 return ConvertDriverMEDReadStatus(status);
426 //================================================================================
428 * \brief Imports mesh data from the CGNS file
430 //================================================================================
432 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
433 const int theMeshIndex,
434 std::string& theMeshName )
435 throw ( SALOME::SALOME_Exception )
437 Unexpect aCatch(SALOME_SalomeException);
440 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
442 catch( SALOME_Exception& S_ex ) {
443 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
446 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
449 CreateGroupServants();
451 return ConvertDriverMEDReadStatus(status);
454 //================================================================================
456 * \brief Return string representation of a MED file version comprising nbDigits
458 //================================================================================
460 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
462 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
464 return CORBA::string_dup( ver.c_str() );
467 //=============================================================================
471 * Imports mesh data from MED file
473 //=============================================================================
475 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
476 throw ( SALOME::SALOME_Exception )
480 // Read mesh with name = <theMeshName> into SMESH_Mesh
481 _impl->UNVToMesh( theFileName );
483 CreateGroupServants();
485 SMESH_CATCH( SMESH::throwCorbaException );
490 //=============================================================================
494 * Imports mesh data from STL file
496 //=============================================================================
497 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
498 throw ( SALOME::SALOME_Exception )
502 // Read mesh with name = <theMeshName> into SMESH_Mesh
503 _impl->STLToMesh( theFileName );
505 SMESH_CATCH( SMESH::throwCorbaException );
510 //================================================================================
512 * \brief Function used in SMESH_CATCH by ImportGMFFile()
514 //================================================================================
518 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
520 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
524 //================================================================================
526 * \brief Imports data from a GMF file and returns an error description
528 //================================================================================
530 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
531 bool theMakeRequiredGroups )
532 throw (SALOME::SALOME_Exception)
534 SMESH_ComputeErrorPtr error;
537 #define SMESH_CAUGHT error =
540 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
542 SMESH_CATCH( exceptionToComputeError );
546 CreateGroupServants();
548 return ConvertComputeError( error );
551 //=============================================================================
555 //=============================================================================
557 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
559 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
560 (SMESH_Hypothesis::Hypothesis_Status theStatus)
563 RETURNCASE( HYP_OK );
564 RETURNCASE( HYP_MISSING );
565 RETURNCASE( HYP_CONCURENT );
566 RETURNCASE( HYP_BAD_PARAMETER );
567 RETURNCASE( HYP_HIDDEN_ALGO );
568 RETURNCASE( HYP_HIDING_ALGO );
569 RETURNCASE( HYP_UNKNOWN_FATAL );
570 RETURNCASE( HYP_INCOMPATIBLE );
571 RETURNCASE( HYP_NOTCONFORM );
572 RETURNCASE( HYP_ALREADY_EXIST );
573 RETURNCASE( HYP_BAD_DIM );
574 RETURNCASE( HYP_BAD_SUBSHAPE );
575 RETURNCASE( HYP_BAD_GEOMETRY );
576 RETURNCASE( HYP_NEED_SHAPE );
577 RETURNCASE( HYP_INCOMPAT_HYPS );
580 return SMESH::HYP_UNKNOWN_FATAL;
583 //=============================================================================
587 * calls internal addHypothesis() and then adds a reference to <anHyp> under
588 * the SObject actually having a reference to <aSubShape>.
589 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
591 //=============================================================================
593 SMESH::Hypothesis_Status
594 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
595 SMESH::SMESH_Hypothesis_ptr anHyp,
596 CORBA::String_out anErrorText)
597 throw(SALOME::SALOME_Exception)
599 Unexpect aCatch(SALOME_SalomeException);
601 _preMeshInfo->ForgetOrLoad();
604 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
605 anErrorText = error.c_str();
607 SMESH::SMESH_Mesh_var mesh( _this() );
608 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
610 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
611 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
613 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
615 // Update Python script
616 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
617 << aSubShape << ", " << anHyp << " )";
619 return ConvertHypothesisStatus(status);
622 //=============================================================================
626 //=============================================================================
628 SMESH_Hypothesis::Hypothesis_Status
629 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
630 SMESH::SMESH_Hypothesis_ptr anHyp,
631 std::string* anErrorText)
633 if(MYDEBUG) MESSAGE("addHypothesis");
635 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
636 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
638 if (CORBA::is_nil( anHyp ))
639 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
641 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
644 TopoDS_Shape myLocSubShape;
645 //use PseudoShape in case if mesh has no shape
647 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
649 myLocSubShape = _impl->GetShapeToMesh();
651 const int hypId = anHyp->GetId();
653 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
654 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
656 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
658 // assure there is a corresponding submesh
659 if ( !_impl->IsMainShape( myLocSubShape )) {
660 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
661 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
662 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
665 else if ( anErrorText )
667 *anErrorText = error;
670 catch(SALOME_Exception & S_ex)
672 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
677 //=============================================================================
681 //=============================================================================
683 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
684 SMESH::SMESH_Hypothesis_ptr anHyp)
685 throw(SALOME::SALOME_Exception)
687 Unexpect aCatch(SALOME_SalomeException);
689 _preMeshInfo->ForgetOrLoad();
691 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
692 SMESH::SMESH_Mesh_var mesh = _this();
694 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
696 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
697 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
699 // Update Python script
700 if(_impl->HasShapeToMesh())
701 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
702 << aSubShape << ", " << anHyp << " )";
704 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
707 return ConvertHypothesisStatus(status);
710 //=============================================================================
714 //=============================================================================
716 SMESH_Hypothesis::Hypothesis_Status
717 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
718 SMESH::SMESH_Hypothesis_ptr anHyp)
720 if(MYDEBUG) MESSAGE("removeHypothesis()");
722 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
723 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
725 if (CORBA::is_nil( anHyp ))
726 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
728 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
731 TopoDS_Shape myLocSubShape;
732 //use PseudoShape in case if mesh has no shape
733 if( _impl->HasShapeToMesh() )
734 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
736 myLocSubShape = _impl->GetShapeToMesh();
738 const int hypId = anHyp->GetId();
739 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
740 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
742 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
746 catch(SALOME_Exception & S_ex)
748 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
753 //=============================================================================
757 //=============================================================================
759 SMESH::ListOfHypothesis *
760 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
761 throw(SALOME::SALOME_Exception)
763 Unexpect aCatch(SALOME_SalomeException);
764 if (MYDEBUG) MESSAGE("GetHypothesisList");
765 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
766 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
768 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
771 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
772 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
773 myLocSubShape = _impl->GetShapeToMesh();
774 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
775 int i = 0, n = aLocalList.size();
778 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
779 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
780 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
782 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
783 if ( id_hypptr != _mapHypo.end() )
784 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
788 catch(SALOME_Exception & S_ex) {
789 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
792 return aList._retn();
795 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
797 Unexpect aCatch(SALOME_SalomeException);
798 if (MYDEBUG) MESSAGE("GetSubMeshes");
800 SMESH::submesh_array_var aList = new SMESH::submesh_array();
803 TPythonDump aPythonDump;
804 if ( !_mapSubMeshIor.empty() )
808 aList->length( _mapSubMeshIor.size() );
810 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
811 for ( ; it != _mapSubMeshIor.end(); it++ ) {
812 if ( CORBA::is_nil( it->second )) continue;
813 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
815 if (i > 1) aPythonDump << ", ";
816 aPythonDump << it->second;
820 catch(SALOME_Exception & S_ex) {
821 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
824 // Update Python script
825 if ( !_mapSubMeshIor.empty() )
826 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
828 return aList._retn();
831 //=============================================================================
835 //=============================================================================
837 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
838 const char* theName )
839 throw(SALOME::SALOME_Exception)
841 Unexpect aCatch(SALOME_SalomeException);
842 if (CORBA::is_nil(aSubShape))
843 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
845 SMESH::SMESH_subMesh_var subMesh;
846 SMESH::SMESH_Mesh_var aMesh = _this();
848 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
850 //Get or Create the SMESH_subMesh object implementation
852 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
854 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
856 TopoDS_Iterator it( myLocSubShape );
858 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
860 subMesh = getSubMesh( subMeshId );
862 // create a new subMesh object servant if there is none for the shape
863 if ( subMesh->_is_nil() )
864 subMesh = createSubMesh( aSubShape );
865 if ( _gen_i->CanPublishInStudy( subMesh ))
867 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
868 SALOMEDS::SObject_wrap aSO =
869 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
870 if ( !aSO->_is_nil()) {
871 // Update Python script
872 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
873 << aSubShape << ", '" << theName << "' )";
877 catch(SALOME_Exception & S_ex) {
878 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
880 return subMesh._retn();
883 //=============================================================================
887 //=============================================================================
889 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
890 throw (SALOME::SALOME_Exception)
894 if ( theSubMesh->_is_nil() )
897 GEOM::GEOM_Object_var aSubShape;
898 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
899 if ( !aStudy->_is_nil() ) {
900 // Remove submesh's SObject
901 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
902 if ( !anSO->_is_nil() ) {
903 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
904 SALOMEDS::SObject_wrap anObj, aRef;
905 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
906 anObj->ReferencedObject( aRef.inout() ))
908 CORBA::Object_var obj = aRef->GetObject();
909 aSubShape = GEOM::GEOM_Object::_narrow( obj );
911 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
912 // aSubShape = theSubMesh->GetSubShape();
914 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
915 builder->RemoveObjectWithChildren( anSO );
917 // Update Python script
918 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
922 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
924 _preMeshInfo->ForgetOrLoad();
926 SMESH_CATCH( SMESH::throwCorbaException );
929 //=============================================================================
933 //=============================================================================
935 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
936 const char* theName )
937 throw(SALOME::SALOME_Exception)
939 Unexpect aCatch(SALOME_SalomeException);
941 _preMeshInfo->FullLoadFromFile();
943 SMESH::SMESH_Group_var aNewGroup =
944 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
946 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
948 SMESH::SMESH_Mesh_var mesh = _this();
949 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
950 SALOMEDS::SObject_wrap aSO =
951 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
952 if ( !aSO->_is_nil())
953 // Update Python script
954 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
955 << theElemType << ", '" << theName << "' )";
957 return aNewGroup._retn();
960 //=============================================================================
964 //=============================================================================
965 SMESH::SMESH_GroupOnGeom_ptr
966 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
968 GEOM::GEOM_Object_ptr theGeomObj)
969 throw(SALOME::SALOME_Exception)
971 Unexpect aCatch(SALOME_SalomeException);
973 _preMeshInfo->FullLoadFromFile();
975 SMESH::SMESH_GroupOnGeom_var aNewGroup;
977 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
978 if ( !aShape.IsNull() )
981 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
983 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
985 SMESH::SMESH_Mesh_var mesh = _this();
986 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
987 SALOMEDS::SObject_wrap aSO =
988 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
989 if ( !aSO->_is_nil())
990 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
991 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
995 return aNewGroup._retn();
998 //================================================================================
1000 * \brief Creates a group whose contents is defined by filter
1001 * \param theElemType - group type
1002 * \param theName - group name
1003 * \param theFilter - the filter
1004 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
1006 //================================================================================
1008 SMESH::SMESH_GroupOnFilter_ptr
1009 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
1010 const char* theName,
1011 SMESH::Filter_ptr theFilter )
1012 throw (SALOME::SALOME_Exception)
1014 Unexpect aCatch(SALOME_SalomeException);
1016 _preMeshInfo->FullLoadFromFile();
1018 if ( CORBA::is_nil( theFilter ))
1019 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1021 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1023 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1025 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1026 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1029 if ( !aNewGroup->_is_nil() )
1030 aNewGroup->SetFilter( theFilter );
1032 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1034 SMESH::SMESH_Mesh_var mesh = _this();
1035 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1036 SALOMEDS::SObject_wrap aSO =
1037 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1039 if ( !aSO->_is_nil())
1040 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1041 << theElemType << ", '" << theName << "', " << theFilter << " )";
1043 return aNewGroup._retn();
1046 //=============================================================================
1050 //=============================================================================
1052 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1053 throw (SALOME::SALOME_Exception)
1055 if ( theGroup->_is_nil() )
1060 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1064 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1065 if ( !aStudy->_is_nil() )
1067 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1068 if ( !aGroupSO->_is_nil() )
1070 // Update Python script
1071 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1073 // Remove group's SObject
1074 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1075 builder->RemoveObjectWithChildren( aGroupSO );
1078 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1080 // Remove the group from SMESH data structures
1081 removeGroup( aGroup->GetLocalID() );
1083 SMESH_CATCH( SMESH::throwCorbaException );
1086 //=============================================================================
1088 * Remove group with its contents
1090 //=============================================================================
1092 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1093 throw (SALOME::SALOME_Exception)
1097 _preMeshInfo->FullLoadFromFile();
1099 if ( theGroup->_is_nil() )
1102 vector<int> nodeIds; // to remove nodes becoming free
1103 if ( !theGroup->IsEmpty() )
1105 CORBA::Long elemID = theGroup->GetID( 1 );
1106 int nbElemNodes = GetElemNbNodes( elemID );
1107 if ( nbElemNodes > 0 )
1108 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1112 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1113 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1114 while ( elemIt->more() )
1116 const SMDS_MeshElement* e = elemIt->next();
1118 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1119 while ( nIt->more() )
1120 nodeIds.push_back( nIt->next()->GetID() );
1122 _impl->GetMeshDS()->RemoveElement( e );
1125 // Remove free nodes
1126 if ( theGroup->GetType() != SMESH::NODE )
1127 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1128 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1129 if ( n->NbInverseElements() == 0 )
1130 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1132 TPythonDump pyDump; // Supress dump from RemoveGroup()
1134 // Update Python script (theGroup must be alive for this)
1135 pyDump << SMESH::SMESH_Mesh_var(_this())
1136 << ".RemoveGroupWithContents( " << theGroup << " )";
1139 RemoveGroup( theGroup );
1141 SMESH_CATCH( SMESH::throwCorbaException );
1144 //================================================================================
1146 * \brief Get the list of groups existing in the mesh
1147 * \retval SMESH::ListOfGroups * - list of groups
1149 //================================================================================
1151 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1153 Unexpect aCatch(SALOME_SalomeException);
1154 if (MYDEBUG) MESSAGE("GetGroups");
1156 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1159 TPythonDump aPythonDump;
1160 if ( !_mapGroups.empty() )
1162 aPythonDump << "[ ";
1164 aList->length( _mapGroups.size() );
1166 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1167 for ( ; it != _mapGroups.end(); it++ ) {
1168 if ( CORBA::is_nil( it->second )) continue;
1169 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1171 if (i > 1) aPythonDump << ", ";
1172 aPythonDump << it->second;
1176 catch(SALOME_Exception & S_ex) {
1177 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1179 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1181 return aList._retn();
1184 //=============================================================================
1186 * Get number of groups existing in the mesh
1188 //=============================================================================
1190 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1192 Unexpect aCatch(SALOME_SalomeException);
1193 return _mapGroups.size();
1196 //=============================================================================
1198 * New group including all mesh elements present in initial groups is created.
1200 //=============================================================================
1202 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1203 SMESH::SMESH_GroupBase_ptr theGroup2,
1204 const char* theName )
1205 throw (SALOME::SALOME_Exception)
1207 SMESH::SMESH_Group_var aResGrp;
1211 _preMeshInfo->FullLoadFromFile();
1213 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1214 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1216 if ( theGroup1->GetType() != theGroup2->GetType() )
1217 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1222 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1223 if ( aResGrp->_is_nil() )
1224 return SMESH::SMESH_Group::_nil();
1226 aResGrp->AddFrom( theGroup1 );
1227 aResGrp->AddFrom( theGroup2 );
1229 // Update Python script
1230 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1231 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1233 SMESH_CATCH( SMESH::throwCorbaException );
1235 return aResGrp._retn();
1238 //=============================================================================
1240 * \brief New group including all mesh elements present in initial groups is created.
1241 * \param theGroups list of groups
1242 * \param theName name of group to be created
1243 * \return pointer to the new group
1245 //=============================================================================
1247 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1248 const char* theName )
1249 throw (SALOME::SALOME_Exception)
1251 SMESH::SMESH_Group_var aResGrp;
1254 _preMeshInfo->FullLoadFromFile();
1257 return SMESH::SMESH_Group::_nil();
1262 SMESH::ElementType aType = SMESH::ALL;
1263 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1265 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1266 if ( CORBA::is_nil( aGrp ) )
1268 if ( aType == SMESH::ALL )
1269 aType = aGrp->GetType();
1270 else if ( aType != aGrp->GetType() )
1271 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1274 if ( aType == SMESH::ALL )
1275 return SMESH::SMESH_Group::_nil();
1280 aResGrp = CreateGroup( aType, theName );
1281 if ( aResGrp->_is_nil() )
1282 return SMESH::SMESH_Group::_nil();
1284 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1285 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1287 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1288 if ( !CORBA::is_nil( aGrp ) )
1290 aResGrp->AddFrom( aGrp );
1291 if ( g > 0 ) pyDump << ", ";
1295 pyDump << " ], '" << theName << "' )";
1297 SMESH_CATCH( SMESH::throwCorbaException );
1299 return aResGrp._retn();
1302 //=============================================================================
1304 * New group is created. All mesh elements that are
1305 * present in both initial groups are added to the new one.
1307 //=============================================================================
1309 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1310 SMESH::SMESH_GroupBase_ptr theGroup2,
1311 const char* theName )
1312 throw (SALOME::SALOME_Exception)
1314 SMESH::SMESH_Group_var aResGrp;
1319 _preMeshInfo->FullLoadFromFile();
1321 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1322 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1324 if ( theGroup1->GetType() != theGroup2->GetType() )
1325 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1329 // Create Intersection
1330 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1331 if ( aResGrp->_is_nil() )
1332 return aResGrp._retn();
1334 SMESHDS_GroupBase* groupDS1 = 0;
1335 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1336 groupDS1 = grp_i->GetGroupDS();
1338 SMESHDS_GroupBase* groupDS2 = 0;
1339 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1340 groupDS2 = grp_i->GetGroupDS();
1342 SMESHDS_Group* resGroupDS = 0;
1343 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1344 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1346 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1348 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1349 while ( elemIt1->more() )
1351 const SMDS_MeshElement* e = elemIt1->next();
1352 if ( groupDS2->Contains( e ))
1353 resGroupDS->SMDSGroup().Add( e );
1356 // Update Python script
1357 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1358 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1360 SMESH_CATCH( SMESH::throwCorbaException );
1362 return aResGrp._retn();
1365 //=============================================================================
1367 \brief Intersect list of groups. New group is created. All mesh elements that
1368 are present in all initial groups simultaneously are added to the new one.
1369 \param theGroups list of groups
1370 \param theName name of group to be created
1371 \return pointer on the group
1373 //=============================================================================
1374 SMESH::SMESH_Group_ptr
1375 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1376 const char* theName )
1377 throw (SALOME::SALOME_Exception)
1379 SMESH::SMESH_Group_var aResGrp;
1384 _preMeshInfo->FullLoadFromFile();
1387 return SMESH::SMESH_Group::_nil();
1389 // check types and get SMESHDS_GroupBase's
1390 SMESH::ElementType aType = SMESH::ALL;
1391 vector< SMESHDS_GroupBase* > groupVec;
1392 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1394 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1395 if ( CORBA::is_nil( aGrp ) )
1397 if ( aType == SMESH::ALL )
1398 aType = aGrp->GetType();
1399 else if ( aType != aGrp->GetType() )
1400 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1403 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1404 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1406 if ( grpDS->IsEmpty() )
1411 groupVec.push_back( grpDS );
1414 if ( aType == SMESH::ALL ) // all groups are nil
1415 return SMESH::SMESH_Group::_nil();
1420 aResGrp = CreateGroup( aType, theName );
1422 SMESHDS_Group* resGroupDS = 0;
1423 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1424 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1425 if ( !resGroupDS || groupVec.empty() )
1426 return aResGrp._retn();
1429 size_t i, nb = groupVec.size();
1430 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1431 while ( elemIt1->more() )
1433 const SMDS_MeshElement* e = elemIt1->next();
1435 for ( i = 1; ( i < nb && inAll ); ++i )
1436 inAll = groupVec[i]->Contains( e );
1439 resGroupDS->SMDSGroup().Add( e );
1442 // Update Python script
1443 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1444 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1446 SMESH_CATCH( SMESH::throwCorbaException );
1448 return aResGrp._retn();
1451 //=============================================================================
1453 * New group is created. All mesh elements that are present in
1454 * a main group but is not present in a tool group are added to the new one
1456 //=============================================================================
1458 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1459 SMESH::SMESH_GroupBase_ptr theGroup2,
1460 const char* theName )
1461 throw (SALOME::SALOME_Exception)
1463 SMESH::SMESH_Group_var aResGrp;
1468 _preMeshInfo->FullLoadFromFile();
1470 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1471 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1473 if ( theGroup1->GetType() != theGroup2->GetType() )
1474 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1478 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1479 if ( aResGrp->_is_nil() )
1480 return aResGrp._retn();
1482 SMESHDS_GroupBase* groupDS1 = 0;
1483 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1484 groupDS1 = grp_i->GetGroupDS();
1486 SMESHDS_GroupBase* groupDS2 = 0;
1487 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1488 groupDS2 = grp_i->GetGroupDS();
1490 SMESHDS_Group* resGroupDS = 0;
1491 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1492 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1494 if ( groupDS1 && groupDS2 && resGroupDS )
1496 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1497 while ( elemIt1->more() )
1499 const SMDS_MeshElement* e = elemIt1->next();
1500 if ( !groupDS2->Contains( e ))
1501 resGroupDS->SMDSGroup().Add( e );
1504 // Update Python script
1505 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1506 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1508 SMESH_CATCH( SMESH::throwCorbaException );
1510 return aResGrp._retn();
1513 //=============================================================================
1515 \brief Cut lists of groups. New group is created. All mesh elements that are
1516 present in main groups but do not present in tool groups are added to the new one
1517 \param theMainGroups list of main groups
1518 \param theToolGroups list of tool groups
1519 \param theName name of group to be created
1520 \return pointer on the group
1522 //=============================================================================
1523 SMESH::SMESH_Group_ptr
1524 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1525 const SMESH::ListOfGroups& theToolGroups,
1526 const char* theName )
1527 throw (SALOME::SALOME_Exception)
1529 SMESH::SMESH_Group_var aResGrp;
1534 _preMeshInfo->FullLoadFromFile();
1537 return SMESH::SMESH_Group::_nil();
1539 // check types and get SMESHDS_GroupBase's
1540 SMESH::ElementType aType = SMESH::ALL;
1541 vector< SMESHDS_GroupBase* > toolGroupVec;
1542 vector< SMDS_ElemIteratorPtr > mainIterVec;
1544 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1546 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1547 if ( CORBA::is_nil( aGrp ) )
1549 if ( aType == SMESH::ALL )
1550 aType = aGrp->GetType();
1551 else if ( aType != aGrp->GetType() )
1552 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1554 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1555 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1556 if ( !grpDS->IsEmpty() )
1557 mainIterVec.push_back( grpDS->GetElements() );
1559 if ( aType == SMESH::ALL ) // all main groups are nil
1560 return SMESH::SMESH_Group::_nil();
1561 if ( mainIterVec.empty() ) // all main groups are empty
1562 return aResGrp._retn();
1564 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1566 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1567 if ( CORBA::is_nil( aGrp ) )
1569 if ( aType != aGrp->GetType() )
1570 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1572 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1573 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1574 toolGroupVec.push_back( grpDS );
1580 aResGrp = CreateGroup( aType, theName );
1582 SMESHDS_Group* resGroupDS = 0;
1583 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1584 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1586 return aResGrp._retn();
1589 size_t i, nb = toolGroupVec.size();
1590 SMDS_ElemIteratorPtr mainElemIt
1591 ( new SMDS_IteratorOnIterators
1592 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1593 while ( mainElemIt->more() )
1595 const SMDS_MeshElement* e = mainElemIt->next();
1597 for ( i = 0; ( i < nb && !isIn ); ++i )
1598 isIn = toolGroupVec[i]->Contains( e );
1601 resGroupDS->SMDSGroup().Add( e );
1604 // Update Python script
1605 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1606 << ".CutListOfGroups( " << theMainGroups << ", "
1607 << theToolGroups << ", '" << theName << "' )";
1609 SMESH_CATCH( SMESH::throwCorbaException );
1611 return aResGrp._retn();
1614 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1616 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1617 bool & toStopChecking )
1619 toStopChecking = ( nbCommon < nbChecked );
1620 return nbCommon == nbNodes;
1622 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1623 bool & toStopChecking )
1625 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1626 return nbCommon == nbCorners;
1628 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1629 bool & toStopChecking )
1631 return nbCommon > 0;
1633 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1634 bool & toStopChecking )
1636 return nbCommon >= (nbNodes+1) / 2;
1640 //=============================================================================
1642 * Create a group of entities basing on nodes of other groups.
1643 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1644 * \param [in] anElemType - a type of elements to include to the new group.
1645 * \param [in] theName - a name of the new group.
1646 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1647 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1648 * new group provided that it is based on nodes of an element of \a aListOfGroups
1649 * \return SMESH_Group - the created group
1651 // IMP 19939, bug 22010, IMP 22635
1652 //=============================================================================
1654 SMESH::SMESH_Group_ptr
1655 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1656 SMESH::ElementType theElemType,
1657 const char* theName,
1658 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1659 CORBA::Boolean theUnderlyingOnly)
1660 throw (SALOME::SALOME_Exception)
1662 SMESH::SMESH_Group_var aResGrp;
1666 _preMeshInfo->FullLoadFromFile();
1668 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1670 if ( !theName || !aMeshDS )
1671 return SMESH::SMESH_Group::_nil();
1673 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1675 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1676 SMESH_Comment nbCoNoStr( "SMESH.");
1677 switch ( theNbCommonNodes ) {
1678 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1679 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1680 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1681 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1682 default: return aResGrp._retn();
1684 int nbChecked, nbCommon, nbNodes, nbCorners;
1690 aResGrp = CreateGroup( theElemType, theName );
1691 if ( aResGrp->_is_nil() )
1692 return SMESH::SMESH_Group::_nil();
1694 SMESHDS_GroupBase* groupBaseDS =
1695 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1696 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1698 vector<bool> isNodeInGroups;
1700 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1702 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1703 if ( CORBA::is_nil( aGrp ) )
1705 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1706 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1709 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1710 if ( !elIt ) continue;
1712 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1714 while ( elIt->more() ) {
1715 const SMDS_MeshElement* el = elIt->next();
1716 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1717 while ( nIt->more() )
1718 resGroupCore.Add( nIt->next() );
1721 // get elements of theElemType based on nodes of every element of group
1722 else if ( theUnderlyingOnly )
1724 while ( elIt->more() )
1726 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1727 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1728 TIDSortedElemSet checkedElems;
1729 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1730 while ( nIt->more() )
1732 const SMDS_MeshNode* n = nIt->next();
1733 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1734 // check nodes of elements of theElemType around el
1735 while ( elOfTypeIt->more() )
1737 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1738 if ( !checkedElems.insert( elOfType ).second ) continue;
1739 nbNodes = elOfType->NbNodes();
1740 nbCorners = elOfType->NbCornerNodes();
1742 bool toStopChecking = false;
1743 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1744 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1745 if ( elNodes.count( nIt2->next() ) &&
1746 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1748 resGroupCore.Add( elOfType );
1755 // get all nodes of elements of groups
1758 while ( elIt->more() )
1760 const SMDS_MeshElement* el = elIt->next(); // an element of group
1761 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1762 while ( nIt->more() )
1764 const SMDS_MeshNode* n = nIt->next();
1765 if ( n->GetID() >= isNodeInGroups.size() )
1766 isNodeInGroups.resize( n->GetID() + 1, false );
1767 isNodeInGroups[ n->GetID() ] = true;
1773 // Get elements of theElemType based on a certain number of nodes of elements of groups
1774 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1776 const SMDS_MeshNode* n;
1777 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1778 const int isNodeInGroupsSize = isNodeInGroups.size();
1779 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1781 if ( !isNodeInGroups[ iN ] ||
1782 !( n = aMeshDS->FindNode( iN )))
1785 // check nodes of elements of theElemType around n
1786 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1787 while ( elOfTypeIt->more() )
1789 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1790 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1795 nbNodes = elOfType->NbNodes();
1796 nbCorners = elOfType->NbCornerNodes();
1798 bool toStopChecking = false;
1799 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1800 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1802 const int nID = nIt->next()->GetID();
1803 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1804 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1806 resGroupCore.Add( elOfType );
1814 // Update Python script
1815 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1816 << ".CreateDimGroup( "
1817 << theGroups << ", " << theElemType << ", '" << theName << "', "
1818 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1820 SMESH_CATCH( SMESH::throwCorbaException );
1822 return aResGrp._retn();
1825 //================================================================================
1827 * \brief Remember GEOM group data
1829 //================================================================================
1831 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1832 CORBA::Object_ptr theSmeshObj)
1834 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1837 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1838 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1839 if ( groupSO->_is_nil() )
1842 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1843 GEOM::GEOM_IGroupOperations_wrap groupOp =
1844 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1845 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1848 _geomGroupData.push_back( TGeomGroupData() );
1849 TGeomGroupData & groupData = _geomGroupData.back();
1851 CORBA::String_var entry = groupSO->GetID();
1852 groupData._groupEntry = entry.in();
1854 for ( int i = 0; i < ids->length(); ++i )
1855 groupData._indices.insert( ids[i] );
1857 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1858 // shape index in SMESHDS
1859 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1860 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1863 //================================================================================
1865 * Remove GEOM group data relating to removed smesh object
1867 //================================================================================
1869 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1871 list<TGeomGroupData>::iterator
1872 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1873 for ( ; data != dataEnd; ++data ) {
1874 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1875 _geomGroupData.erase( data );
1881 //================================================================================
1883 * \brief Return new group contents if it has been changed and update group data
1885 //================================================================================
1887 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1889 TopoDS_Shape newShape;
1892 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1893 if ( study->_is_nil() ) return newShape; // means "not changed"
1894 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1895 if ( !groupSO->_is_nil() )
1897 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1898 if ( CORBA::is_nil( groupObj )) return newShape;
1899 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1901 // get indices of group items
1902 set<int> curIndices;
1903 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1904 GEOM::GEOM_IGroupOperations_wrap groupOp =
1905 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1906 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1907 for ( int i = 0; i < ids->length(); ++i )
1908 curIndices.insert( ids[i] );
1910 if ( groupData._indices == curIndices )
1911 return newShape; // group not changed
1914 groupData._indices = curIndices;
1916 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1917 if ( !geomClient ) return newShape;
1918 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1919 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1920 newShape = _gen_i->GeomObjectToShape( geomGroup );
1923 if ( newShape.IsNull() ) {
1924 // geom group becomes empty - return empty compound
1925 TopoDS_Compound compound;
1926 BRep_Builder().MakeCompound(compound);
1927 newShape = compound;
1934 //-----------------------------------------------------------------------------
1936 * \brief Storage of shape and index used in CheckGeomGroupModif()
1938 struct TIndexedShape
1941 TopoDS_Shape _shape;
1942 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1944 //-----------------------------------------------------------------------------
1946 * \brief Data to re-create a group on geometry
1948 struct TGroupOnGeomData
1952 SMDSAbs_ElementType _type;
1954 Quantity_Color _color;
1958 //=============================================================================
1960 * \brief Update data if geometry changes
1964 //=============================================================================
1966 void SMESH_Mesh_i::CheckGeomModif()
1968 if ( !_impl->HasShapeToMesh() ) return;
1970 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1971 if ( study->_is_nil() ) return;
1973 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1974 //if ( mainGO->_is_nil() ) return;
1976 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1977 called by other mesh (IPAL52735) */
1978 mainGO->GetType() == GEOM_GROUP ||
1979 mainGO->GetTick() == _mainShapeTick )
1981 CheckGeomGroupModif();
1985 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1986 if ( !geomClient ) return;
1987 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1988 if ( geomGen->_is_nil() ) return;
1990 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1991 geomClient->RemoveShapeFromBuffer( ior.in() );
1993 // Update data taking into account that
1994 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1997 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1998 if ( newShape.IsNull() )
2001 _mainShapeTick = mainGO->GetTick();
2003 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2005 // store data of groups on geometry
2006 vector< TGroupOnGeomData > groupsData;
2007 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2008 groupsData.reserve( groups.size() );
2009 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2010 for ( ; g != groups.end(); ++g )
2011 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2013 TGroupOnGeomData data;
2014 data._oldID = group->GetID();
2015 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2016 data._type = group->GetType();
2017 data._name = group->GetStoreName();
2018 data._color = group->GetColor();
2019 groupsData.push_back( data );
2021 // store assigned hypotheses
2022 vector< pair< int, THypList > > ids2Hyps;
2023 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2024 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2026 const TopoDS_Shape& s = s2hyps.Key();
2027 const THypList& hyps = s2hyps.ChangeValue();
2028 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2031 // change shape to mesh
2032 int oldNbSubShapes = meshDS->MaxShapeIndex();
2033 _impl->ShapeToMesh( TopoDS_Shape() );
2034 _impl->ShapeToMesh( newShape );
2036 // re-add shapes of geom groups
2037 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2038 for ( ; data != _geomGroupData.end(); ++data )
2040 TopoDS_Shape newShape = newGroupShape( *data );
2041 if ( !newShape.IsNull() )
2043 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2045 TopoDS_Compound compound;
2046 BRep_Builder().MakeCompound( compound );
2047 BRep_Builder().Add( compound, newShape );
2048 newShape = compound;
2050 _impl->GetSubMesh( newShape );
2053 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2054 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2055 SALOME::INTERNAL_ERROR );
2057 // re-assign hypotheses
2058 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2060 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2061 const THypList& hyps = ids2Hyps[i].second;
2062 THypList::const_iterator h = hyps.begin();
2063 for ( ; h != hyps.end(); ++h )
2064 _impl->AddHypothesis( s, (*h)->GetID() );
2068 for ( size_t i = 0; i < groupsData.size(); ++i )
2070 const TGroupOnGeomData& data = groupsData[i];
2072 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2073 if ( i2g == _mapGroups.end() ) continue;
2075 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2076 if ( !gr_i ) continue;
2079 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2080 meshDS->IndexToShape( data._shapeID ));
2083 _mapGroups.erase( i2g );
2087 g->GetGroupDS()->SetColor( data._color );
2088 gr_i->changeLocalId( id );
2089 _mapGroups[ id ] = i2g->second;
2090 if ( data._oldID != id )
2091 _mapGroups.erase( i2g );
2095 // update _mapSubMesh
2096 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2097 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2098 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2102 //=============================================================================
2104 * \brief Update objects depending on changed geom groups
2106 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2107 * issue 0020210: Update of a smesh group after modification of the associated geom group
2109 //=============================================================================
2111 void SMESH_Mesh_i::CheckGeomGroupModif()
2113 if ( !_impl->HasShapeToMesh() ) return;
2115 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2116 if ( study->_is_nil() ) return;
2118 CORBA::Long nbEntities = NbNodes() + NbElements();
2120 // Check if group contents changed
2122 typedef map< string, TopoDS_Shape > TEntry2Geom;
2123 TEntry2Geom newGroupContents;
2125 list<TGeomGroupData>::iterator
2126 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2127 for ( ; data != dataEnd; ++data )
2129 pair< TEntry2Geom::iterator, bool > it_new =
2130 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2131 bool processedGroup = !it_new.second;
2132 TopoDS_Shape& newShape = it_new.first->second;
2133 if ( !processedGroup )
2134 newShape = newGroupShape( *data );
2135 if ( newShape.IsNull() )
2136 continue; // no changes
2139 _preMeshInfo->ForgetOrLoad();
2141 if ( processedGroup ) { // update group indices
2142 list<TGeomGroupData>::iterator data2 = data;
2143 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2144 data->_indices = data2->_indices;
2147 // Update SMESH objects according to new GEOM group contents
2149 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2150 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2152 int oldID = submesh->GetId();
2153 if ( !_mapSubMeshIor.count( oldID ))
2155 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2157 // update hypotheses
2158 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2159 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2160 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2162 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2163 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2165 // care of submeshes
2166 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2167 int newID = newSubmesh->GetId();
2168 if ( newID != oldID ) {
2169 _mapSubMesh [ newID ] = newSubmesh;
2170 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2171 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2172 _mapSubMesh. erase(oldID);
2173 _mapSubMesh_i. erase(oldID);
2174 _mapSubMeshIor.erase(oldID);
2175 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2180 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2181 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2182 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2184 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2186 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2187 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2188 ds->SetShape( newShape );
2193 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2194 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2196 // Remove groups and submeshes basing on removed sub-shapes
2198 TopTools_MapOfShape newShapeMap;
2199 TopoDS_Iterator shapeIt( newShape );
2200 for ( ; shapeIt.More(); shapeIt.Next() )
2201 newShapeMap.Add( shapeIt.Value() );
2203 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2204 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2206 if ( newShapeMap.Contains( shapeIt.Value() ))
2208 TopTools_IndexedMapOfShape oldShapeMap;
2209 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2210 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2212 const TopoDS_Shape& oldShape = oldShapeMap(i);
2213 int oldInd = meshDS->ShapeToIndex( oldShape );
2215 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2216 if ( i_smIor != _mapSubMeshIor.end() ) {
2217 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2220 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2221 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2223 // check if a group bases on oldInd shape
2224 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2225 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2226 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2227 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2229 RemoveGroup( i_grp->second ); // several groups can base on same shape
2230 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2235 // Reassign hypotheses and update groups after setting the new shape to mesh
2237 // collect anassigned hypotheses
2238 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2239 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2240 TShapeHypList assignedHyps;
2241 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2243 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2244 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2245 if ( !hyps.empty() ) {
2246 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2247 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2248 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2251 // collect shapes supporting groups
2252 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2253 TShapeTypeList groupData;
2254 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2255 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2256 for ( ; grIt != groups.end(); ++grIt )
2258 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2260 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2262 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2264 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2265 _impl->ShapeToMesh( newShape );
2267 // reassign hypotheses
2268 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2269 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2271 TIndexedShape& geom = indS_hyps->first;
2272 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2273 int oldID = geom._index;
2274 int newID = meshDS->ShapeToIndex( geom._shape );
2275 if ( oldID == 1 ) { // main shape
2277 geom._shape = newShape;
2281 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2282 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2283 // care of sub-meshes
2284 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2285 if ( newID != oldID ) {
2286 _mapSubMesh [ newID ] = newSubmesh;
2287 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2288 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2289 _mapSubMesh. erase(oldID);
2290 _mapSubMesh_i. erase(oldID);
2291 _mapSubMeshIor.erase(oldID);
2292 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2296 TShapeTypeList::iterator geomType = groupData.begin();
2297 for ( ; geomType != groupData.end(); ++geomType )
2299 const TIndexedShape& geom = geomType->first;
2300 int oldID = geom._index;
2301 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2304 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2305 CORBA::String_var name = groupSO->GetName();
2307 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2309 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2310 group_i->changeLocalId( newID );
2313 break; // everything has been updated
2316 } // loop on group data
2320 CORBA::Long newNbEntities = NbNodes() + NbElements();
2321 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2322 if ( newNbEntities != nbEntities )
2324 // Add all SObjects with icons to soToUpdateIcons
2325 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2327 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2328 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2329 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2331 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2332 i_gr != _mapGroups.end(); ++i_gr ) // groups
2333 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2336 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2337 for ( ; so != soToUpdateIcons.end(); ++so )
2338 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2341 //=============================================================================
2343 * \brief Create standalone group from a group on geometry or filter
2345 //=============================================================================
2347 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2348 throw (SALOME::SALOME_Exception)
2350 SMESH::SMESH_Group_var aGroup;
2355 _preMeshInfo->FullLoadFromFile();
2357 if ( theGroup->_is_nil() )
2358 return aGroup._retn();
2360 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2362 return aGroup._retn();
2364 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2366 const int anId = aGroupToRem->GetLocalID();
2367 if ( !_impl->ConvertToStandalone( anId ) )
2368 return aGroup._retn();
2369 removeGeomGroupData( theGroup );
2371 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2373 // remove old instance of group from own map
2374 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2375 _mapGroups.erase( anId );
2377 SALOMEDS::StudyBuilder_var builder;
2378 SALOMEDS::SObject_wrap aGroupSO;
2379 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2380 if ( !aStudy->_is_nil() ) {
2381 builder = aStudy->NewBuilder();
2382 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2383 if ( !aGroupSO->_is_nil() )
2385 // remove reference to geometry
2386 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2387 for ( ; chItr->More(); chItr->Next() )
2388 // Remove group's child SObject
2389 builder->RemoveObject( chItr->Value() );
2391 // Update Python script
2392 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2393 << ".ConvertToStandalone( " << aGroupSO << " )";
2395 // change icon of Group on Filter
2398 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2399 const int isEmpty = ( elemTypes->length() == 0 );
2402 SALOMEDS::GenericAttribute_wrap anAttr =
2403 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2404 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2405 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2411 // remember new group in own map
2412 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2413 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2415 // register CORBA object for persistence
2416 _gen_i->RegisterObject( aGroup );
2418 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2419 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2420 //aGroup->Register();
2421 aGroupToRem->UnRegister();
2423 SMESH_CATCH( SMESH::throwCorbaException );
2425 return aGroup._retn();
2428 //=============================================================================
2432 //=============================================================================
2434 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2436 if(MYDEBUG) MESSAGE( "createSubMesh" );
2437 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2438 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2439 const int subMeshId = mySubMesh->GetId();
2441 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2442 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2444 _mapSubMesh [subMeshId] = mySubMesh;
2445 _mapSubMesh_i [subMeshId] = subMeshServant;
2446 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2448 subMeshServant->Register();
2450 // register CORBA object for persistence
2451 int nextId = _gen_i->RegisterObject( subMesh );
2452 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2453 else { nextId = 0; } // avoid "unused variable" warning
2455 // to track changes of GEOM groups
2456 addGeomGroupData( theSubShapeObject, subMesh );
2458 return subMesh._retn();
2461 //=======================================================================
2462 //function : getSubMesh
2464 //=======================================================================
2466 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2468 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2469 if ( it == _mapSubMeshIor.end() )
2470 return SMESH::SMESH_subMesh::_nil();
2472 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2475 //=============================================================================
2479 //=============================================================================
2481 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2482 GEOM::GEOM_Object_ptr theSubShapeObject )
2484 bool isHypChanged = false;
2485 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2486 return isHypChanged;
2488 const int subMeshId = theSubMesh->GetId();
2490 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2492 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2494 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2497 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2498 isHypChanged = !hyps.empty();
2499 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2500 for ( ; hyp != hyps.end(); ++hyp )
2501 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2508 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2509 isHypChanged = ( aHypList->length() > 0 );
2510 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2511 removeHypothesis( theSubShapeObject, aHypList[i] );
2514 catch( const SALOME::SALOME_Exception& ) {
2515 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2517 removeGeomGroupData( theSubShapeObject );
2521 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2522 if ( id_smi != _mapSubMesh_i.end() )
2523 id_smi->second->UnRegister();
2525 // remove a CORBA object
2526 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2527 if ( id_smptr != _mapSubMeshIor.end() )
2528 SMESH::SMESH_subMesh_var( id_smptr->second );
2530 _mapSubMesh.erase(subMeshId);
2531 _mapSubMesh_i.erase(subMeshId);
2532 _mapSubMeshIor.erase(subMeshId);
2534 return isHypChanged;
2537 //=============================================================================
2541 //=============================================================================
2543 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2544 const char* theName,
2545 const TopoDS_Shape& theShape,
2546 const SMESH_PredicatePtr& thePredicate )
2548 std::string newName;
2549 if ( !theName || strlen( theName ) == 0 )
2551 std::set< std::string > presentNames;
2552 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2553 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2555 CORBA::String_var name = i_gr->second->GetName();
2556 presentNames.insert( name.in() );
2559 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2560 } while ( !presentNames.insert( newName ).second );
2561 theName = newName.c_str();
2564 SMESH::SMESH_GroupBase_var aGroup;
2565 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2567 SMESH_GroupBase_i* aGroupImpl;
2568 if ( !theShape.IsNull() )
2569 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2570 else if ( thePredicate )
2571 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2573 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2575 aGroup = aGroupImpl->_this();
2576 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2577 aGroupImpl->Register();
2579 // register CORBA object for persistence
2580 int nextId = _gen_i->RegisterObject( aGroup );
2581 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2582 else { nextId = 0; } // avoid "unused variable" warning in release mode
2584 // to track changes of GEOM groups
2585 if ( !theShape.IsNull() ) {
2586 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2587 addGeomGroupData( geom, aGroup );
2590 return aGroup._retn();
2593 //=============================================================================
2595 * SMESH_Mesh_i::removeGroup
2597 * Should be called by ~SMESH_Group_i()
2599 //=============================================================================
2601 void SMESH_Mesh_i::removeGroup( const int theId )
2603 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2604 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2605 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2606 _mapGroups.erase( theId );
2607 removeGeomGroupData( group );
2608 if ( !_impl->RemoveGroup( theId ))
2610 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2611 RemoveGroup( group );
2613 group->UnRegister();
2617 //=============================================================================
2621 //=============================================================================
2623 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2624 throw(SALOME::SALOME_Exception)
2626 SMESH::log_array_var aLog;
2630 _preMeshInfo->FullLoadFromFile();
2632 list < SMESHDS_Command * >logDS = _impl->GetLog();
2633 aLog = new SMESH::log_array;
2635 int lg = logDS.size();
2638 list < SMESHDS_Command * >::iterator its = logDS.begin();
2639 while(its != logDS.end()){
2640 SMESHDS_Command *com = *its;
2641 int comType = com->GetType();
2643 int lgcom = com->GetNumber();
2645 const list < int >&intList = com->GetIndexes();
2646 int inum = intList.size();
2648 list < int >::const_iterator ii = intList.begin();
2649 const list < double >&coordList = com->GetCoords();
2650 int rnum = coordList.size();
2652 list < double >::const_iterator ir = coordList.begin();
2653 aLog[indexLog].commandType = comType;
2654 aLog[indexLog].number = lgcom;
2655 aLog[indexLog].coords.length(rnum);
2656 aLog[indexLog].indexes.length(inum);
2657 for(int i = 0; i < rnum; i++){
2658 aLog[indexLog].coords[i] = *ir;
2659 //MESSAGE(" "<<i<<" "<<ir.Value());
2662 for(int i = 0; i < inum; i++){
2663 aLog[indexLog].indexes[i] = *ii;
2664 //MESSAGE(" "<<i<<" "<<ii.Value());
2673 SMESH_CATCH( SMESH::throwCorbaException );
2675 return aLog._retn();
2679 //=============================================================================
2683 //=============================================================================
2685 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2689 SMESH_CATCH( SMESH::throwCorbaException );
2692 //=============================================================================
2696 //=============================================================================
2698 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2703 //=============================================================================
2707 //=============================================================================
2709 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2714 //=============================================================================
2717 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2718 // issue 0020918: groups removal is caused by hyp modification
2719 // issue 0021208: to forget not loaded mesh data at hyp modification
2720 struct TCallUp_i : public SMESH_Mesh::TCallUp
2722 SMESH_Mesh_i* _mesh;
2723 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2724 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2725 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2726 virtual void Load () { _mesh->Load(); }
2730 //================================================================================
2732 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2734 //================================================================================
2736 void SMESH_Mesh_i::onHypothesisModified()
2739 _preMeshInfo->ForgetOrLoad();
2742 //=============================================================================
2746 //=============================================================================
2748 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2750 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2753 _impl->SetCallUp( new TCallUp_i(this));
2756 //=============================================================================
2760 //=============================================================================
2762 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2764 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2768 //=============================================================================
2770 * Return mesh editor
2772 //=============================================================================
2774 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2775 throw (SALOME::SALOME_Exception)
2777 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2781 _preMeshInfo->FullLoadFromFile();
2783 // Create MeshEditor
2785 _editor = new SMESH_MeshEditor_i( this, false );
2786 aMeshEdVar = _editor->_this();
2788 // Update Python script
2789 TPythonDump() << _editor << " = "
2790 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2792 SMESH_CATCH( SMESH::throwCorbaException );
2794 return aMeshEdVar._retn();
2797 //=============================================================================
2799 * Return mesh edition previewer
2801 //=============================================================================
2803 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2804 throw (SALOME::SALOME_Exception)
2806 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2810 _preMeshInfo->FullLoadFromFile();
2812 if ( !_previewEditor )
2813 _previewEditor = new SMESH_MeshEditor_i( this, true );
2814 aMeshEdVar = _previewEditor->_this();
2816 SMESH_CATCH( SMESH::throwCorbaException );
2818 return aMeshEdVar._retn();
2821 //================================================================================
2823 * \brief Return true if the mesh has been edited since a last total re-compute
2824 * and those modifications may prevent successful partial re-compute
2826 //================================================================================
2828 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2830 Unexpect aCatch(SALOME_SalomeException);
2831 return _impl->HasModificationsToDiscard();
2834 //================================================================================
2836 * \brief Returns a random unique color
2838 //================================================================================
2840 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2842 const int MAX_ATTEMPTS = 100;
2844 double tolerance = 0.5;
2845 SALOMEDS::Color col;
2849 // generate random color
2850 double red = (double)rand() / RAND_MAX;
2851 double green = (double)rand() / RAND_MAX;
2852 double blue = (double)rand() / RAND_MAX;
2853 // check existence in the list of the existing colors
2854 bool matched = false;
2855 std::list<SALOMEDS::Color>::const_iterator it;
2856 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2857 SALOMEDS::Color color = *it;
2858 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2859 matched = tol < tolerance;
2861 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2862 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2870 //=============================================================================
2872 * Sets auto-color mode. If it is on, groups get unique random colors
2874 //=============================================================================
2876 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2878 Unexpect aCatch(SALOME_SalomeException);
2879 _impl->SetAutoColor(theAutoColor);
2881 TPythonDump pyDump; // not to dump group->SetColor() from below code
2882 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2884 std::list<SALOMEDS::Color> aReservedColors;
2885 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2886 for ( ; it != _mapGroups.end(); it++ ) {
2887 if ( CORBA::is_nil( it->second )) continue;
2888 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2889 it->second->SetColor( aColor );
2890 aReservedColors.push_back( aColor );
2894 //=============================================================================
2896 * Returns true if auto-color mode is on
2898 //=============================================================================
2900 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2902 Unexpect aCatch(SALOME_SalomeException);
2903 return _impl->GetAutoColor();
2906 //=============================================================================
2908 * Checks if there are groups with equal names
2910 //=============================================================================
2912 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2914 return _impl->HasDuplicatedGroupNamesMED();
2917 //================================================================================
2919 * \brief Care of a file before exporting mesh into it
2921 //================================================================================
2923 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2925 SMESH_File aFile( file );
2927 if (aFile.exists()) {
2928 // existing filesystem node
2929 if ( !aFile.isDirectory() ) {
2930 if ( aFile.openForWriting() ) {
2931 if ( overwrite && ! aFile.remove()) {
2932 msg << "Can't replace " << aFile.getName();
2935 msg << "Can't write into " << aFile.getName();
2938 msg << "Location " << aFile.getName() << " is not a file";
2942 // nonexisting file; check if it can be created
2943 if ( !aFile.openForWriting() ) {
2944 msg << "You cannot create the file "
2946 << ". Check the directory existance and access rights";
2954 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2958 //================================================================================
2960 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2961 * \param file - file name
2962 * \param overwrite - to erase the file or not
2963 * \retval string - mesh name
2965 //================================================================================
2967 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2968 CORBA::Boolean overwrite)
2971 PrepareForWriting(file, overwrite);
2972 string aMeshName = "Mesh";
2973 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2974 if ( !aStudy->_is_nil() ) {
2975 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2976 if ( !aMeshSO->_is_nil() ) {
2977 CORBA::String_var name = aMeshSO->GetName();
2979 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2980 if ( !aStudy->GetProperties()->IsLocked() )
2982 SALOMEDS::GenericAttribute_wrap anAttr;
2983 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2984 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2985 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2986 ASSERT(!aFileName->_is_nil());
2987 aFileName->SetValue(file);
2988 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2989 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2990 ASSERT(!aFileType->_is_nil());
2991 aFileType->SetValue("FICHIERMED");
2995 // Update Python script
2996 // set name of mesh before export
2997 TPythonDump() << _gen_i << ".SetName("
2998 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3000 // check names of groups
3006 //================================================================================
3008 * \brief Export to med file
3010 //================================================================================
3012 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3013 CORBA::Boolean auto_groups,
3014 SMESH::MED_VERSION theVersion,
3015 CORBA::Boolean overwrite,
3016 CORBA::Boolean autoDimension)
3017 throw(SALOME::SALOME_Exception)
3021 _preMeshInfo->FullLoadFromFile();
3023 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3024 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3026 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3027 << file << "', " << auto_groups << ", "
3028 << theVersion << ", " << overwrite << ", "
3029 << autoDimension << " )";
3031 SMESH_CATCH( SMESH::throwCorbaException );
3034 //================================================================================
3036 * \brief Export a mesh to a med file
3038 //================================================================================
3040 void SMESH_Mesh_i::ExportToMED (const char* file,
3041 CORBA::Boolean auto_groups,
3042 SMESH::MED_VERSION theVersion)
3043 throw(SALOME::SALOME_Exception)
3045 ExportToMEDX(file,auto_groups,theVersion,true);
3048 //================================================================================
3050 * \brief Export a mesh to a med file
3052 //================================================================================
3054 void SMESH_Mesh_i::ExportMED (const char* file,
3055 CORBA::Boolean auto_groups)
3056 throw(SALOME::SALOME_Exception)
3058 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3061 //================================================================================
3063 * \brief Export a mesh to a SAUV file
3065 //================================================================================
3067 void SMESH_Mesh_i::ExportSAUV (const char* file,
3068 CORBA::Boolean auto_groups)
3069 throw(SALOME::SALOME_Exception)
3071 Unexpect aCatch(SALOME_SalomeException);
3073 _preMeshInfo->FullLoadFromFile();
3075 string aMeshName = prepareMeshNameAndGroups(file, true);
3076 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3077 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3078 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3082 //================================================================================
3084 * \brief Export a mesh to a DAT file
3086 //================================================================================
3088 void SMESH_Mesh_i::ExportDAT (const char *file)
3089 throw(SALOME::SALOME_Exception)
3091 Unexpect aCatch(SALOME_SalomeException);
3093 _preMeshInfo->FullLoadFromFile();
3095 // Update Python script
3096 // check names of groups
3098 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3101 PrepareForWriting(file);
3102 _impl->ExportDAT(file);
3105 //================================================================================
3107 * \brief Export a mesh to an UNV file
3109 //================================================================================
3111 void SMESH_Mesh_i::ExportUNV (const char *file)
3112 throw(SALOME::SALOME_Exception)
3114 Unexpect aCatch(SALOME_SalomeException);
3116 _preMeshInfo->FullLoadFromFile();
3118 // Update Python script
3119 // check names of groups
3121 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3124 PrepareForWriting(file);
3125 _impl->ExportUNV(file);
3128 //================================================================================
3130 * \brief Export a mesh to an STL file
3132 //================================================================================
3134 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3135 throw(SALOME::SALOME_Exception)
3137 Unexpect aCatch(SALOME_SalomeException);
3139 _preMeshInfo->FullLoadFromFile();
3141 // Update Python script
3142 // check names of groups
3144 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3145 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3148 PrepareForWriting(file);
3149 _impl->ExportSTL(file, isascii);
3152 //================================================================================
3154 * \brief Export a part of mesh to a med file
3156 //================================================================================
3158 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3160 CORBA::Boolean auto_groups,
3161 SMESH::MED_VERSION version,
3162 CORBA::Boolean overwrite,
3163 CORBA::Boolean autoDimension,
3164 const GEOM::ListOfFields& fields,
3165 const char* geomAssocFields)
3166 throw (SALOME::SALOME_Exception)
3170 _preMeshInfo->FullLoadFromFile();
3173 bool have0dField = false;
3174 if ( fields.length() > 0 )
3176 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3177 if ( shapeToMesh->_is_nil() )
3178 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3180 for ( size_t i = 0; i < fields.length(); ++i )
3182 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3183 THROW_SALOME_CORBA_EXCEPTION
3184 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3185 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3186 if ( fieldShape->_is_nil() )
3187 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3188 if ( !fieldShape->IsSame( shapeToMesh ) )
3189 THROW_SALOME_CORBA_EXCEPTION
3190 ( "Field defined not on shape", SALOME::BAD_PARAM);
3191 if ( fields[i]->GetDimension() == 0 )
3194 if ( geomAssocFields )
3195 for ( int i = 0; geomAssocFields[i]; ++i )
3196 switch ( geomAssocFields[i] ) {
3197 case 'v':case 'e':case 'f':case 's': break;
3198 case 'V':case 'E':case 'F':case 'S': break;
3199 default: THROW_SALOME_CORBA_EXCEPTION
3200 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3204 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3208 string aMeshName = "Mesh";
3209 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3210 if ( CORBA::is_nil( meshPart ) ||
3211 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3213 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3214 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3215 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3216 meshDS = _impl->GetMeshDS();
3221 _preMeshInfo->FullLoadFromFile();
3223 PrepareForWriting(file, overwrite);
3225 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3226 if ( !aStudy->_is_nil() ) {
3227 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3228 if ( !SO->_is_nil() ) {
3229 CORBA::String_var name = SO->GetName();
3233 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3234 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3235 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3236 meshDS = tmpDSDeleter._obj = partDS;
3241 if ( _impl->HasShapeToMesh() )
3243 DriverMED_W_Field fieldWriter;
3244 fieldWriter.SetFile( file );
3245 fieldWriter.SetMeshName( aMeshName );
3246 fieldWriter.AddODOnVertices( have0dField );
3248 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3252 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3253 goList->length( fields.length() );
3254 for ( size_t i = 0; i < fields.length(); ++i )
3256 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3259 TPythonDump() << _this() << ".ExportPartToMED( "
3260 << meshPart << ", r'" << file << "', "
3261 << auto_groups << ", " << version << ", " << overwrite << ", "
3262 << autoDimension << ", " << goList
3263 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3265 SMESH_CATCH( SMESH::throwCorbaException );
3268 //================================================================================
3270 * Write GEOM fields to MED file
3272 //================================================================================
3274 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3275 SMESHDS_Mesh* meshDS,
3276 const GEOM::ListOfFields& fields,
3277 const char* geomAssocFields)
3279 #define METH "SMESH_Mesh_i::exportMEDFields() "
3281 if (( fields.length() < 1 ) &&
3282 ( !geomAssocFields || !geomAssocFields[0] ))
3285 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3286 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3287 std::vector< int > subIdsByDim[ 4 ];
3288 const double noneDblValue = 0.;
3289 const double noneIntValue = 0;
3291 for ( size_t iF = 0; iF < fields.length(); ++iF )
3295 int dim = fields[ iF ]->GetDimension();
3296 SMDSAbs_ElementType elemType;
3297 TopAbs_ShapeEnum shapeType;
3299 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3300 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3301 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3302 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3304 continue; // skip fields on whole shape
3306 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3307 if ( dataType == GEOM::FDT_String )
3309 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3310 if ( stepIDs->length() < 1 )
3312 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3313 if ( comps->length() < 1 )
3315 CORBA::String_var name = fields[ iF ]->GetName();
3317 if ( !fieldWriter.Set( meshDS,
3321 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3324 for ( size_t iC = 0; iC < comps->length(); ++iC )
3325 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3327 // find sub-shape IDs
3329 std::vector< int >& subIds = subIdsByDim[ dim ];
3330 if ( subIds.empty() )
3331 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3332 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3333 subIds.push_back( id );
3337 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3341 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3343 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3344 if ( step->_is_nil() )
3347 CORBA::Long stamp = step->GetStamp();
3348 CORBA::Long id = step->GetID();
3349 fieldWriter.SetDtIt( int( stamp ), int( id ));
3351 // fill dblVals or intVals
3354 case GEOM::FDT_Double:
3356 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3357 if ( dblStep->_is_nil() ) continue;
3358 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3359 if ( vv->length() != subIds.size() )
3360 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3361 for ( size_t i = 0; i < vv->length(); ++i )
3362 dblVals[ subIds[ i ]] = vv[ i ];
3367 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3368 if ( intStep->_is_nil() ) continue;
3369 GEOM::ListOfLong_var vv = intStep->GetValues();
3370 if ( vv->length() != subIds.size() )
3371 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3372 for ( size_t i = 0; i < vv->length(); ++i )
3373 intVals[ subIds[ i ]] = (int) vv[ i ];
3376 case GEOM::FDT_Bool:
3378 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3379 if ( boolStep->_is_nil() ) continue;
3380 GEOM::short_array_var vv = boolStep->GetValues();
3381 if ( vv->length() != subIds.size() )
3382 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3383 for ( size_t i = 0; i < vv->length(); ++i )
3384 intVals[ subIds[ i ]] = (int) vv[ i ];
3390 // pass values to fieldWriter
3391 elemIt = fieldWriter.GetOrderedElems();
3392 if ( dataType == GEOM::FDT_Double )
3393 while ( elemIt->more() )
3395 const SMDS_MeshElement* e = elemIt->next();
3396 const int shapeID = e->getshapeId();
3397 if ( shapeID < 1 || shapeID >= dblVals.size() )
3398 fieldWriter.AddValue( noneDblValue );
3400 fieldWriter.AddValue( dblVals[ shapeID ]);
3403 while ( elemIt->more() )
3405 const SMDS_MeshElement* e = elemIt->next();
3406 const int shapeID = e->getshapeId();
3407 if ( shapeID < 1 || shapeID >= intVals.size() )
3408 fieldWriter.AddValue( (double) noneIntValue );
3410 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3414 fieldWriter.Perform();
3415 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3416 if ( res && res->IsKO() )
3418 if ( res->myComment.empty() )
3419 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3421 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3427 if ( !geomAssocFields || !geomAssocFields[0] )
3430 // write geomAssocFields
3432 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3433 shapeDim[ TopAbs_COMPOUND ] = 3;
3434 shapeDim[ TopAbs_COMPSOLID ] = 3;
3435 shapeDim[ TopAbs_SOLID ] = 3;
3436 shapeDim[ TopAbs_SHELL ] = 2;
3437 shapeDim[ TopAbs_FACE ] = 2;
3438 shapeDim[ TopAbs_WIRE ] = 1;
3439 shapeDim[ TopAbs_EDGE ] = 1;
3440 shapeDim[ TopAbs_VERTEX ] = 0;
3441 shapeDim[ TopAbs_SHAPE ] = 3;
3443 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3445 std::vector< std::string > compNames;
3446 switch ( geomAssocFields[ iF ]) {
3448 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3449 compNames.push_back( "dim" );
3452 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3455 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3458 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3462 compNames.push_back( "id" );
3463 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3464 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3466 fieldWriter.SetDtIt( -1, -1 );
3468 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3472 if ( compNames.size() == 2 ) // _vertices_
3473 while ( elemIt->more() )
3475 const SMDS_MeshElement* e = elemIt->next();
3476 const int shapeID = e->getshapeId();
3479 fieldWriter.AddValue( (double) -1 );
3480 fieldWriter.AddValue( (double) -1 );
3484 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3485 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3486 fieldWriter.AddValue( (double) shapeID );
3490 while ( elemIt->more() )
3492 const SMDS_MeshElement* e = elemIt->next();
3493 const int shapeID = e->getshapeId();
3495 fieldWriter.AddValue( (double) -1 );
3497 fieldWriter.AddValue( (double) shapeID );
3501 fieldWriter.Perform();
3502 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3503 if ( res && res->IsKO() )
3505 if ( res->myComment.empty() )
3506 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3508 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3511 } // loop on geomAssocFields
3516 //================================================================================
3518 * \brief Export a part of mesh to a DAT file
3520 //================================================================================
3522 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3524 throw (SALOME::SALOME_Exception)
3526 Unexpect aCatch(SALOME_SalomeException);
3528 _preMeshInfo->FullLoadFromFile();
3530 PrepareForWriting(file);
3532 SMESH_MeshPartDS partDS( meshPart );
3533 _impl->ExportDAT(file,&partDS);
3535 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3536 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3538 //================================================================================
3540 * \brief Export a part of mesh to an UNV file
3542 //================================================================================
3544 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3546 throw (SALOME::SALOME_Exception)
3548 Unexpect aCatch(SALOME_SalomeException);
3550 _preMeshInfo->FullLoadFromFile();
3552 PrepareForWriting(file);
3554 SMESH_MeshPartDS partDS( meshPart );
3555 _impl->ExportUNV(file, &partDS);
3557 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3558 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3560 //================================================================================
3562 * \brief Export a part of mesh to an STL file
3564 //================================================================================
3566 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3568 ::CORBA::Boolean isascii)
3569 throw (SALOME::SALOME_Exception)
3571 Unexpect aCatch(SALOME_SalomeException);
3573 _preMeshInfo->FullLoadFromFile();
3575 PrepareForWriting(file);
3577 SMESH_MeshPartDS partDS( meshPart );
3578 _impl->ExportSTL(file, isascii, &partDS);
3580 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3581 << meshPart<< ", r'" << file << "', " << isascii << ")";
3584 //================================================================================
3586 * \brief Export a part of mesh to an STL file
3588 //================================================================================
3590 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3592 CORBA::Boolean overwrite)
3593 throw (SALOME::SALOME_Exception)
3596 Unexpect aCatch(SALOME_SalomeException);
3598 _preMeshInfo->FullLoadFromFile();
3600 PrepareForWriting(file,overwrite);
3602 std::string meshName("");
3603 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3604 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3605 if ( !so->_is_nil() )
3607 CORBA::String_var name = so->GetName();
3608 meshName = name.in();
3610 SMESH_MeshPartDS partDS( meshPart );
3611 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3613 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3614 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3616 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3620 //================================================================================
3622 * \brief Export a part of mesh to a GMF file
3624 //================================================================================
3626 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3628 bool withRequiredGroups)
3629 throw (SALOME::SALOME_Exception)
3631 Unexpect aCatch(SALOME_SalomeException);
3633 _preMeshInfo->FullLoadFromFile();
3635 PrepareForWriting(file,/*overwrite=*/true);
3637 SMESH_MeshPartDS partDS( meshPart );
3638 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3640 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3641 << meshPart<< ", r'"
3643 << withRequiredGroups << ")";
3646 //=============================================================================
3648 * Return computation progress [0.,1]
3650 //=============================================================================
3652 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3656 return _impl->GetComputeProgress();
3658 SMESH_CATCH( SMESH::doNothing );
3662 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3664 Unexpect aCatch(SALOME_SalomeException);
3666 return _preMeshInfo->NbNodes();
3668 return _impl->NbNodes();
3671 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3673 Unexpect aCatch(SALOME_SalomeException);
3675 return _preMeshInfo->NbElements();
3677 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3680 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3682 Unexpect aCatch(SALOME_SalomeException);
3684 return _preMeshInfo->Nb0DElements();
3686 return _impl->Nb0DElements();
3689 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3691 Unexpect aCatch(SALOME_SalomeException);
3693 return _preMeshInfo->NbBalls();
3695 return _impl->NbBalls();
3698 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3700 Unexpect aCatch(SALOME_SalomeException);
3702 return _preMeshInfo->NbEdges();
3704 return _impl->NbEdges();
3707 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3708 throw(SALOME::SALOME_Exception)
3710 Unexpect aCatch(SALOME_SalomeException);
3712 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3714 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3717 //=============================================================================
3719 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->NbFaces();
3725 return _impl->NbFaces();
3728 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3730 Unexpect aCatch(SALOME_SalomeException);
3732 return _preMeshInfo->NbTriangles();
3734 return _impl->NbTriangles();
3737 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3739 Unexpect aCatch(SALOME_SalomeException);
3741 return _preMeshInfo->NbBiQuadTriangles();
3743 return _impl->NbBiQuadTriangles();
3746 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3748 Unexpect aCatch(SALOME_SalomeException);
3750 return _preMeshInfo->NbQuadrangles();
3752 return _impl->NbQuadrangles();
3755 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3757 Unexpect aCatch(SALOME_SalomeException);
3759 return _preMeshInfo->NbBiQuadQuadrangles();
3761 return _impl->NbBiQuadQuadrangles();
3764 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3766 Unexpect aCatch(SALOME_SalomeException);
3768 return _preMeshInfo->NbPolygons();
3770 return _impl->NbPolygons();
3773 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3774 throw(SALOME::SALOME_Exception)
3776 Unexpect aCatch(SALOME_SalomeException);
3778 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3780 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3783 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3784 throw(SALOME::SALOME_Exception)
3786 Unexpect aCatch(SALOME_SalomeException);
3788 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3790 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3793 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3794 throw(SALOME::SALOME_Exception)
3796 Unexpect aCatch(SALOME_SalomeException);
3798 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3800 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3803 //=============================================================================
3805 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3807 Unexpect aCatch(SALOME_SalomeException);
3809 return _preMeshInfo->NbVolumes();
3811 return _impl->NbVolumes();
3814 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3816 Unexpect aCatch(SALOME_SalomeException);
3818 return _preMeshInfo->NbTetras();
3820 return _impl->NbTetras();
3823 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3825 Unexpect aCatch(SALOME_SalomeException);
3827 return _preMeshInfo->NbHexas();
3829 return _impl->NbHexas();
3832 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3834 Unexpect aCatch(SALOME_SalomeException);
3836 return _preMeshInfo->NbTriQuadHexas();
3838 return _impl->NbTriQuadraticHexas();
3841 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3843 Unexpect aCatch(SALOME_SalomeException);
3845 return _preMeshInfo->NbPyramids();
3847 return _impl->NbPyramids();
3850 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3852 Unexpect aCatch(SALOME_SalomeException);
3854 return _preMeshInfo->NbPrisms();
3856 return _impl->NbPrisms();
3859 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3861 Unexpect aCatch(SALOME_SalomeException);
3863 return _preMeshInfo->NbHexPrisms();
3865 return _impl->NbHexagonalPrisms();
3868 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3870 Unexpect aCatch(SALOME_SalomeException);
3872 return _preMeshInfo->NbPolyhedrons();
3874 return _impl->NbPolyhedrons();
3877 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3878 throw(SALOME::SALOME_Exception)
3880 Unexpect aCatch(SALOME_SalomeException);
3882 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3884 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3887 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3888 throw(SALOME::SALOME_Exception)
3890 Unexpect aCatch(SALOME_SalomeException);
3892 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3894 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3897 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3898 throw(SALOME::SALOME_Exception)
3900 Unexpect aCatch(SALOME_SalomeException);
3902 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3904 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3907 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3908 throw(SALOME::SALOME_Exception)
3910 Unexpect aCatch(SALOME_SalomeException);
3912 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3914 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3917 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3918 throw(SALOME::SALOME_Exception)
3920 Unexpect aCatch(SALOME_SalomeException);
3922 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3924 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3927 //=============================================================================
3929 * Returns nb of published sub-meshes
3931 //=============================================================================
3933 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3935 Unexpect aCatch(SALOME_SalomeException);
3936 return _mapSubMesh_i.size();
3939 //=============================================================================
3941 * Dumps mesh into a string
3943 //=============================================================================
3945 char* SMESH_Mesh_i::Dump()
3949 return CORBA::string_dup( os.str().c_str() );
3952 //=============================================================================
3954 * Method of SMESH_IDSource interface
3956 //=============================================================================
3958 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3960 return GetElementsId();
3963 //=============================================================================
3965 * Returns ids of all elements
3967 //=============================================================================
3969 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3970 throw (SALOME::SALOME_Exception)
3972 Unexpect aCatch(SALOME_SalomeException);
3974 _preMeshInfo->FullLoadFromFile();
3976 SMESH::long_array_var aResult = new SMESH::long_array();
3977 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3979 if ( aSMESHDS_Mesh == NULL )
3980 return aResult._retn();
3982 long nbElements = NbElements();
3983 aResult->length( nbElements );
3984 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3985 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3986 aResult[i] = anIt->next()->GetID();
3988 return aResult._retn();
3992 //=============================================================================
3994 * Returns ids of all elements of given type
3996 //=============================================================================
3998 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3999 throw (SALOME::SALOME_Exception)
4001 Unexpect aCatch(SALOME_SalomeException);
4003 _preMeshInfo->FullLoadFromFile();
4005 SMESH::long_array_var aResult = new SMESH::long_array();
4006 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4008 if ( aSMESHDS_Mesh == NULL )
4009 return aResult._retn();
4011 long nbElements = NbElements();
4013 // No sense in returning ids of elements along with ids of nodes:
4014 // when theElemType == SMESH::ALL, return node ids only if
4015 // there are no elements
4016 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4017 return GetNodesId();
4019 aResult->length( nbElements );
4023 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4024 while ( i < nbElements && anIt->more() )
4025 aResult[i++] = anIt->next()->GetID();
4027 aResult->length( i );
4029 return aResult._retn();
4032 //=============================================================================
4034 * Returns ids of all nodes
4036 //=============================================================================
4038 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4039 throw (SALOME::SALOME_Exception)
4041 Unexpect aCatch(SALOME_SalomeException);
4043 _preMeshInfo->FullLoadFromFile();
4045 SMESH::long_array_var aResult = new SMESH::long_array();
4046 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4048 if ( aSMESHDS_Mesh == NULL )
4049 return aResult._retn();
4051 long nbNodes = NbNodes();
4052 aResult->length( nbNodes );
4053 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4054 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4055 aResult[i] = anIt->next()->GetID();
4057 return aResult._retn();
4060 //=============================================================================
4064 //=============================================================================
4066 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4067 throw (SALOME::SALOME_Exception)
4069 SMESH::ElementType type;
4073 _preMeshInfo->FullLoadFromFile();
4075 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4077 SMESH_CATCH( SMESH::throwCorbaException );
4082 //=============================================================================
4086 //=============================================================================
4088 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4089 throw (SALOME::SALOME_Exception)
4092 _preMeshInfo->FullLoadFromFile();
4094 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4096 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4098 return ( SMESH::EntityType ) e->GetEntityType();
4101 //=============================================================================
4105 //=============================================================================
4107 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4108 throw (SALOME::SALOME_Exception)
4111 _preMeshInfo->FullLoadFromFile();
4113 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4115 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4117 return ( SMESH::GeometryType ) e->GetGeomType();
4120 //=============================================================================
4122 * Returns ID of elements for given submesh
4124 //=============================================================================
4125 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4126 throw (SALOME::SALOME_Exception)
4128 SMESH::long_array_var aResult = new SMESH::long_array();
4132 _preMeshInfo->FullLoadFromFile();
4134 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4135 if(!SM) return aResult._retn();
4137 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4138 if(!SDSM) return aResult._retn();
4140 aResult->length(SDSM->NbElements());
4142 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4144 while ( eIt->more() ) {
4145 aResult[i++] = eIt->next()->GetID();
4148 SMESH_CATCH( SMESH::throwCorbaException );
4150 return aResult._retn();
4153 //=============================================================================
4155 * Returns ID of nodes for given submesh
4156 * If param all==true - returns all nodes, else -
4157 * returns only nodes on shapes.
4159 //=============================================================================
4161 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4163 throw (SALOME::SALOME_Exception)
4165 SMESH::long_array_var aResult = new SMESH::long_array();
4169 _preMeshInfo->FullLoadFromFile();
4171 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4172 if(!SM) return aResult._retn();
4174 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4175 if(!SDSM) return aResult._retn();
4178 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4179 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4180 while ( nIt->more() ) {
4181 const SMDS_MeshNode* elem = nIt->next();
4182 theElems.insert( elem->GetID() );
4185 else { // all nodes of submesh elements
4186 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4187 while ( eIt->more() ) {
4188 const SMDS_MeshElement* anElem = eIt->next();
4189 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4190 while ( nIt->more() ) {
4191 const SMDS_MeshElement* elem = nIt->next();
4192 theElems.insert( elem->GetID() );
4197 aResult->length(theElems.size());
4198 set<int>::iterator itElem;
4200 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4201 aResult[i++] = *itElem;
4203 SMESH_CATCH( SMESH::throwCorbaException );
4205 return aResult._retn();
4208 //=============================================================================
4210 * Returns type of elements for given submesh
4212 //=============================================================================
4214 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4215 throw (SALOME::SALOME_Exception)
4217 SMESH::ElementType type;
4221 _preMeshInfo->FullLoadFromFile();
4223 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4224 if(!SM) return SMESH::ALL;
4226 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4227 if(!SDSM) return SMESH::ALL;
4229 if(SDSM->NbElements()==0)
4230 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4232 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4233 const SMDS_MeshElement* anElem = eIt->next();
4235 type = ( SMESH::ElementType ) anElem->GetType();
4237 SMESH_CATCH( SMESH::throwCorbaException );
4243 //=============================================================================
4245 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4247 //=============================================================================
4249 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4252 _preMeshInfo->FullLoadFromFile();
4254 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4256 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4261 //=============================================================================
4263 * Get XYZ coordinates of node as list of double
4264 * If there is not node for given ID - returns empty list
4266 //=============================================================================
4268 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4271 _preMeshInfo->FullLoadFromFile();
4273 SMESH::double_array_var aResult = new SMESH::double_array();
4274 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4275 if ( aSMESHDS_Mesh == NULL )
4276 return aResult._retn();
4279 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4281 return aResult._retn();
4285 aResult[0] = aNode->X();
4286 aResult[1] = aNode->Y();
4287 aResult[2] = aNode->Z();
4288 return aResult._retn();
4292 //=============================================================================
4294 * For given node returns list of IDs of inverse elements
4295 * If there is not node for given ID - returns empty list
4297 //=============================================================================
4299 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4302 _preMeshInfo->FullLoadFromFile();
4304 SMESH::long_array_var aResult = new SMESH::long_array();
4305 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4306 if ( aSMESHDS_Mesh == NULL )
4307 return aResult._retn();
4310 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4312 return aResult._retn();
4314 // find inverse elements
4315 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4316 aResult->length( aNode->NbInverseElements() );
4317 for( int i = 0; eIt->more(); ++i )
4319 const SMDS_MeshElement* elem = eIt->next();
4320 aResult[ i ] = elem->GetID();
4322 return aResult._retn();
4325 //=============================================================================
4327 * \brief Return position of a node on shape
4329 //=============================================================================
4331 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4334 _preMeshInfo->FullLoadFromFile();
4336 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4337 aNodePosition->shapeID = 0;
4338 aNodePosition->shapeType = GEOM::SHAPE;
4340 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4341 if ( !mesh ) return aNodePosition;
4343 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4345 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4347 aNodePosition->shapeID = aNode->getshapeId();
4348 switch ( pos->GetTypeOfPosition() ) {
4350 aNodePosition->shapeType = GEOM::EDGE;
4351 aNodePosition->params.length(1);
4352 aNodePosition->params[0] =
4353 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4356 aNodePosition->shapeType = GEOM::FACE;
4357 aNodePosition->params.length(2);
4358 aNodePosition->params[0] =
4359 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4360 aNodePosition->params[1] =
4361 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4363 case SMDS_TOP_VERTEX:
4364 aNodePosition->shapeType = GEOM::VERTEX;
4366 case SMDS_TOP_3DSPACE:
4367 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4368 aNodePosition->shapeType = GEOM::SOLID;
4369 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4370 aNodePosition->shapeType = GEOM::SHELL;
4376 return aNodePosition;
4379 //=============================================================================
4381 * \brief Return position of an element on shape
4383 //=============================================================================
4385 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4388 _preMeshInfo->FullLoadFromFile();
4390 SMESH::ElementPosition anElementPosition;
4391 anElementPosition.shapeID = 0;
4392 anElementPosition.shapeType = GEOM::SHAPE;
4394 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4395 if ( !mesh ) return anElementPosition;
4397 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4399 anElementPosition.shapeID = anElem->getshapeId();
4400 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4401 if ( !aSp.IsNull() ) {
4402 switch ( aSp.ShapeType() ) {
4404 anElementPosition.shapeType = GEOM::EDGE;
4407 anElementPosition.shapeType = GEOM::FACE;
4410 anElementPosition.shapeType = GEOM::VERTEX;
4413 anElementPosition.shapeType = GEOM::SOLID;
4416 anElementPosition.shapeType = GEOM::SHELL;
4422 return anElementPosition;
4425 //=============================================================================
4427 * If given element is node returns IDs of shape from position
4428 * If there is not node for given ID - returns -1
4430 //=============================================================================
4432 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4435 _preMeshInfo->FullLoadFromFile();
4437 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4438 if ( aSMESHDS_Mesh == NULL )
4442 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4444 return aNode->getshapeId();
4451 //=============================================================================
4453 * For given element returns ID of result shape after
4454 * ::FindShape() from SMESH_MeshEditor
4455 * If there is not element for given ID - returns -1
4457 //=============================================================================
4459 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4462 _preMeshInfo->FullLoadFromFile();
4464 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4465 if ( aSMESHDS_Mesh == NULL )
4468 // try to find element
4469 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4473 ::SMESH_MeshEditor aMeshEditor(_impl);
4474 int index = aMeshEditor.FindShape( elem );
4482 //=============================================================================
4484 * Returns number of nodes for given element
4485 * If there is not element for given ID - returns -1
4487 //=============================================================================
4489 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4492 _preMeshInfo->FullLoadFromFile();
4494 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4495 if ( aSMESHDS_Mesh == NULL ) return -1;
4496 // try to find element
4497 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4498 if(!elem) return -1;
4499 return elem->NbNodes();
4503 //=============================================================================
4505 * Returns ID of node by given index for given element
4506 * If there is not element for given ID - returns -1
4507 * If there is not node for given index - returns -2
4509 //=============================================================================
4511 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4514 _preMeshInfo->FullLoadFromFile();
4516 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4517 if ( aSMESHDS_Mesh == NULL ) return -1;
4518 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4519 if(!elem) return -1;
4520 if( index>=elem->NbNodes() || index<0 ) return -1;
4521 return elem->GetNode(index)->GetID();
4524 //=============================================================================
4526 * Returns IDs of nodes of given element
4528 //=============================================================================
4530 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4533 _preMeshInfo->FullLoadFromFile();
4535 SMESH::long_array_var aResult = new SMESH::long_array();
4536 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4538 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4540 aResult->length( elem->NbNodes() );
4541 for ( int i = 0; i < elem->NbNodes(); ++i )
4542 aResult[ i ] = elem->GetNode( i )->GetID();
4545 return aResult._retn();
4548 //=============================================================================
4550 * Returns true if given node is medium node
4551 * in given quadratic element
4553 //=============================================================================
4555 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4558 _preMeshInfo->FullLoadFromFile();
4560 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4561 if ( aSMESHDS_Mesh == NULL ) return false;
4563 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4564 if(!aNode) return false;
4565 // try to find element
4566 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4567 if(!elem) return false;
4569 return elem->IsMediumNode(aNode);
4573 //=============================================================================
4575 * Returns true if given node is medium node
4576 * in one of quadratic elements
4578 //=============================================================================
4580 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4581 SMESH::ElementType theElemType)
4584 _preMeshInfo->FullLoadFromFile();
4586 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4587 if ( aSMESHDS_Mesh == NULL ) return false;
4590 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4591 if(!aNode) return false;
4593 SMESH_MesherHelper aHelper( *(_impl) );
4595 SMDSAbs_ElementType aType;
4596 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4597 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4598 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4599 else aType = SMDSAbs_All;
4601 return aHelper.IsMedium(aNode,aType);
4605 //=============================================================================
4607 * Returns number of edges for given element
4609 //=============================================================================
4611 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4614 _preMeshInfo->FullLoadFromFile();
4616 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4617 if ( aSMESHDS_Mesh == NULL ) return -1;
4618 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4619 if(!elem) return -1;
4620 return elem->NbEdges();
4624 //=============================================================================
4626 * Returns number of faces for given element
4628 //=============================================================================
4630 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4633 _preMeshInfo->FullLoadFromFile();
4635 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4636 if ( aSMESHDS_Mesh == NULL ) return -1;
4637 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4638 if(!elem) return -1;
4639 return elem->NbFaces();
4642 //=======================================================================
4643 //function : GetElemFaceNodes
4644 //purpose : Returns nodes of given face (counted from zero) for given element.
4645 //=======================================================================
4647 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4648 CORBA::Short faceIndex)
4651 _preMeshInfo->FullLoadFromFile();
4653 SMESH::long_array_var aResult = new SMESH::long_array();
4654 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4656 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4658 SMDS_VolumeTool vtool( elem );
4659 if ( faceIndex < vtool.NbFaces() )
4661 aResult->length( vtool.NbFaceNodes( faceIndex ));
4662 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4663 for ( int i = 0; i < aResult->length(); ++i )
4664 aResult[ i ] = nn[ i ]->GetID();
4668 return aResult._retn();
4671 //=======================================================================
4672 //function : GetElemFaceNodes
4673 //purpose : Returns three components of normal of given mesh face.
4674 //=======================================================================
4676 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4677 CORBA::Boolean normalized)
4680 _preMeshInfo->FullLoadFromFile();
4682 SMESH::double_array_var aResult = new SMESH::double_array();
4684 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4687 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4689 aResult->length( 3 );
4690 aResult[ 0 ] = normal.X();
4691 aResult[ 1 ] = normal.Y();
4692 aResult[ 2 ] = normal.Z();
4695 return aResult._retn();
4698 //=======================================================================
4699 //function : FindElementByNodes
4700 //purpose : Returns an element based on all given nodes.
4701 //=======================================================================
4703 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4706 _preMeshInfo->FullLoadFromFile();
4708 CORBA::Long elemID(0);
4709 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4711 vector< const SMDS_MeshNode * > nn( nodes.length() );
4712 for ( int i = 0; i < nodes.length(); ++i )
4713 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4716 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4717 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4718 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4719 _impl->NbVolumes( ORDER_QUADRATIC )))
4720 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4722 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4727 //=============================================================================
4729 * Returns true if given element is polygon
4731 //=============================================================================
4733 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4736 _preMeshInfo->FullLoadFromFile();
4738 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4739 if ( aSMESHDS_Mesh == NULL ) return false;
4740 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4741 if(!elem) return false;
4742 return elem->IsPoly();
4746 //=============================================================================
4748 * Returns true if given element is quadratic
4750 //=============================================================================
4752 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4755 _preMeshInfo->FullLoadFromFile();
4757 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4758 if ( aSMESHDS_Mesh == NULL ) return false;
4759 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4760 if(!elem) return false;
4761 return elem->IsQuadratic();
4764 //=============================================================================
4766 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4768 //=============================================================================
4770 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4773 _preMeshInfo->FullLoadFromFile();
4775 if ( const SMDS_BallElement* ball =
4776 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4777 return ball->GetDiameter();
4782 //=============================================================================
4784 * Returns bary center for given element
4786 //=============================================================================
4788 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4791 _preMeshInfo->FullLoadFromFile();
4793 SMESH::double_array_var aResult = new SMESH::double_array();
4794 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4795 if ( aSMESHDS_Mesh == NULL )
4796 return aResult._retn();
4798 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4800 return aResult._retn();
4802 if(elem->GetType()==SMDSAbs_Volume) {
4803 SMDS_VolumeTool aTool;
4804 if(aTool.Set(elem)) {
4806 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4811 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4813 double x=0., y=0., z=0.;
4814 for(; anIt->more(); ) {
4816 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4830 return aResult._retn();
4833 //================================================================================
4835 * \brief Create a group of elements preventing computation of a sub-shape
4837 //================================================================================
4839 SMESH::ListOfGroups*
4840 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4841 const char* theGroupName )
4842 throw ( SALOME::SALOME_Exception )
4844 Unexpect aCatch(SALOME_SalomeException);
4846 if ( !theGroupName || strlen( theGroupName) == 0 )
4847 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4849 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4851 // submesh by subshape id
4852 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4853 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4856 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4857 if ( error && !error->myBadElements.empty())
4859 // sort bad elements by type
4860 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4861 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4862 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4863 for ( ; elemIt != elemEnd; ++elemIt )
4865 const SMDS_MeshElement* elem = *elemIt;
4866 if ( !elem ) continue;
4868 if ( elem->GetID() < 1 )
4870 // elem is a temporary element, make a real element
4871 vector< const SMDS_MeshNode* > nodes;
4872 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4873 while ( nIt->more() && elem )
4875 nodes.push_back( nIt->next() );
4876 if ( nodes.back()->GetID() < 1 )
4877 elem = 0; // a temporary element on temporary nodes
4881 ::SMESH_MeshEditor editor( _impl );
4882 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4886 elemsByType[ elem->GetType() ].push_back( elem );
4889 // how many groups to create?
4891 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4892 nbTypes += int( !elemsByType[ i ].empty() );
4893 groups->length( nbTypes );
4896 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4898 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4899 if ( elems.empty() ) continue;
4901 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4902 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4904 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4905 SMESH::SMESH_Mesh_var mesh = _this();
4906 SALOMEDS::SObject_wrap aSO =
4907 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4908 GEOM::GEOM_Object::_nil(), theGroupName);
4910 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4911 if ( !grp_i ) continue;
4913 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4914 for ( size_t iE = 0; iE < elems.size(); ++iE )
4915 grpDS->SMDSGroup().Add( elems[ iE ]);
4920 return groups._retn();
4923 //=============================================================================
4925 * Create and publish group servants if any groups were imported or created anyhow
4927 //=============================================================================
4929 void SMESH_Mesh_i::CreateGroupServants()
4931 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4932 SMESH::SMESH_Mesh_var aMesh = _this();
4935 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4936 while ( groupIt->more() )
4938 ::SMESH_Group* group = groupIt->next();
4939 int anId = group->GetGroupDS()->GetID();
4941 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4942 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4944 addedIDs.insert( anId );
4946 SMESH_GroupBase_i* aGroupImpl;
4948 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4949 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4951 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4952 shape = groupOnGeom->GetShape();
4955 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4958 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4959 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4960 aGroupImpl->Register();
4962 // register CORBA object for persistence
4963 int nextId = _gen_i->RegisterObject( groupVar );
4964 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4965 else { nextId = 0; } // avoid "unused variable" warning in release mode
4967 // publishing the groups in the study
4968 if ( !aStudy->_is_nil() ) {
4969 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4970 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4973 if ( !addedIDs.empty() )
4976 set<int>::iterator id = addedIDs.begin();
4977 for ( ; id != addedIDs.end(); ++id )
4979 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4980 int i = std::distance( _mapGroups.begin(), it );
4981 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4986 //=============================================================================
4988 * \brief Return groups cantained in _mapGroups by their IDs
4990 //=============================================================================
4992 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4994 int nbGroups = groupIDs.size();
4995 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4996 aList->length( nbGroups );
4998 list<int>::const_iterator ids = groupIDs.begin();
4999 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5001 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5002 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5003 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5005 aList->length( nbGroups );
5006 return aList._retn();
5009 //=============================================================================
5011 * \brief Return information about imported file
5013 //=============================================================================
5015 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5017 SMESH::MedFileInfo_var res( _medFileInfo );
5018 if ( !res.operator->() ) {
5019 res = new SMESH::MedFileInfo;
5021 res->fileSize = res->major = res->minor = res->release = -1;
5026 //=============================================================================
5028 * \brief Pass names of mesh groups from study to mesh DS
5030 //=============================================================================
5032 void SMESH_Mesh_i::checkGroupNames()
5034 int nbGrp = NbGroups();
5038 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5039 if ( aStudy->_is_nil() )
5040 return; // nothing to do
5042 SMESH::ListOfGroups* grpList = 0;
5043 // avoid dump of "GetGroups"
5045 // store python dump into a local variable inside local scope
5046 SMESH::TPythonDump pDump; // do not delete this line of code
5047 grpList = GetGroups();
5050 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5051 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5054 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5055 if ( aGrpSO->_is_nil() )
5057 // correct name of the mesh group if necessary
5058 const char* guiName = aGrpSO->GetName();
5059 if ( strcmp(guiName, aGrp->GetName()) )
5060 aGrp->SetName( guiName );
5064 //=============================================================================
5066 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5068 //=============================================================================
5069 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5071 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5075 //=============================================================================
5077 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5079 //=============================================================================
5081 char* SMESH_Mesh_i::GetParameters()
5083 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5086 //=============================================================================
5088 * \brief Returns list of notebook variables used for last Mesh operation
5090 //=============================================================================
5091 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5093 SMESH::string_array_var aResult = new SMESH::string_array();
5094 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5096 CORBA::String_var aParameters = GetParameters();
5097 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5098 if ( !aStudy->_is_nil()) {
5099 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5100 if(aSections->length() > 0) {
5101 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5102 aResult->length(aVars.length());
5103 for(int i = 0;i < aVars.length();i++)
5104 aResult[i] = CORBA::string_dup( aVars[i]);
5108 return aResult._retn();
5111 //=======================================================================
5112 //function : GetTypes
5113 //purpose : Returns types of elements it contains
5114 //=======================================================================
5116 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5119 return _preMeshInfo->GetTypes();
5121 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5125 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5126 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5127 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5128 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5129 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5130 types->length( nbTypes );
5132 return types._retn();
5135 //=======================================================================
5136 //function : GetMesh
5137 //purpose : Returns self
5138 //=======================================================================
5140 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5142 return SMESH::SMESH_Mesh::_duplicate( _this() );
5145 //=======================================================================
5146 //function : IsMeshInfoCorrect
5147 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5148 // * happen if mesh data is not yet fully loaded from the file of study.
5149 //=======================================================================
5151 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5153 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5156 //=============================================================================
5158 * \brief Returns number of mesh elements per each \a EntityType
5160 //=============================================================================
5162 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5165 return _preMeshInfo->GetMeshInfo();
5167 SMESH::long_array_var aRes = new SMESH::long_array();
5168 aRes->length(SMESH::Entity_Last);
5169 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5171 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5173 return aRes._retn();
5174 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5175 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5176 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5177 return aRes._retn();
5180 //=============================================================================
5182 * \brief Returns number of mesh elements per each \a ElementType
5184 //=============================================================================
5186 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5188 SMESH::long_array_var aRes = new SMESH::long_array();
5189 aRes->length(SMESH::NB_ELEMENT_TYPES);
5190 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5193 const SMDS_MeshInfo* meshInfo = 0;
5195 meshInfo = _preMeshInfo;
5196 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5197 meshInfo = & meshDS->GetMeshInfo();
5200 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5201 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5203 return aRes._retn();
5206 //=============================================================================
5208 * Collect statistic of mesh elements given by iterator
5210 //=============================================================================
5212 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5213 SMESH::long_array& theInfo)
5215 if (!theItr) return;
5216 while (theItr->more())
5217 theInfo[ theItr->next()->GetEntityType() ]++;
5219 //=============================================================================
5221 * Returns mesh unstructed grid information.
5223 //=============================================================================
5225 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5227 SALOMEDS::TMPFile_var SeqFile;
5228 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5229 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5231 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5232 aWriter->WriteToOutputStringOn();
5233 aWriter->SetInputData(aGrid);
5234 aWriter->SetFileTypeToBinary();
5236 char* str = aWriter->GetOutputString();
5237 int size = aWriter->GetOutputStringLength();
5239 //Allocate octect buffer of required size
5240 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5241 //Copy ostrstream content to the octect buffer
5242 memcpy(OctetBuf, str, size);
5243 //Create and return TMPFile
5244 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5248 return SeqFile._retn();
5251 //=============================================================================
5252 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5253 * SMESH::ElementType type) */
5255 using namespace SMESH::Controls;
5256 //-----------------------------------------------------------------------------
5257 struct PredicateIterator : public SMDS_ElemIterator
5259 SMDS_ElemIteratorPtr _elemIter;
5260 PredicatePtr _predicate;
5261 const SMDS_MeshElement* _elem;
5263 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5264 PredicatePtr predicate):
5265 _elemIter(iterator), _predicate(predicate)
5273 virtual const SMDS_MeshElement* next()
5275 const SMDS_MeshElement* res = _elem;
5277 while ( _elemIter->more() && !_elem )
5279 _elem = _elemIter->next();
5280 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5287 //-----------------------------------------------------------------------------
5288 struct IDSourceIterator : public SMDS_ElemIterator
5290 const CORBA::Long* _idPtr;
5291 const CORBA::Long* _idEndPtr;
5292 SMESH::long_array_var _idArray;
5293 const SMDS_Mesh* _mesh;
5294 const SMDSAbs_ElementType _type;
5295 const SMDS_MeshElement* _elem;
5297 IDSourceIterator( const SMDS_Mesh* mesh,
5298 const CORBA::Long* ids,
5300 SMDSAbs_ElementType type):
5301 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5303 if ( _idPtr && nbIds && _mesh )
5306 IDSourceIterator( const SMDS_Mesh* mesh,
5307 SMESH::long_array* idArray,
5308 SMDSAbs_ElementType type):
5309 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5311 if ( idArray && _mesh )
5313 _idPtr = &_idArray[0];
5314 _idEndPtr = _idPtr + _idArray->length();
5322 virtual const SMDS_MeshElement* next()
5324 const SMDS_MeshElement* res = _elem;
5326 while ( _idPtr < _idEndPtr && !_elem )
5328 if ( _type == SMDSAbs_Node )
5330 _elem = _mesh->FindNode( *_idPtr++ );
5332 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5333 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5341 //-----------------------------------------------------------------------------
5343 struct NodeOfElemIterator : public SMDS_ElemIterator
5345 TColStd_MapOfInteger _checkedNodeIDs;
5346 SMDS_ElemIteratorPtr _elemIter;
5347 SMDS_ElemIteratorPtr _nodeIter;
5348 const SMDS_MeshElement* _node;
5350 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5352 if ( _elemIter && _elemIter->more() )
5354 _nodeIter = _elemIter->next()->nodesIterator();
5362 virtual const SMDS_MeshElement* next()
5364 const SMDS_MeshElement* res = _node;
5366 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5368 if ( _nodeIter->more() )
5370 _node = _nodeIter->next();
5371 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5376 _nodeIter = _elemIter->next()->nodesIterator();
5384 //=============================================================================
5386 * Return iterator on elements of given type in given object
5388 //=============================================================================
5390 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5391 SMESH::ElementType theType)
5393 SMDS_ElemIteratorPtr elemIt;
5394 bool typeOK = false;
5395 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5397 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5398 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5399 if ( !mesh_i ) return elemIt;
5400 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5402 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5404 elemIt = meshDS->elementsIterator( elemType );
5407 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5409 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5412 elemIt = sm->GetElements();
5413 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5415 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5416 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5420 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5422 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5423 if ( groupDS && ( elemType == groupDS->GetType() ||
5424 elemType == SMDSAbs_Node ||
5425 elemType == SMDSAbs_All ))
5427 elemIt = groupDS->GetElements();
5428 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5431 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5433 if ( filter_i->GetElementType() == theType ||
5434 elemType == SMDSAbs_Node ||
5435 elemType == SMDSAbs_All)
5437 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5438 if ( pred_i && pred_i->GetPredicate() )
5440 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5441 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5442 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5443 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5449 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5450 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5451 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5453 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5456 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5457 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5461 SMESH::long_array_var ids = theObject->GetIDs();
5462 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5464 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5467 if ( elemIt && elemIt->more() && !typeOK )
5469 if ( elemType == SMDSAbs_Node )
5471 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5475 elemIt = SMDS_ElemIteratorPtr();
5481 //=============================================================================
5482 namespace // Finding concurrent hypotheses
5483 //=============================================================================
5487 * \brief mapping of mesh dimension into shape type
5489 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5491 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5493 case 0: aType = TopAbs_VERTEX; break;
5494 case 1: aType = TopAbs_EDGE; break;
5495 case 2: aType = TopAbs_FACE; break;
5497 default:aType = TopAbs_SOLID; break;
5502 //-----------------------------------------------------------------------------
5504 * \brief Internal structure used to find concurent submeshes
5506 * It represents a pair < submesh, concurent dimension >, where
5507 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5508 * with another submesh. In other words, it is dimension of a hypothesis assigned
5515 int _dim; //!< a dimension the algo can build (concurrent dimension)
5516 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5517 TopTools_MapOfShape _shapeMap;
5518 SMESH_subMesh* _subMesh;
5519 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5521 //-----------------------------------------------------------------------------
5522 // Return the algorithm
5523 const SMESH_Algo* GetAlgo() const
5524 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5526 //-----------------------------------------------------------------------------
5528 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5530 const TopoDS_Shape& theShape)
5532 _subMesh = (SMESH_subMesh*)theSubMesh;
5533 SetShape( theDim, theShape );
5536 //-----------------------------------------------------------------------------
5538 void SetShape(const int theDim,
5539 const TopoDS_Shape& theShape)
5542 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5543 if (_dim >= _ownDim)
5544 _shapeMap.Add( theShape );
5546 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5547 for( ; anExp.More(); anExp.Next() )
5548 _shapeMap.Add( anExp.Current() );
5552 //-----------------------------------------------------------------------------
5553 //! Check sharing of sub-shapes
5554 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5555 const TopTools_MapOfShape& theToFind,
5556 const TopAbs_ShapeEnum theType)
5558 bool isShared = false;
5559 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5560 for (; !isShared && anItr.More(); anItr.Next() )
5562 const TopoDS_Shape aSubSh = anItr.Key();
5563 // check for case when concurrent dimensions are same
5564 isShared = theToFind.Contains( aSubSh );
5565 // check for sub-shape with concurrent dimension
5566 TopExp_Explorer anExp( aSubSh, theType );
5567 for ( ; !isShared && anExp.More(); anExp.Next() )
5568 isShared = theToFind.Contains( anExp.Current() );
5573 //-----------------------------------------------------------------------------
5574 //! check algorithms
5575 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5576 const SMESHDS_Hypothesis* theA2)
5578 if ( !theA1 || !theA2 ||
5579 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5580 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5581 return false; // one of the hypothesis is not algorithm
5582 // check algorithm names (should be equal)
5583 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5587 //-----------------------------------------------------------------------------
5588 //! Check if sub-shape hypotheses are concurrent
5589 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5591 if ( _subMesh == theOther->_subMesh )
5592 return false; // same sub-shape - should not be
5594 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5595 // any of the two submeshes is not on COMPOUND shape )
5596 // -> no concurrency
5597 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5598 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5599 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5600 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5601 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5604 // bool checkSubShape = ( _dim >= theOther->_dim )
5605 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5606 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5607 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5608 if ( !checkSubShape )
5611 // check algorithms to be same
5612 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5613 return true; // different algorithms -> concurrency !
5615 // check hypothesises for concurrence (skip first as algorithm)
5617 // pointers should be same, because it is referened from mesh hypothesis partition
5618 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5619 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5620 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5621 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5623 // the submeshes are concurrent if their algorithms has different parameters
5624 return nbSame != theOther->_hypotheses.size() - 1;
5627 // Return true if algorithm of this SMESH_DimHyp is used if no
5628 // sub-mesh order is imposed by the user
5629 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5631 // NeedDiscreteBoundary() algo has a higher priority
5632 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5633 theOther->GetAlgo()->NeedDiscreteBoundary() )
5634 return !this->GetAlgo()->NeedDiscreteBoundary();
5636 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5639 }; // end of SMESH_DimHyp
5640 //-----------------------------------------------------------------------------
5642 typedef list<const SMESH_DimHyp*> TDimHypList;
5644 //-----------------------------------------------------------------------------
5646 void addDimHypInstance(const int theDim,
5647 const TopoDS_Shape& theShape,
5648 const SMESH_Algo* theAlgo,
5649 const SMESH_subMesh* theSubMesh,
5650 const list <const SMESHDS_Hypothesis*>& theHypList,
5651 TDimHypList* theDimHypListArr )
5653 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5654 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5655 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5656 dimHyp->_hypotheses.push_front(theAlgo);
5657 listOfdimHyp.push_back( dimHyp );
5660 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5661 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5662 theHypList.begin(), theHypList.end() );
5665 //-----------------------------------------------------------------------------
5666 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5667 TDimHypList& theListOfConcurr)
5669 if ( theListOfConcurr.empty() )
5671 theListOfConcurr.push_back( theDimHyp );
5675 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5676 while ( hypIt != theListOfConcurr.end() &&
5677 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5679 theListOfConcurr.insert( hypIt, theDimHyp );
5683 //-----------------------------------------------------------------------------
5684 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5685 const TDimHypList& theListOfDimHyp,
5686 TDimHypList& theListOfConcurrHyp,
5687 set<int>& theSetOfConcurrId )
5689 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5690 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5692 const SMESH_DimHyp* curDimHyp = *rIt;
5693 if ( curDimHyp == theDimHyp )
5694 break; // meet own dimHyp pointer in same dimension
5696 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5697 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5699 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5704 //-----------------------------------------------------------------------------
5705 void unionLists(TListOfInt& theListOfId,
5706 TListOfListOfInt& theListOfListOfId,
5709 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5710 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5712 continue; //skip already treated lists
5713 // check if other list has any same submesh object
5714 TListOfInt& otherListOfId = *it;
5715 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5716 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5719 // union two lists (from source into target)
5720 TListOfInt::iterator it2 = otherListOfId.begin();
5721 for ( ; it2 != otherListOfId.end(); it2++ ) {
5722 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5723 theListOfId.push_back(*it2);
5725 // clear source list
5726 otherListOfId.clear();
5729 //-----------------------------------------------------------------------------
5731 //! free memory allocated for dimension-hypothesis objects
5732 void removeDimHyps( TDimHypList* theArrOfList )
5734 for (int i = 0; i < 4; i++ ) {
5735 TDimHypList& listOfdimHyp = theArrOfList[i];
5736 TDimHypList::const_iterator it = listOfdimHyp.begin();
5737 for ( ; it != listOfdimHyp.end(); it++ )
5742 //-----------------------------------------------------------------------------
5744 * \brief find common submeshes with given submesh
5745 * \param theSubMeshList list of already collected submesh to check
5746 * \param theSubMesh given submesh to intersect with other
5747 * \param theCommonSubMeshes collected common submeshes
5749 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5750 const SMESH_subMesh* theSubMesh,
5751 set<const SMESH_subMesh*>& theCommon )
5755 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5756 for ( ; it != theSubMeshList.end(); it++ )
5757 theSubMesh->FindIntersection( *it, theCommon );
5758 theSubMeshList.push_back( theSubMesh );
5759 //theCommon.insert( theSubMesh );
5762 //-----------------------------------------------------------------------------
5763 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5765 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5766 for ( ; listsIt != smLists.end(); ++listsIt )
5768 const TListOfInt& smIDs = *listsIt;
5769 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5777 //=============================================================================
5779 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5781 //=============================================================================
5783 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5785 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5786 if ( isSubMeshInList( submeshID, anOrder ))
5789 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5790 return isSubMeshInList( submeshID, allConurrent );
5793 //=============================================================================
5795 * \brief Return submesh objects list in meshing order
5797 //=============================================================================
5799 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5801 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5803 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5805 return aResult._retn();
5807 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5808 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5809 anOrder.splice( anOrder.end(), allConurrent );
5812 TListOfListOfInt::iterator listIt = anOrder.begin();
5813 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5814 unionLists( *listIt, anOrder, listIndx + 1 );
5816 // convert submesh ids into interface instances
5817 // and dump command into python
5818 convertMeshOrder( anOrder, aResult, false );
5820 return aResult._retn();
5823 //=============================================================================
5825 * \brief Finds concurrent sub-meshes
5827 //=============================================================================
5829 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5831 TListOfListOfInt anOrder;
5832 ::SMESH_Mesh& mesh = GetImpl();
5834 // collect submeshes and detect concurrent algorithms and hypothesises
5835 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5837 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5838 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5839 ::SMESH_subMesh* sm = (*i_sm).second;
5841 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5843 // list of assigned hypothesises
5844 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5845 // Find out dimensions where the submesh can be concurrent.
5846 // We define the dimensions by algo of each of hypotheses in hypList
5847 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5848 for( ; hypIt != hypList.end(); hypIt++ ) {
5849 SMESH_Algo* anAlgo = 0;
5850 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5851 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5852 // hyp it-self is algo
5853 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5855 // try to find algorithm with help of sub-shapes
5856 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5857 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5858 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5861 continue; // no algorithm assigned to a current submesh
5863 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5864 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5866 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5867 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5868 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5870 } // end iterations on submesh
5872 // iterate on created dimension-hypotheses and check for concurrents
5873 for ( int i = 0; i < 4; i++ ) {
5874 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5875 // check for concurrents in own and other dimensions (step-by-step)
5876 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5877 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5878 const SMESH_DimHyp* dimHyp = *dhIt;
5879 TDimHypList listOfConcurr;
5880 set<int> setOfConcurrIds;
5881 // looking for concurrents and collect into own list
5882 for ( int j = i; j < 4; j++ )
5883 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5884 // check if any concurrents found
5885 if ( listOfConcurr.size() > 0 ) {
5886 // add own submesh to list of concurrent
5887 addInOrderOfPriority( dimHyp, listOfConcurr );
5888 list<int> listOfConcurrIds;
5889 TDimHypList::iterator hypIt = listOfConcurr.begin();
5890 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5891 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5892 anOrder.push_back( listOfConcurrIds );
5897 removeDimHyps(dimHypListArr);
5899 // now, minimise the number of concurrent groups
5900 // Here we assume that lists of submeshes can have same submesh
5901 // in case of multi-dimension algorithms, as result
5902 // list with common submesh has to be united into one list
5904 TListOfListOfInt::iterator listIt = anOrder.begin();
5905 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5906 unionLists( *listIt, anOrder, listIndx + 1 );
5912 //=============================================================================
5914 * \brief Set submesh object order
5915 * \param theSubMeshArray submesh array order
5917 //=============================================================================
5919 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5922 _preMeshInfo->ForgetOrLoad();
5925 ::SMESH_Mesh& mesh = GetImpl();
5927 TPythonDump aPythonDump; // prevent dump of called methods
5928 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5930 TListOfListOfInt subMeshOrder;
5931 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5933 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5934 TListOfInt subMeshIds;
5936 aPythonDump << ", ";
5937 aPythonDump << "[ ";
5938 // Collect subMeshes which should be clear
5939 // do it list-by-list, because modification of submesh order
5940 // take effect between concurrent submeshes only
5941 set<const SMESH_subMesh*> subMeshToClear;
5942 list<const SMESH_subMesh*> subMeshList;
5943 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5945 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5947 aPythonDump << ", ";
5948 aPythonDump << subMesh;
5949 subMeshIds.push_back( subMesh->GetId() );
5950 // detect common parts of submeshes
5951 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5952 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5954 aPythonDump << " ]";
5955 subMeshOrder.push_back( subMeshIds );
5957 // clear collected submeshes
5958 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5959 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5960 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5961 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5963 aPythonDump << " ])";
5965 mesh.SetMeshOrder( subMeshOrder );
5971 //=============================================================================
5973 * \brief Convert submesh ids into submesh interfaces
5975 //=============================================================================
5977 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5978 SMESH::submesh_array_array& theResOrder,
5979 const bool theIsDump)
5981 int nbSet = theIdsOrder.size();
5982 TPythonDump aPythonDump; // prevent dump of called methods
5984 aPythonDump << "[ ";
5985 theResOrder.length(nbSet);
5986 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5988 for( ; it != theIdsOrder.end(); it++ ) {
5989 // translate submesh identificators into submesh objects
5990 // takeing into account real number of concurrent lists
5991 const TListOfInt& aSubOrder = (*it);
5992 if (!aSubOrder.size())
5995 aPythonDump << "[ ";
5996 // convert shape indeces into interfaces
5997 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5998 aResSubSet->length(aSubOrder.size());
5999 TListOfInt::const_iterator subIt = aSubOrder.begin();
6001 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6002 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6004 SMESH::SMESH_subMesh_var subMesh =
6005 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6008 aPythonDump << ", ";
6009 aPythonDump << subMesh;
6011 aResSubSet[ j++ ] = subMesh;
6014 aPythonDump << " ]";
6016 theResOrder[ listIndx++ ] = aResSubSet;
6018 // correct number of lists
6019 theResOrder.length( listIndx );
6022 // finilise python dump
6023 aPythonDump << " ]";
6024 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6028 //================================================================================
6030 // Implementation of SMESH_MeshPartDS
6032 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6033 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6035 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6036 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6038 _meshDS = mesh_i->GetImpl().GetMeshDS();
6040 SetPersistentId( _meshDS->GetPersistentId() );
6042 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6044 // <meshPart> is the whole mesh
6045 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6047 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6048 myGroupSet = _meshDS->GetGroups();
6053 SMESH::long_array_var anIDs = meshPart->GetIDs();
6054 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6055 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6057 for (int i=0; i < anIDs->length(); i++)
6058 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6059 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6064 for (int i=0; i < anIDs->length(); i++)
6065 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6066 if ( _elements[ e->GetType() ].insert( e ).second )
6069 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6070 while ( nIt->more() )
6072 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6073 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6080 ShapeToMesh( _meshDS->ShapeToMesh() );
6082 _meshDS = 0; // to enforce iteration on _elements and _nodes
6085 // -------------------------------------------------------------------------------------
6086 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6087 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6090 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6091 for ( ; partIt != meshPart.end(); ++partIt )
6092 if ( const SMDS_MeshElement * e = *partIt )
6093 if ( _elements[ e->GetType() ].insert( e ).second )
6096 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6097 while ( nIt->more() )
6099 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6100 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6106 // -------------------------------------------------------------------------------------
6107 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6109 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6111 typedef SMDS_SetIterator
6112 <const SMDS_MeshElement*,
6113 TIDSortedElemSet::const_iterator,
6114 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6115 SMDS_MeshElement::GeomFilter
6118 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6120 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6121 _elements[type].end(),
6122 SMDS_MeshElement::GeomFilter( geomType )));
6124 // -------------------------------------------------------------------------------------
6125 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6127 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6129 typedef SMDS_SetIterator
6130 <const SMDS_MeshElement*,
6131 TIDSortedElemSet::const_iterator,
6132 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6133 SMDS_MeshElement::EntityFilter
6136 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6138 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6139 _elements[type].end(),
6140 SMDS_MeshElement::EntityFilter( entity )));
6142 // -------------------------------------------------------------------------------------
6143 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6145 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6146 if ( type == SMDSAbs_All && !_meshDS )
6148 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6150 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6151 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6153 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6155 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6156 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6158 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6159 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6161 // -------------------------------------------------------------------------------------
6162 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6163 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6165 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6166 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6167 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6169 // -------------------------------------------------------------------------------------
6170 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6171 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6172 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6173 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6174 #undef _GET_ITER_DEFINE
6176 // END Implementation of SMESH_MeshPartDS
6178 //================================================================================