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 // Update after group modification
1978 if ( mainGO->_is_nil() || /* shape was removed from GEOM_Client by newGroupShape()
1979 called by other mesh (IPAL52735) */
1980 mainGO->GetType() == GEOM_GROUP ||
1981 mainGO->GetTick() == _mainShapeTick )
1983 CheckGeomGroupModif();
1987 // Update after shape transformation like Translate
1989 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1990 if ( !geomClient ) return;
1991 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1992 if ( geomGen->_is_nil() ) return;
1994 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1995 geomClient->RemoveShapeFromBuffer( ior.in() );
1997 // Update data taking into account that
1998 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
2001 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
2002 if ( newShape.IsNull() )
2005 _mainShapeTick = mainGO->GetTick();
2007 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
2009 // store data of groups on geometry
2010 vector< TGroupOnGeomData > groupsData;
2011 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2012 groupsData.reserve( groups.size() );
2013 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
2014 for ( ; g != groups.end(); ++g )
2015 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
2017 TGroupOnGeomData data;
2018 data._oldID = group->GetID();
2019 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
2020 data._type = group->GetType();
2021 data._name = group->GetStoreName();
2022 data._color = group->GetColor();
2023 groupsData.push_back( data );
2025 // store assigned hypotheses
2026 vector< pair< int, THypList > > ids2Hyps;
2027 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2028 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2030 const TopoDS_Shape& s = s2hyps.Key();
2031 const THypList& hyps = s2hyps.ChangeValue();
2032 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2035 // change shape to mesh
2036 int oldNbSubShapes = meshDS->MaxShapeIndex();
2037 _impl->ShapeToMesh( TopoDS_Shape() );
2038 _impl->ShapeToMesh( newShape );
2040 // re-add shapes of geom groups
2041 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2042 for ( ; data != _geomGroupData.end(); ++data )
2044 TopoDS_Shape newShape = newGroupShape( *data );
2045 if ( !newShape.IsNull() )
2047 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2049 TopoDS_Compound compound;
2050 BRep_Builder().MakeCompound( compound );
2051 BRep_Builder().Add( compound, newShape );
2052 newShape = compound;
2054 _impl->GetSubMesh( newShape );
2057 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2058 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2059 SALOME::INTERNAL_ERROR );
2061 // re-assign hypotheses
2062 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2064 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2065 const THypList& hyps = ids2Hyps[i].second;
2066 THypList::const_iterator h = hyps.begin();
2067 for ( ; h != hyps.end(); ++h )
2068 _impl->AddHypothesis( s, (*h)->GetID() );
2072 for ( size_t i = 0; i < groupsData.size(); ++i )
2074 const TGroupOnGeomData& data = groupsData[i];
2076 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2077 if ( i2g == _mapGroups.end() ) continue;
2079 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2080 if ( !gr_i ) continue;
2083 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2084 meshDS->IndexToShape( data._shapeID ));
2087 _mapGroups.erase( i2g );
2091 g->GetGroupDS()->SetColor( data._color );
2092 gr_i->changeLocalId( id );
2093 _mapGroups[ id ] = i2g->second;
2094 if ( data._oldID != id )
2095 _mapGroups.erase( i2g );
2099 // update _mapSubMesh
2100 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2101 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2102 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2106 //=============================================================================
2108 * \brief Update objects depending on changed geom groups
2110 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2111 * issue 0020210: Update of a smesh group after modification of the associated geom group
2113 //=============================================================================
2115 void SMESH_Mesh_i::CheckGeomGroupModif()
2117 if ( !_impl->HasShapeToMesh() ) return;
2119 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2120 if ( study->_is_nil() ) return;
2122 CORBA::Long nbEntities = NbNodes() + NbElements();
2124 // Check if group contents changed
2126 typedef map< string, TopoDS_Shape > TEntry2Geom;
2127 TEntry2Geom newGroupContents;
2129 list<TGeomGroupData>::iterator
2130 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2131 for ( ; data != dataEnd; ++data )
2133 pair< TEntry2Geom::iterator, bool > it_new =
2134 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2135 bool processedGroup = !it_new.second;
2136 TopoDS_Shape& newShape = it_new.first->second;
2137 if ( !processedGroup )
2138 newShape = newGroupShape( *data );
2139 if ( newShape.IsNull() )
2140 continue; // no changes
2143 _preMeshInfo->ForgetOrLoad();
2145 if ( processedGroup ) { // update group indices
2146 list<TGeomGroupData>::iterator data2 = data;
2147 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2148 data->_indices = data2->_indices;
2151 // Update SMESH objects according to new GEOM group contents
2153 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2154 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2156 int oldID = submesh->GetId();
2157 if ( !_mapSubMeshIor.count( oldID ))
2159 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2161 // update hypotheses
2162 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2163 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2164 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2166 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2167 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2169 // care of submeshes
2170 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2171 int newID = newSubmesh->GetId();
2172 if ( newID != oldID ) {
2173 _mapSubMesh [ newID ] = newSubmesh;
2174 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2175 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2176 _mapSubMesh. erase(oldID);
2177 _mapSubMesh_i. erase(oldID);
2178 _mapSubMeshIor.erase(oldID);
2179 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2184 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2185 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2186 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2188 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2190 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2191 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2192 ds->SetShape( newShape );
2197 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2198 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2200 // Remove groups and submeshes basing on removed sub-shapes
2202 TopTools_MapOfShape newShapeMap;
2203 TopoDS_Iterator shapeIt( newShape );
2204 for ( ; shapeIt.More(); shapeIt.Next() )
2205 newShapeMap.Add( shapeIt.Value() );
2207 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2208 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2210 if ( newShapeMap.Contains( shapeIt.Value() ))
2212 TopTools_IndexedMapOfShape oldShapeMap;
2213 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2214 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2216 const TopoDS_Shape& oldShape = oldShapeMap(i);
2217 int oldInd = meshDS->ShapeToIndex( oldShape );
2219 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2220 if ( i_smIor != _mapSubMeshIor.end() ) {
2221 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2224 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2225 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2227 // check if a group bases on oldInd shape
2228 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2229 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2230 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2231 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2233 RemoveGroup( i_grp->second ); // several groups can base on same shape
2234 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2239 // Reassign hypotheses and update groups after setting the new shape to mesh
2241 // collect anassigned hypotheses
2242 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2243 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2244 TShapeHypList assignedHyps;
2245 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2247 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2248 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2249 if ( !hyps.empty() ) {
2250 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2251 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2252 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2255 // collect shapes supporting groups
2256 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2257 TShapeTypeList groupData;
2258 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2259 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2260 for ( ; grIt != groups.end(); ++grIt )
2262 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2264 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2266 // set new shape to mesh -> DS of sub-meshes and geom groups are deleted
2268 _impl->ShapeToMesh( TopoDS_Shape() ); // IPAL52730
2269 _impl->ShapeToMesh( newShape );
2271 // reassign hypotheses
2272 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2273 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2275 TIndexedShape& geom = indS_hyps->first;
2276 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2277 int oldID = geom._index;
2278 int newID = meshDS->ShapeToIndex( geom._shape );
2279 if ( oldID == 1 ) { // main shape
2281 geom._shape = newShape;
2285 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2286 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2287 // care of sub-meshes
2288 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2289 if ( newID != oldID ) {
2290 _mapSubMesh [ newID ] = newSubmesh;
2291 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2292 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2293 _mapSubMesh. erase(oldID);
2294 _mapSubMesh_i. erase(oldID);
2295 _mapSubMeshIor.erase(oldID);
2296 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2300 TShapeTypeList::iterator geomType = groupData.begin();
2301 for ( ; geomType != groupData.end(); ++geomType )
2303 const TIndexedShape& geom = geomType->first;
2304 int oldID = geom._index;
2305 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2308 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2309 CORBA::String_var name = groupSO->GetName();
2311 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2313 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2314 group_i->changeLocalId( newID );
2317 break; // everything has been updated
2320 } // loop on group data
2324 CORBA::Long newNbEntities = NbNodes() + NbElements();
2325 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2326 if ( newNbEntities != nbEntities )
2328 // Add all SObjects with icons to soToUpdateIcons
2329 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2331 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2332 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2333 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2335 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2336 i_gr != _mapGroups.end(); ++i_gr ) // groups
2337 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2340 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2341 for ( ; so != soToUpdateIcons.end(); ++so )
2342 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2345 //=============================================================================
2347 * \brief Create standalone group from a group on geometry or filter
2349 //=============================================================================
2351 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2352 throw (SALOME::SALOME_Exception)
2354 SMESH::SMESH_Group_var aGroup;
2359 _preMeshInfo->FullLoadFromFile();
2361 if ( theGroup->_is_nil() )
2362 return aGroup._retn();
2364 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2366 return aGroup._retn();
2368 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2370 const int anId = aGroupToRem->GetLocalID();
2371 if ( !_impl->ConvertToStandalone( anId ) )
2372 return aGroup._retn();
2373 removeGeomGroupData( theGroup );
2375 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2377 // remove old instance of group from own map
2378 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2379 _mapGroups.erase( anId );
2381 SALOMEDS::StudyBuilder_var builder;
2382 SALOMEDS::SObject_wrap aGroupSO;
2383 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2384 if ( !aStudy->_is_nil() ) {
2385 builder = aStudy->NewBuilder();
2386 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2387 if ( !aGroupSO->_is_nil() )
2389 // remove reference to geometry
2390 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2391 for ( ; chItr->More(); chItr->Next() )
2392 // Remove group's child SObject
2393 builder->RemoveObject( chItr->Value() );
2395 // Update Python script
2396 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2397 << ".ConvertToStandalone( " << aGroupSO << " )";
2399 // change icon of Group on Filter
2402 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2403 const int isEmpty = ( elemTypes->length() == 0 );
2406 SALOMEDS::GenericAttribute_wrap anAttr =
2407 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2408 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2409 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2415 // remember new group in own map
2416 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2417 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2419 // register CORBA object for persistence
2420 _gen_i->RegisterObject( aGroup );
2422 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2423 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2424 //aGroup->Register();
2425 aGroupToRem->UnRegister();
2427 SMESH_CATCH( SMESH::throwCorbaException );
2429 return aGroup._retn();
2432 //=============================================================================
2436 //=============================================================================
2438 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2440 if(MYDEBUG) MESSAGE( "createSubMesh" );
2441 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2442 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2443 const int subMeshId = mySubMesh->GetId();
2445 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2446 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2448 _mapSubMesh [subMeshId] = mySubMesh;
2449 _mapSubMesh_i [subMeshId] = subMeshServant;
2450 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2452 subMeshServant->Register();
2454 // register CORBA object for persistence
2455 int nextId = _gen_i->RegisterObject( subMesh );
2456 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2457 else { nextId = 0; } // avoid "unused variable" warning
2459 // to track changes of GEOM groups
2460 addGeomGroupData( theSubShapeObject, subMesh );
2462 return subMesh._retn();
2465 //=======================================================================
2466 //function : getSubMesh
2468 //=======================================================================
2470 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2472 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2473 if ( it == _mapSubMeshIor.end() )
2474 return SMESH::SMESH_subMesh::_nil();
2476 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2479 //=============================================================================
2483 //=============================================================================
2485 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2486 GEOM::GEOM_Object_ptr theSubShapeObject )
2488 bool isHypChanged = false;
2489 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2490 return isHypChanged;
2492 const int subMeshId = theSubMesh->GetId();
2494 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2496 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2498 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2501 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2502 isHypChanged = !hyps.empty();
2503 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2504 for ( ; hyp != hyps.end(); ++hyp )
2505 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2512 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2513 isHypChanged = ( aHypList->length() > 0 );
2514 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2515 removeHypothesis( theSubShapeObject, aHypList[i] );
2518 catch( const SALOME::SALOME_Exception& ) {
2519 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2521 removeGeomGroupData( theSubShapeObject );
2525 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2526 if ( id_smi != _mapSubMesh_i.end() )
2527 id_smi->second->UnRegister();
2529 // remove a CORBA object
2530 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2531 if ( id_smptr != _mapSubMeshIor.end() )
2532 SMESH::SMESH_subMesh_var( id_smptr->second );
2534 _mapSubMesh.erase(subMeshId);
2535 _mapSubMesh_i.erase(subMeshId);
2536 _mapSubMeshIor.erase(subMeshId);
2538 return isHypChanged;
2541 //=============================================================================
2545 //=============================================================================
2547 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2548 const char* theName,
2549 const TopoDS_Shape& theShape,
2550 const SMESH_PredicatePtr& thePredicate )
2552 std::string newName;
2553 if ( !theName || strlen( theName ) == 0 )
2555 std::set< std::string > presentNames;
2556 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2557 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2559 CORBA::String_var name = i_gr->second->GetName();
2560 presentNames.insert( name.in() );
2563 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2564 } while ( !presentNames.insert( newName ).second );
2565 theName = newName.c_str();
2568 SMESH::SMESH_GroupBase_var aGroup;
2569 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2571 SMESH_GroupBase_i* aGroupImpl;
2572 if ( !theShape.IsNull() )
2573 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2574 else if ( thePredicate )
2575 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2577 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2579 aGroup = aGroupImpl->_this();
2580 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2581 aGroupImpl->Register();
2583 // register CORBA object for persistence
2584 int nextId = _gen_i->RegisterObject( aGroup );
2585 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2586 else { nextId = 0; } // avoid "unused variable" warning in release mode
2588 // to track changes of GEOM groups
2589 if ( !theShape.IsNull() ) {
2590 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2591 addGeomGroupData( geom, aGroup );
2594 return aGroup._retn();
2597 //=============================================================================
2599 * SMESH_Mesh_i::removeGroup
2601 * Should be called by ~SMESH_Group_i()
2603 //=============================================================================
2605 void SMESH_Mesh_i::removeGroup( const int theId )
2607 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2608 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2609 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2610 _mapGroups.erase( theId );
2611 removeGeomGroupData( group );
2612 if ( !_impl->RemoveGroup( theId ))
2614 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2615 RemoveGroup( group );
2617 group->UnRegister();
2621 //=============================================================================
2625 //=============================================================================
2627 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2628 throw(SALOME::SALOME_Exception)
2630 SMESH::log_array_var aLog;
2634 _preMeshInfo->FullLoadFromFile();
2636 list < SMESHDS_Command * >logDS = _impl->GetLog();
2637 aLog = new SMESH::log_array;
2639 int lg = logDS.size();
2642 list < SMESHDS_Command * >::iterator its = logDS.begin();
2643 while(its != logDS.end()){
2644 SMESHDS_Command *com = *its;
2645 int comType = com->GetType();
2647 int lgcom = com->GetNumber();
2649 const list < int >&intList = com->GetIndexes();
2650 int inum = intList.size();
2652 list < int >::const_iterator ii = intList.begin();
2653 const list < double >&coordList = com->GetCoords();
2654 int rnum = coordList.size();
2656 list < double >::const_iterator ir = coordList.begin();
2657 aLog[indexLog].commandType = comType;
2658 aLog[indexLog].number = lgcom;
2659 aLog[indexLog].coords.length(rnum);
2660 aLog[indexLog].indexes.length(inum);
2661 for(int i = 0; i < rnum; i++){
2662 aLog[indexLog].coords[i] = *ir;
2663 //MESSAGE(" "<<i<<" "<<ir.Value());
2666 for(int i = 0; i < inum; i++){
2667 aLog[indexLog].indexes[i] = *ii;
2668 //MESSAGE(" "<<i<<" "<<ii.Value());
2677 SMESH_CATCH( SMESH::throwCorbaException );
2679 return aLog._retn();
2683 //=============================================================================
2687 //=============================================================================
2689 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2693 SMESH_CATCH( SMESH::throwCorbaException );
2696 //=============================================================================
2700 //=============================================================================
2702 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2707 //=============================================================================
2711 //=============================================================================
2713 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2718 //=============================================================================
2721 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2722 // issue 0020918: groups removal is caused by hyp modification
2723 // issue 0021208: to forget not loaded mesh data at hyp modification
2724 struct TCallUp_i : public SMESH_Mesh::TCallUp
2726 SMESH_Mesh_i* _mesh;
2727 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2728 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2729 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2730 virtual void Load () { _mesh->Load(); }
2734 //================================================================================
2736 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2738 //================================================================================
2740 void SMESH_Mesh_i::onHypothesisModified()
2743 _preMeshInfo->ForgetOrLoad();
2746 //=============================================================================
2750 //=============================================================================
2752 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2754 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2757 _impl->SetCallUp( new TCallUp_i(this));
2760 //=============================================================================
2764 //=============================================================================
2766 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2768 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2772 //=============================================================================
2774 * Return mesh editor
2776 //=============================================================================
2778 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2779 throw (SALOME::SALOME_Exception)
2781 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2785 _preMeshInfo->FullLoadFromFile();
2787 // Create MeshEditor
2789 _editor = new SMESH_MeshEditor_i( this, false );
2790 aMeshEdVar = _editor->_this();
2792 // Update Python script
2793 TPythonDump() << _editor << " = "
2794 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2796 SMESH_CATCH( SMESH::throwCorbaException );
2798 return aMeshEdVar._retn();
2801 //=============================================================================
2803 * Return mesh edition previewer
2805 //=============================================================================
2807 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2808 throw (SALOME::SALOME_Exception)
2810 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2814 _preMeshInfo->FullLoadFromFile();
2816 if ( !_previewEditor )
2817 _previewEditor = new SMESH_MeshEditor_i( this, true );
2818 aMeshEdVar = _previewEditor->_this();
2820 SMESH_CATCH( SMESH::throwCorbaException );
2822 return aMeshEdVar._retn();
2825 //================================================================================
2827 * \brief Return true if the mesh has been edited since a last total re-compute
2828 * and those modifications may prevent successful partial re-compute
2830 //================================================================================
2832 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2834 Unexpect aCatch(SALOME_SalomeException);
2835 return _impl->HasModificationsToDiscard();
2838 //================================================================================
2840 * \brief Returns a random unique color
2842 //================================================================================
2844 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2846 const int MAX_ATTEMPTS = 100;
2848 double tolerance = 0.5;
2849 SALOMEDS::Color col;
2853 // generate random color
2854 double red = (double)rand() / RAND_MAX;
2855 double green = (double)rand() / RAND_MAX;
2856 double blue = (double)rand() / RAND_MAX;
2857 // check existence in the list of the existing colors
2858 bool matched = false;
2859 std::list<SALOMEDS::Color>::const_iterator it;
2860 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2861 SALOMEDS::Color color = *it;
2862 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2863 matched = tol < tolerance;
2865 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2866 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2874 //=============================================================================
2876 * Sets auto-color mode. If it is on, groups get unique random colors
2878 //=============================================================================
2880 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2882 Unexpect aCatch(SALOME_SalomeException);
2883 _impl->SetAutoColor(theAutoColor);
2885 TPythonDump pyDump; // not to dump group->SetColor() from below code
2886 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2888 std::list<SALOMEDS::Color> aReservedColors;
2889 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2890 for ( ; it != _mapGroups.end(); it++ ) {
2891 if ( CORBA::is_nil( it->second )) continue;
2892 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2893 it->second->SetColor( aColor );
2894 aReservedColors.push_back( aColor );
2898 //=============================================================================
2900 * Returns true if auto-color mode is on
2902 //=============================================================================
2904 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2906 Unexpect aCatch(SALOME_SalomeException);
2907 return _impl->GetAutoColor();
2910 //=============================================================================
2912 * Checks if there are groups with equal names
2914 //=============================================================================
2916 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2918 return _impl->HasDuplicatedGroupNamesMED();
2921 //================================================================================
2923 * \brief Care of a file before exporting mesh into it
2925 //================================================================================
2927 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2929 SMESH_File aFile( file );
2931 if (aFile.exists()) {
2932 // existing filesystem node
2933 if ( !aFile.isDirectory() ) {
2934 if ( aFile.openForWriting() ) {
2935 if ( overwrite && ! aFile.remove()) {
2936 msg << "Can't replace " << aFile.getName();
2939 msg << "Can't write into " << aFile.getName();
2942 msg << "Location " << aFile.getName() << " is not a file";
2946 // nonexisting file; check if it can be created
2947 if ( !aFile.openForWriting() ) {
2948 msg << "You cannot create the file "
2950 << ". Check the directory existance and access rights";
2958 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2962 //================================================================================
2964 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2965 * \param file - file name
2966 * \param overwrite - to erase the file or not
2967 * \retval string - mesh name
2969 //================================================================================
2971 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2972 CORBA::Boolean overwrite)
2975 PrepareForWriting(file, overwrite);
2976 string aMeshName = "Mesh";
2977 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2978 if ( !aStudy->_is_nil() ) {
2979 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2980 if ( !aMeshSO->_is_nil() ) {
2981 CORBA::String_var name = aMeshSO->GetName();
2983 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2984 if ( !aStudy->GetProperties()->IsLocked() )
2986 SALOMEDS::GenericAttribute_wrap anAttr;
2987 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2988 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2989 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2990 ASSERT(!aFileName->_is_nil());
2991 aFileName->SetValue(file);
2992 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2993 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2994 ASSERT(!aFileType->_is_nil());
2995 aFileType->SetValue("FICHIERMED");
2999 // Update Python script
3000 // set name of mesh before export
3001 TPythonDump() << _gen_i << ".SetName("
3002 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
3004 // check names of groups
3010 //================================================================================
3012 * \brief Export to med file
3014 //================================================================================
3016 void SMESH_Mesh_i::ExportToMEDX (const char* file,
3017 CORBA::Boolean auto_groups,
3018 SMESH::MED_VERSION theVersion,
3019 CORBA::Boolean overwrite,
3020 CORBA::Boolean autoDimension)
3021 throw(SALOME::SALOME_Exception)
3025 _preMeshInfo->FullLoadFromFile();
3027 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3028 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3030 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3031 << file << "', " << auto_groups << ", "
3032 << theVersion << ", " << overwrite << ", "
3033 << autoDimension << " )";
3035 SMESH_CATCH( SMESH::throwCorbaException );
3038 //================================================================================
3040 * \brief Export a mesh to a med file
3042 //================================================================================
3044 void SMESH_Mesh_i::ExportToMED (const char* file,
3045 CORBA::Boolean auto_groups,
3046 SMESH::MED_VERSION theVersion)
3047 throw(SALOME::SALOME_Exception)
3049 ExportToMEDX(file,auto_groups,theVersion,true);
3052 //================================================================================
3054 * \brief Export a mesh to a med file
3056 //================================================================================
3058 void SMESH_Mesh_i::ExportMED (const char* file,
3059 CORBA::Boolean auto_groups)
3060 throw(SALOME::SALOME_Exception)
3062 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3065 //================================================================================
3067 * \brief Export a mesh to a SAUV file
3069 //================================================================================
3071 void SMESH_Mesh_i::ExportSAUV (const char* file,
3072 CORBA::Boolean auto_groups)
3073 throw(SALOME::SALOME_Exception)
3075 Unexpect aCatch(SALOME_SalomeException);
3077 _preMeshInfo->FullLoadFromFile();
3079 string aMeshName = prepareMeshNameAndGroups(file, true);
3080 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3081 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3082 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3086 //================================================================================
3088 * \brief Export a mesh to a DAT file
3090 //================================================================================
3092 void SMESH_Mesh_i::ExportDAT (const char *file)
3093 throw(SALOME::SALOME_Exception)
3095 Unexpect aCatch(SALOME_SalomeException);
3097 _preMeshInfo->FullLoadFromFile();
3099 // Update Python script
3100 // check names of groups
3102 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3105 PrepareForWriting(file);
3106 _impl->ExportDAT(file);
3109 //================================================================================
3111 * \brief Export a mesh to an UNV file
3113 //================================================================================
3115 void SMESH_Mesh_i::ExportUNV (const char *file)
3116 throw(SALOME::SALOME_Exception)
3118 Unexpect aCatch(SALOME_SalomeException);
3120 _preMeshInfo->FullLoadFromFile();
3122 // Update Python script
3123 // check names of groups
3125 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3128 PrepareForWriting(file);
3129 _impl->ExportUNV(file);
3132 //================================================================================
3134 * \brief Export a mesh to an STL file
3136 //================================================================================
3138 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3139 throw(SALOME::SALOME_Exception)
3141 Unexpect aCatch(SALOME_SalomeException);
3143 _preMeshInfo->FullLoadFromFile();
3145 // Update Python script
3146 // check names of groups
3148 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3149 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3152 PrepareForWriting(file);
3153 _impl->ExportSTL(file, isascii);
3156 //================================================================================
3158 * \brief Export a part of mesh to a med file
3160 //================================================================================
3162 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3164 CORBA::Boolean auto_groups,
3165 SMESH::MED_VERSION version,
3166 CORBA::Boolean overwrite,
3167 CORBA::Boolean autoDimension,
3168 const GEOM::ListOfFields& fields,
3169 const char* geomAssocFields)
3170 throw (SALOME::SALOME_Exception)
3174 _preMeshInfo->FullLoadFromFile();
3177 bool have0dField = false;
3178 if ( fields.length() > 0 )
3180 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3181 if ( shapeToMesh->_is_nil() )
3182 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3184 for ( size_t i = 0; i < fields.length(); ++i )
3186 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3187 THROW_SALOME_CORBA_EXCEPTION
3188 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3189 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3190 if ( fieldShape->_is_nil() )
3191 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3192 if ( !fieldShape->IsSame( shapeToMesh ) )
3193 THROW_SALOME_CORBA_EXCEPTION
3194 ( "Field defined not on shape", SALOME::BAD_PARAM);
3195 if ( fields[i]->GetDimension() == 0 )
3198 if ( geomAssocFields )
3199 for ( int i = 0; geomAssocFields[i]; ++i )
3200 switch ( geomAssocFields[i] ) {
3201 case 'v':case 'e':case 'f':case 's': break;
3202 case 'V':case 'E':case 'F':case 'S': break;
3203 default: THROW_SALOME_CORBA_EXCEPTION
3204 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3208 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3212 string aMeshName = "Mesh";
3213 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3214 if ( CORBA::is_nil( meshPart ) ||
3215 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3217 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3218 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3219 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3220 meshDS = _impl->GetMeshDS();
3225 _preMeshInfo->FullLoadFromFile();
3227 PrepareForWriting(file, overwrite);
3229 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3230 if ( !aStudy->_is_nil() ) {
3231 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3232 if ( !SO->_is_nil() ) {
3233 CORBA::String_var name = SO->GetName();
3237 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3238 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3239 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3240 meshDS = tmpDSDeleter._obj = partDS;
3245 if ( _impl->HasShapeToMesh() )
3247 DriverMED_W_Field fieldWriter;
3248 fieldWriter.SetFile( file );
3249 fieldWriter.SetMeshName( aMeshName );
3250 fieldWriter.AddODOnVertices( have0dField );
3252 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3256 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3257 goList->length( fields.length() );
3258 for ( size_t i = 0; i < fields.length(); ++i )
3260 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3263 TPythonDump() << _this() << ".ExportPartToMED( "
3264 << meshPart << ", r'" << file << "', "
3265 << auto_groups << ", " << version << ", " << overwrite << ", "
3266 << autoDimension << ", " << goList
3267 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3269 SMESH_CATCH( SMESH::throwCorbaException );
3272 //================================================================================
3274 * Write GEOM fields to MED file
3276 //================================================================================
3278 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3279 SMESHDS_Mesh* meshDS,
3280 const GEOM::ListOfFields& fields,
3281 const char* geomAssocFields)
3283 #define METH "SMESH_Mesh_i::exportMEDFields() "
3285 if (( fields.length() < 1 ) &&
3286 ( !geomAssocFields || !geomAssocFields[0] ))
3289 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3290 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3291 std::vector< int > subIdsByDim[ 4 ];
3292 const double noneDblValue = 0.;
3293 const double noneIntValue = 0;
3295 for ( size_t iF = 0; iF < fields.length(); ++iF )
3299 int dim = fields[ iF ]->GetDimension();
3300 SMDSAbs_ElementType elemType;
3301 TopAbs_ShapeEnum shapeType;
3303 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3304 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3305 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3306 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3308 continue; // skip fields on whole shape
3310 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3311 if ( dataType == GEOM::FDT_String )
3313 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3314 if ( stepIDs->length() < 1 )
3316 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3317 if ( comps->length() < 1 )
3319 CORBA::String_var name = fields[ iF ]->GetName();
3321 if ( !fieldWriter.Set( meshDS,
3325 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3328 for ( size_t iC = 0; iC < comps->length(); ++iC )
3329 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3331 // find sub-shape IDs
3333 std::vector< int >& subIds = subIdsByDim[ dim ];
3334 if ( subIds.empty() )
3335 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3336 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3337 subIds.push_back( id );
3341 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3345 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3347 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3348 if ( step->_is_nil() )
3351 CORBA::Long stamp = step->GetStamp();
3352 CORBA::Long id = step->GetID();
3353 fieldWriter.SetDtIt( int( stamp ), int( id ));
3355 // fill dblVals or intVals
3358 case GEOM::FDT_Double:
3360 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3361 if ( dblStep->_is_nil() ) continue;
3362 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3363 if ( vv->length() != subIds.size() )
3364 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3365 for ( size_t i = 0; i < vv->length(); ++i )
3366 dblVals[ subIds[ i ]] = vv[ i ];
3371 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3372 if ( intStep->_is_nil() ) continue;
3373 GEOM::ListOfLong_var vv = intStep->GetValues();
3374 if ( vv->length() != subIds.size() )
3375 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3376 for ( size_t i = 0; i < vv->length(); ++i )
3377 intVals[ subIds[ i ]] = (int) vv[ i ];
3380 case GEOM::FDT_Bool:
3382 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3383 if ( boolStep->_is_nil() ) continue;
3384 GEOM::short_array_var vv = boolStep->GetValues();
3385 if ( vv->length() != subIds.size() )
3386 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3387 for ( size_t i = 0; i < vv->length(); ++i )
3388 intVals[ subIds[ i ]] = (int) vv[ i ];
3394 // pass values to fieldWriter
3395 elemIt = fieldWriter.GetOrderedElems();
3396 if ( dataType == GEOM::FDT_Double )
3397 while ( elemIt->more() )
3399 const SMDS_MeshElement* e = elemIt->next();
3400 const int shapeID = e->getshapeId();
3401 if ( shapeID < 1 || shapeID >= dblVals.size() )
3402 fieldWriter.AddValue( noneDblValue );
3404 fieldWriter.AddValue( dblVals[ shapeID ]);
3407 while ( elemIt->more() )
3409 const SMDS_MeshElement* e = elemIt->next();
3410 const int shapeID = e->getshapeId();
3411 if ( shapeID < 1 || shapeID >= intVals.size() )
3412 fieldWriter.AddValue( (double) noneIntValue );
3414 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3418 fieldWriter.Perform();
3419 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3420 if ( res && res->IsKO() )
3422 if ( res->myComment.empty() )
3423 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3425 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3431 if ( !geomAssocFields || !geomAssocFields[0] )
3434 // write geomAssocFields
3436 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3437 shapeDim[ TopAbs_COMPOUND ] = 3;
3438 shapeDim[ TopAbs_COMPSOLID ] = 3;
3439 shapeDim[ TopAbs_SOLID ] = 3;
3440 shapeDim[ TopAbs_SHELL ] = 2;
3441 shapeDim[ TopAbs_FACE ] = 2;
3442 shapeDim[ TopAbs_WIRE ] = 1;
3443 shapeDim[ TopAbs_EDGE ] = 1;
3444 shapeDim[ TopAbs_VERTEX ] = 0;
3445 shapeDim[ TopAbs_SHAPE ] = 3;
3447 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3449 std::vector< std::string > compNames;
3450 switch ( geomAssocFields[ iF ]) {
3452 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3453 compNames.push_back( "dim" );
3456 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3459 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3462 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3466 compNames.push_back( "id" );
3467 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3468 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3470 fieldWriter.SetDtIt( -1, -1 );
3472 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3476 if ( compNames.size() == 2 ) // _vertices_
3477 while ( elemIt->more() )
3479 const SMDS_MeshElement* e = elemIt->next();
3480 const int shapeID = e->getshapeId();
3483 fieldWriter.AddValue( (double) -1 );
3484 fieldWriter.AddValue( (double) -1 );
3488 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3489 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3490 fieldWriter.AddValue( (double) shapeID );
3494 while ( elemIt->more() )
3496 const SMDS_MeshElement* e = elemIt->next();
3497 const int shapeID = e->getshapeId();
3499 fieldWriter.AddValue( (double) -1 );
3501 fieldWriter.AddValue( (double) shapeID );
3505 fieldWriter.Perform();
3506 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3507 if ( res && res->IsKO() )
3509 if ( res->myComment.empty() )
3510 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3512 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3515 } // loop on geomAssocFields
3520 //================================================================================
3522 * \brief Export a part of mesh to a DAT file
3524 //================================================================================
3526 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3528 throw (SALOME::SALOME_Exception)
3530 Unexpect aCatch(SALOME_SalomeException);
3532 _preMeshInfo->FullLoadFromFile();
3534 PrepareForWriting(file);
3536 SMESH_MeshPartDS partDS( meshPart );
3537 _impl->ExportDAT(file,&partDS);
3539 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3540 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3542 //================================================================================
3544 * \brief Export a part of mesh to an UNV file
3546 //================================================================================
3548 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3550 throw (SALOME::SALOME_Exception)
3552 Unexpect aCatch(SALOME_SalomeException);
3554 _preMeshInfo->FullLoadFromFile();
3556 PrepareForWriting(file);
3558 SMESH_MeshPartDS partDS( meshPart );
3559 _impl->ExportUNV(file, &partDS);
3561 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3562 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3564 //================================================================================
3566 * \brief Export a part of mesh to an STL file
3568 //================================================================================
3570 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3572 ::CORBA::Boolean isascii)
3573 throw (SALOME::SALOME_Exception)
3575 Unexpect aCatch(SALOME_SalomeException);
3577 _preMeshInfo->FullLoadFromFile();
3579 PrepareForWriting(file);
3581 SMESH_MeshPartDS partDS( meshPart );
3582 _impl->ExportSTL(file, isascii, &partDS);
3584 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3585 << meshPart<< ", r'" << file << "', " << isascii << ")";
3588 //================================================================================
3590 * \brief Export a part of mesh to an STL file
3592 //================================================================================
3594 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3596 CORBA::Boolean overwrite)
3597 throw (SALOME::SALOME_Exception)
3600 Unexpect aCatch(SALOME_SalomeException);
3602 _preMeshInfo->FullLoadFromFile();
3604 PrepareForWriting(file,overwrite);
3606 std::string meshName("");
3607 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
3608 SALOMEDS::SObject_wrap so = _gen_i->ObjectToSObject( study, meshPart );
3609 if ( !so->_is_nil() )
3611 CORBA::String_var name = so->GetName();
3612 meshName = name.in();
3614 SMESH_MeshPartDS partDS( meshPart );
3615 _impl->ExportCGNS(file, &partDS, meshName.c_str() );
3617 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3618 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3620 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3624 //================================================================================
3626 * \brief Export a part of mesh to a GMF file
3628 //================================================================================
3630 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3632 bool withRequiredGroups)
3633 throw (SALOME::SALOME_Exception)
3635 Unexpect aCatch(SALOME_SalomeException);
3637 _preMeshInfo->FullLoadFromFile();
3639 PrepareForWriting(file,/*overwrite=*/true);
3641 SMESH_MeshPartDS partDS( meshPart );
3642 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3644 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3645 << meshPart<< ", r'"
3647 << withRequiredGroups << ")";
3650 //=============================================================================
3652 * Return computation progress [0.,1]
3654 //=============================================================================
3656 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3660 return _impl->GetComputeProgress();
3662 SMESH_CATCH( SMESH::doNothing );
3666 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3668 Unexpect aCatch(SALOME_SalomeException);
3670 return _preMeshInfo->NbNodes();
3672 return _impl->NbNodes();
3675 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3677 Unexpect aCatch(SALOME_SalomeException);
3679 return _preMeshInfo->NbElements();
3681 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3684 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3686 Unexpect aCatch(SALOME_SalomeException);
3688 return _preMeshInfo->Nb0DElements();
3690 return _impl->Nb0DElements();
3693 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3695 Unexpect aCatch(SALOME_SalomeException);
3697 return _preMeshInfo->NbBalls();
3699 return _impl->NbBalls();
3702 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3704 Unexpect aCatch(SALOME_SalomeException);
3706 return _preMeshInfo->NbEdges();
3708 return _impl->NbEdges();
3711 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3712 throw(SALOME::SALOME_Exception)
3714 Unexpect aCatch(SALOME_SalomeException);
3716 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3718 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3721 //=============================================================================
3723 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3725 Unexpect aCatch(SALOME_SalomeException);
3727 return _preMeshInfo->NbFaces();
3729 return _impl->NbFaces();
3732 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3734 Unexpect aCatch(SALOME_SalomeException);
3736 return _preMeshInfo->NbTriangles();
3738 return _impl->NbTriangles();
3741 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3743 Unexpect aCatch(SALOME_SalomeException);
3745 return _preMeshInfo->NbBiQuadTriangles();
3747 return _impl->NbBiQuadTriangles();
3750 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 return _preMeshInfo->NbQuadrangles();
3756 return _impl->NbQuadrangles();
3759 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3763 return _preMeshInfo->NbBiQuadQuadrangles();
3765 return _impl->NbBiQuadQuadrangles();
3768 CORBA::Long SMESH_Mesh_i::NbPolygons(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3774 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3777 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3778 throw(SALOME::SALOME_Exception)
3780 Unexpect aCatch(SALOME_SalomeException);
3782 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3784 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3787 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3788 throw(SALOME::SALOME_Exception)
3790 Unexpect aCatch(SALOME_SalomeException);
3792 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3794 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3797 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3798 throw(SALOME::SALOME_Exception)
3800 Unexpect aCatch(SALOME_SalomeException);
3802 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3804 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3807 //=============================================================================
3809 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3811 Unexpect aCatch(SALOME_SalomeException);
3813 return _preMeshInfo->NbVolumes();
3815 return _impl->NbVolumes();
3818 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3820 Unexpect aCatch(SALOME_SalomeException);
3822 return _preMeshInfo->NbTetras();
3824 return _impl->NbTetras();
3827 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3829 Unexpect aCatch(SALOME_SalomeException);
3831 return _preMeshInfo->NbHexas();
3833 return _impl->NbHexas();
3836 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3838 Unexpect aCatch(SALOME_SalomeException);
3840 return _preMeshInfo->NbTriQuadHexas();
3842 return _impl->NbTriQuadraticHexas();
3845 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3847 Unexpect aCatch(SALOME_SalomeException);
3849 return _preMeshInfo->NbPyramids();
3851 return _impl->NbPyramids();
3854 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3856 Unexpect aCatch(SALOME_SalomeException);
3858 return _preMeshInfo->NbPrisms();
3860 return _impl->NbPrisms();
3863 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbHexPrisms();
3869 return _impl->NbHexagonalPrisms();
3872 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 return _preMeshInfo->NbPolyhedrons();
3878 return _impl->NbPolyhedrons();
3881 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3882 throw(SALOME::SALOME_Exception)
3884 Unexpect aCatch(SALOME_SalomeException);
3886 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3888 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3891 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3892 throw(SALOME::SALOME_Exception)
3894 Unexpect aCatch(SALOME_SalomeException);
3896 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3898 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3901 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3902 throw(SALOME::SALOME_Exception)
3904 Unexpect aCatch(SALOME_SalomeException);
3906 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3908 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3911 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3912 throw(SALOME::SALOME_Exception)
3914 Unexpect aCatch(SALOME_SalomeException);
3916 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3918 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3921 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3922 throw(SALOME::SALOME_Exception)
3924 Unexpect aCatch(SALOME_SalomeException);
3926 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3928 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3931 //=============================================================================
3933 * Returns nb of published sub-meshes
3935 //=============================================================================
3937 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3939 Unexpect aCatch(SALOME_SalomeException);
3940 return _mapSubMesh_i.size();
3943 //=============================================================================
3945 * Dumps mesh into a string
3947 //=============================================================================
3949 char* SMESH_Mesh_i::Dump()
3953 return CORBA::string_dup( os.str().c_str() );
3956 //=============================================================================
3958 * Method of SMESH_IDSource interface
3960 //=============================================================================
3962 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3964 return GetElementsId();
3967 //=============================================================================
3969 * Returns ids of all elements
3971 //=============================================================================
3973 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3974 throw (SALOME::SALOME_Exception)
3976 Unexpect aCatch(SALOME_SalomeException);
3978 _preMeshInfo->FullLoadFromFile();
3980 SMESH::long_array_var aResult = new SMESH::long_array();
3981 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3983 if ( aSMESHDS_Mesh == NULL )
3984 return aResult._retn();
3986 long nbElements = NbElements();
3987 aResult->length( nbElements );
3988 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3989 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3990 aResult[i] = anIt->next()->GetID();
3992 return aResult._retn();
3996 //=============================================================================
3998 * Returns ids of all elements of given type
4000 //=============================================================================
4002 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4003 throw (SALOME::SALOME_Exception)
4005 Unexpect aCatch(SALOME_SalomeException);
4007 _preMeshInfo->FullLoadFromFile();
4009 SMESH::long_array_var aResult = new SMESH::long_array();
4010 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4012 if ( aSMESHDS_Mesh == NULL )
4013 return aResult._retn();
4015 long nbElements = NbElements();
4017 // No sense in returning ids of elements along with ids of nodes:
4018 // when theElemType == SMESH::ALL, return node ids only if
4019 // there are no elements
4020 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4021 return GetNodesId();
4023 aResult->length( nbElements );
4027 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4028 while ( i < nbElements && anIt->more() )
4029 aResult[i++] = anIt->next()->GetID();
4031 aResult->length( i );
4033 return aResult._retn();
4036 //=============================================================================
4038 * Returns ids of all nodes
4040 //=============================================================================
4042 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4043 throw (SALOME::SALOME_Exception)
4045 Unexpect aCatch(SALOME_SalomeException);
4047 _preMeshInfo->FullLoadFromFile();
4049 SMESH::long_array_var aResult = new SMESH::long_array();
4050 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4052 if ( aSMESHDS_Mesh == NULL )
4053 return aResult._retn();
4055 long nbNodes = NbNodes();
4056 aResult->length( nbNodes );
4057 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4058 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4059 aResult[i] = anIt->next()->GetID();
4061 return aResult._retn();
4064 //=============================================================================
4068 //=============================================================================
4070 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4071 throw (SALOME::SALOME_Exception)
4073 SMESH::ElementType type;
4077 _preMeshInfo->FullLoadFromFile();
4079 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4081 SMESH_CATCH( SMESH::throwCorbaException );
4086 //=============================================================================
4090 //=============================================================================
4092 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4093 throw (SALOME::SALOME_Exception)
4096 _preMeshInfo->FullLoadFromFile();
4098 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4100 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4102 return ( SMESH::EntityType ) e->GetEntityType();
4105 //=============================================================================
4109 //=============================================================================
4111 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4112 throw (SALOME::SALOME_Exception)
4115 _preMeshInfo->FullLoadFromFile();
4117 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4119 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4121 return ( SMESH::GeometryType ) e->GetGeomType();
4124 //=============================================================================
4126 * Returns ID of elements for given submesh
4128 //=============================================================================
4129 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4130 throw (SALOME::SALOME_Exception)
4132 SMESH::long_array_var aResult = new SMESH::long_array();
4136 _preMeshInfo->FullLoadFromFile();
4138 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4139 if(!SM) return aResult._retn();
4141 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4142 if(!SDSM) return aResult._retn();
4144 aResult->length(SDSM->NbElements());
4146 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4148 while ( eIt->more() ) {
4149 aResult[i++] = eIt->next()->GetID();
4152 SMESH_CATCH( SMESH::throwCorbaException );
4154 return aResult._retn();
4157 //=============================================================================
4159 * Returns ID of nodes for given submesh
4160 * If param all==true - returns all nodes, else -
4161 * returns only nodes on shapes.
4163 //=============================================================================
4165 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4167 throw (SALOME::SALOME_Exception)
4169 SMESH::long_array_var aResult = new SMESH::long_array();
4173 _preMeshInfo->FullLoadFromFile();
4175 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4176 if(!SM) return aResult._retn();
4178 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4179 if(!SDSM) return aResult._retn();
4182 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4183 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4184 while ( nIt->more() ) {
4185 const SMDS_MeshNode* elem = nIt->next();
4186 theElems.insert( elem->GetID() );
4189 else { // all nodes of submesh elements
4190 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4191 while ( eIt->more() ) {
4192 const SMDS_MeshElement* anElem = eIt->next();
4193 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4194 while ( nIt->more() ) {
4195 const SMDS_MeshElement* elem = nIt->next();
4196 theElems.insert( elem->GetID() );
4201 aResult->length(theElems.size());
4202 set<int>::iterator itElem;
4204 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4205 aResult[i++] = *itElem;
4207 SMESH_CATCH( SMESH::throwCorbaException );
4209 return aResult._retn();
4212 //=============================================================================
4214 * Returns type of elements for given submesh
4216 //=============================================================================
4218 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4219 throw (SALOME::SALOME_Exception)
4221 SMESH::ElementType type;
4225 _preMeshInfo->FullLoadFromFile();
4227 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4228 if(!SM) return SMESH::ALL;
4230 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4231 if(!SDSM) return SMESH::ALL;
4233 if(SDSM->NbElements()==0)
4234 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4236 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4237 const SMDS_MeshElement* anElem = eIt->next();
4239 type = ( SMESH::ElementType ) anElem->GetType();
4241 SMESH_CATCH( SMESH::throwCorbaException );
4247 //=============================================================================
4249 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4251 //=============================================================================
4253 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4256 _preMeshInfo->FullLoadFromFile();
4258 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4260 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4265 //=============================================================================
4267 * Get XYZ coordinates of node as list of double
4268 * If there is not node for given ID - returns empty list
4270 //=============================================================================
4272 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4275 _preMeshInfo->FullLoadFromFile();
4277 SMESH::double_array_var aResult = new SMESH::double_array();
4278 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4279 if ( aSMESHDS_Mesh == NULL )
4280 return aResult._retn();
4283 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4285 return aResult._retn();
4289 aResult[0] = aNode->X();
4290 aResult[1] = aNode->Y();
4291 aResult[2] = aNode->Z();
4292 return aResult._retn();
4296 //=============================================================================
4298 * For given node returns list of IDs of inverse elements
4299 * If there is not node for given ID - returns empty list
4301 //=============================================================================
4303 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4306 _preMeshInfo->FullLoadFromFile();
4308 SMESH::long_array_var aResult = new SMESH::long_array();
4309 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4310 if ( aSMESHDS_Mesh == NULL )
4311 return aResult._retn();
4314 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4316 return aResult._retn();
4318 // find inverse elements
4319 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4320 aResult->length( aNode->NbInverseElements() );
4321 for( int i = 0; eIt->more(); ++i )
4323 const SMDS_MeshElement* elem = eIt->next();
4324 aResult[ i ] = elem->GetID();
4326 return aResult._retn();
4329 //=============================================================================
4331 * \brief Return position of a node on shape
4333 //=============================================================================
4335 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4338 _preMeshInfo->FullLoadFromFile();
4340 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4341 aNodePosition->shapeID = 0;
4342 aNodePosition->shapeType = GEOM::SHAPE;
4344 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4345 if ( !mesh ) return aNodePosition;
4347 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4349 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4351 aNodePosition->shapeID = aNode->getshapeId();
4352 switch ( pos->GetTypeOfPosition() ) {
4354 aNodePosition->shapeType = GEOM::EDGE;
4355 aNodePosition->params.length(1);
4356 aNodePosition->params[0] =
4357 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4360 aNodePosition->shapeType = GEOM::FACE;
4361 aNodePosition->params.length(2);
4362 aNodePosition->params[0] =
4363 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4364 aNodePosition->params[1] =
4365 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4367 case SMDS_TOP_VERTEX:
4368 aNodePosition->shapeType = GEOM::VERTEX;
4370 case SMDS_TOP_3DSPACE:
4371 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4372 aNodePosition->shapeType = GEOM::SOLID;
4373 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4374 aNodePosition->shapeType = GEOM::SHELL;
4380 return aNodePosition;
4383 //=============================================================================
4385 * \brief Return position of an element on shape
4387 //=============================================================================
4389 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4392 _preMeshInfo->FullLoadFromFile();
4394 SMESH::ElementPosition anElementPosition;
4395 anElementPosition.shapeID = 0;
4396 anElementPosition.shapeType = GEOM::SHAPE;
4398 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4399 if ( !mesh ) return anElementPosition;
4401 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4403 anElementPosition.shapeID = anElem->getshapeId();
4404 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4405 if ( !aSp.IsNull() ) {
4406 switch ( aSp.ShapeType() ) {
4408 anElementPosition.shapeType = GEOM::EDGE;
4411 anElementPosition.shapeType = GEOM::FACE;
4414 anElementPosition.shapeType = GEOM::VERTEX;
4417 anElementPosition.shapeType = GEOM::SOLID;
4420 anElementPosition.shapeType = GEOM::SHELL;
4426 return anElementPosition;
4429 //=============================================================================
4431 * If given element is node returns IDs of shape from position
4432 * If there is not node for given ID - returns -1
4434 //=============================================================================
4436 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4439 _preMeshInfo->FullLoadFromFile();
4441 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4442 if ( aSMESHDS_Mesh == NULL )
4446 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4448 return aNode->getshapeId();
4455 //=============================================================================
4457 * For given element returns ID of result shape after
4458 * ::FindShape() from SMESH_MeshEditor
4459 * If there is not element for given ID - returns -1
4461 //=============================================================================
4463 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4466 _preMeshInfo->FullLoadFromFile();
4468 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4469 if ( aSMESHDS_Mesh == NULL )
4472 // try to find element
4473 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4477 ::SMESH_MeshEditor aMeshEditor(_impl);
4478 int index = aMeshEditor.FindShape( elem );
4486 //=============================================================================
4488 * Returns number of nodes for given element
4489 * If there is not element for given ID - returns -1
4491 //=============================================================================
4493 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4496 _preMeshInfo->FullLoadFromFile();
4498 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4499 if ( aSMESHDS_Mesh == NULL ) return -1;
4500 // try to find element
4501 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4502 if(!elem) return -1;
4503 return elem->NbNodes();
4507 //=============================================================================
4509 * Returns ID of node by given index for given element
4510 * If there is not element for given ID - returns -1
4511 * If there is not node for given index - returns -2
4513 //=============================================================================
4515 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4518 _preMeshInfo->FullLoadFromFile();
4520 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4521 if ( aSMESHDS_Mesh == NULL ) return -1;
4522 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4523 if(!elem) return -1;
4524 if( index>=elem->NbNodes() || index<0 ) return -1;
4525 return elem->GetNode(index)->GetID();
4528 //=============================================================================
4530 * Returns IDs of nodes of given element
4532 //=============================================================================
4534 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4537 _preMeshInfo->FullLoadFromFile();
4539 SMESH::long_array_var aResult = new SMESH::long_array();
4540 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4542 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4544 aResult->length( elem->NbNodes() );
4545 for ( int i = 0; i < elem->NbNodes(); ++i )
4546 aResult[ i ] = elem->GetNode( i )->GetID();
4549 return aResult._retn();
4552 //=============================================================================
4554 * Returns true if given node is medium node
4555 * in given quadratic element
4557 //=============================================================================
4559 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4562 _preMeshInfo->FullLoadFromFile();
4564 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4565 if ( aSMESHDS_Mesh == NULL ) return false;
4567 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4568 if(!aNode) return false;
4569 // try to find element
4570 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4571 if(!elem) return false;
4573 return elem->IsMediumNode(aNode);
4577 //=============================================================================
4579 * Returns true if given node is medium node
4580 * in one of quadratic elements
4582 //=============================================================================
4584 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4585 SMESH::ElementType theElemType)
4588 _preMeshInfo->FullLoadFromFile();
4590 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4591 if ( aSMESHDS_Mesh == NULL ) return false;
4594 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4595 if(!aNode) return false;
4597 SMESH_MesherHelper aHelper( *(_impl) );
4599 SMDSAbs_ElementType aType;
4600 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4601 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4602 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4603 else aType = SMDSAbs_All;
4605 return aHelper.IsMedium(aNode,aType);
4609 //=============================================================================
4611 * Returns number of edges for given element
4613 //=============================================================================
4615 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4618 _preMeshInfo->FullLoadFromFile();
4620 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4621 if ( aSMESHDS_Mesh == NULL ) return -1;
4622 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4623 if(!elem) return -1;
4624 return elem->NbEdges();
4628 //=============================================================================
4630 * Returns number of faces for given element
4632 //=============================================================================
4634 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4637 _preMeshInfo->FullLoadFromFile();
4639 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4640 if ( aSMESHDS_Mesh == NULL ) return -1;
4641 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4642 if(!elem) return -1;
4643 return elem->NbFaces();
4646 //=======================================================================
4647 //function : GetElemFaceNodes
4648 //purpose : Returns nodes of given face (counted from zero) for given element.
4649 //=======================================================================
4651 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4652 CORBA::Short faceIndex)
4655 _preMeshInfo->FullLoadFromFile();
4657 SMESH::long_array_var aResult = new SMESH::long_array();
4658 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4660 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4662 SMDS_VolumeTool vtool( elem );
4663 if ( faceIndex < vtool.NbFaces() )
4665 aResult->length( vtool.NbFaceNodes( faceIndex ));
4666 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4667 for ( int i = 0; i < aResult->length(); ++i )
4668 aResult[ i ] = nn[ i ]->GetID();
4672 return aResult._retn();
4675 //=======================================================================
4676 //function : GetElemFaceNodes
4677 //purpose : Returns three components of normal of given mesh face.
4678 //=======================================================================
4680 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4681 CORBA::Boolean normalized)
4684 _preMeshInfo->FullLoadFromFile();
4686 SMESH::double_array_var aResult = new SMESH::double_array();
4688 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4691 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4693 aResult->length( 3 );
4694 aResult[ 0 ] = normal.X();
4695 aResult[ 1 ] = normal.Y();
4696 aResult[ 2 ] = normal.Z();
4699 return aResult._retn();
4702 //=======================================================================
4703 //function : FindElementByNodes
4704 //purpose : Returns an element based on all given nodes.
4705 //=======================================================================
4707 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4710 _preMeshInfo->FullLoadFromFile();
4712 CORBA::Long elemID(0);
4713 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4715 vector< const SMDS_MeshNode * > nn( nodes.length() );
4716 for ( int i = 0; i < nodes.length(); ++i )
4717 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4720 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4721 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4722 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4723 _impl->NbVolumes( ORDER_QUADRATIC )))
4724 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4726 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4731 //=============================================================================
4733 * Returns true if given element is polygon
4735 //=============================================================================
4737 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4740 _preMeshInfo->FullLoadFromFile();
4742 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4743 if ( aSMESHDS_Mesh == NULL ) return false;
4744 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4745 if(!elem) return false;
4746 return elem->IsPoly();
4750 //=============================================================================
4752 * Returns true if given element is quadratic
4754 //=============================================================================
4756 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4759 _preMeshInfo->FullLoadFromFile();
4761 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4762 if ( aSMESHDS_Mesh == NULL ) return false;
4763 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4764 if(!elem) return false;
4765 return elem->IsQuadratic();
4768 //=============================================================================
4770 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4772 //=============================================================================
4774 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4777 _preMeshInfo->FullLoadFromFile();
4779 if ( const SMDS_BallElement* ball =
4780 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4781 return ball->GetDiameter();
4786 //=============================================================================
4788 * Returns bary center for given element
4790 //=============================================================================
4792 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4795 _preMeshInfo->FullLoadFromFile();
4797 SMESH::double_array_var aResult = new SMESH::double_array();
4798 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4799 if ( aSMESHDS_Mesh == NULL )
4800 return aResult._retn();
4802 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4804 return aResult._retn();
4806 if(elem->GetType()==SMDSAbs_Volume) {
4807 SMDS_VolumeTool aTool;
4808 if(aTool.Set(elem)) {
4810 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4815 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4817 double x=0., y=0., z=0.;
4818 for(; anIt->more(); ) {
4820 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4834 return aResult._retn();
4837 //================================================================================
4839 * \brief Create a group of elements preventing computation of a sub-shape
4841 //================================================================================
4843 SMESH::ListOfGroups*
4844 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4845 const char* theGroupName )
4846 throw ( SALOME::SALOME_Exception )
4848 Unexpect aCatch(SALOME_SalomeException);
4850 if ( !theGroupName || strlen( theGroupName) == 0 )
4851 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4853 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4854 ::SMESH_MeshEditor::ElemFeatures elemType;
4856 // submesh by subshape id
4857 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4858 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4861 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4862 if ( error && !error->myBadElements.empty())
4864 // sort bad elements by type
4865 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4866 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4867 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4868 for ( ; elemIt != elemEnd; ++elemIt )
4870 const SMDS_MeshElement* elem = *elemIt;
4871 if ( !elem ) continue;
4873 if ( elem->GetID() < 1 )
4875 // elem is a temporary element, make a real element
4876 vector< const SMDS_MeshNode* > nodes;
4877 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4878 while ( nIt->more() && elem )
4880 nodes.push_back( nIt->next() );
4881 if ( nodes.back()->GetID() < 1 )
4882 elem = 0; // a temporary element on temporary nodes
4886 ::SMESH_MeshEditor editor( _impl );
4887 elem = editor.AddElement( nodes, elemType.Init( elem ));
4891 elemsByType[ elem->GetType() ].push_back( elem );
4894 // how many groups to create?
4896 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4897 nbTypes += int( !elemsByType[ i ].empty() );
4898 groups->length( nbTypes );
4901 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4903 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4904 if ( elems.empty() ) continue;
4906 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4907 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4909 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4910 SMESH::SMESH_Mesh_var mesh = _this();
4911 SALOMEDS::SObject_wrap aSO =
4912 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4913 GEOM::GEOM_Object::_nil(), theGroupName);
4915 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4916 if ( !grp_i ) continue;
4918 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4919 for ( size_t iE = 0; iE < elems.size(); ++iE )
4920 grpDS->SMDSGroup().Add( elems[ iE ]);
4925 return groups._retn();
4928 //=============================================================================
4930 * Create and publish group servants if any groups were imported or created anyhow
4932 //=============================================================================
4934 void SMESH_Mesh_i::CreateGroupServants()
4936 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4937 SMESH::SMESH_Mesh_var aMesh = _this();
4940 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4941 while ( groupIt->more() )
4943 ::SMESH_Group* group = groupIt->next();
4944 int anId = group->GetGroupDS()->GetID();
4946 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4947 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4949 addedIDs.insert( anId );
4951 SMESH_GroupBase_i* aGroupImpl;
4953 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4954 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4956 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4957 shape = groupOnGeom->GetShape();
4960 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4963 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4964 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4965 aGroupImpl->Register();
4967 // register CORBA object for persistence
4968 int nextId = _gen_i->RegisterObject( groupVar );
4969 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4970 else { nextId = 0; } // avoid "unused variable" warning in release mode
4972 // publishing the groups in the study
4973 if ( !aStudy->_is_nil() ) {
4974 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4975 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4978 if ( !addedIDs.empty() )
4981 set<int>::iterator id = addedIDs.begin();
4982 for ( ; id != addedIDs.end(); ++id )
4984 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4985 int i = std::distance( _mapGroups.begin(), it );
4986 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4991 //=============================================================================
4993 * \brief Return groups cantained in _mapGroups by their IDs
4995 //=============================================================================
4997 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4999 int nbGroups = groupIDs.size();
5000 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5001 aList->length( nbGroups );
5003 list<int>::const_iterator ids = groupIDs.begin();
5004 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5006 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5007 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5008 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5010 aList->length( nbGroups );
5011 return aList._retn();
5014 //=============================================================================
5016 * \brief Return information about imported file
5018 //=============================================================================
5020 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5022 SMESH::MedFileInfo_var res( _medFileInfo );
5023 if ( !res.operator->() ) {
5024 res = new SMESH::MedFileInfo;
5026 res->fileSize = res->major = res->minor = res->release = -1;
5031 //=============================================================================
5033 * \brief Pass names of mesh groups from study to mesh DS
5035 //=============================================================================
5037 void SMESH_Mesh_i::checkGroupNames()
5039 int nbGrp = NbGroups();
5043 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5044 if ( aStudy->_is_nil() )
5045 return; // nothing to do
5047 SMESH::ListOfGroups* grpList = 0;
5048 // avoid dump of "GetGroups"
5050 // store python dump into a local variable inside local scope
5051 SMESH::TPythonDump pDump; // do not delete this line of code
5052 grpList = GetGroups();
5055 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5056 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5059 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5060 if ( aGrpSO->_is_nil() )
5062 // correct name of the mesh group if necessary
5063 const char* guiName = aGrpSO->GetName();
5064 if ( strcmp(guiName, aGrp->GetName()) )
5065 aGrp->SetName( guiName );
5069 //=============================================================================
5071 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5073 //=============================================================================
5074 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5076 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5080 //=============================================================================
5082 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5084 //=============================================================================
5086 char* SMESH_Mesh_i::GetParameters()
5088 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5091 //=============================================================================
5093 * \brief Returns list of notebook variables used for last Mesh operation
5095 //=============================================================================
5096 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5098 SMESH::string_array_var aResult = new SMESH::string_array();
5099 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5101 CORBA::String_var aParameters = GetParameters();
5102 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5103 if ( !aStudy->_is_nil()) {
5104 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5105 if(aSections->length() > 0) {
5106 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5107 aResult->length(aVars.length());
5108 for(int i = 0;i < aVars.length();i++)
5109 aResult[i] = CORBA::string_dup( aVars[i]);
5113 return aResult._retn();
5116 //=======================================================================
5117 //function : GetTypes
5118 //purpose : Returns types of elements it contains
5119 //=======================================================================
5121 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5124 return _preMeshInfo->GetTypes();
5126 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5130 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5131 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5132 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5133 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5134 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5135 types->length( nbTypes );
5137 return types._retn();
5140 //=======================================================================
5141 //function : GetMesh
5142 //purpose : Returns self
5143 //=======================================================================
5145 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5147 return SMESH::SMESH_Mesh::_duplicate( _this() );
5150 //=======================================================================
5151 //function : IsMeshInfoCorrect
5152 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5153 // * happen if mesh data is not yet fully loaded from the file of study.
5154 //=======================================================================
5156 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5158 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5161 //=============================================================================
5163 * \brief Returns number of mesh elements per each \a EntityType
5165 //=============================================================================
5167 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5170 return _preMeshInfo->GetMeshInfo();
5172 SMESH::long_array_var aRes = new SMESH::long_array();
5173 aRes->length(SMESH::Entity_Last);
5174 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5176 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5178 return aRes._retn();
5179 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5180 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5181 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5182 return aRes._retn();
5185 //=============================================================================
5187 * \brief Returns number of mesh elements per each \a ElementType
5189 //=============================================================================
5191 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5193 SMESH::long_array_var aRes = new SMESH::long_array();
5194 aRes->length(SMESH::NB_ELEMENT_TYPES);
5195 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5198 const SMDS_MeshInfo* meshInfo = 0;
5200 meshInfo = _preMeshInfo;
5201 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5202 meshInfo = & meshDS->GetMeshInfo();
5205 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5206 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5208 return aRes._retn();
5211 //=============================================================================
5213 * Collect statistic of mesh elements given by iterator
5215 //=============================================================================
5217 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5218 SMESH::long_array& theInfo)
5220 if (!theItr) return;
5221 while (theItr->more())
5222 theInfo[ theItr->next()->GetEntityType() ]++;
5224 //=============================================================================
5226 * Returns mesh unstructed grid information.
5228 //=============================================================================
5230 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5232 SALOMEDS::TMPFile_var SeqFile;
5233 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5234 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5236 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5237 aWriter->WriteToOutputStringOn();
5238 aWriter->SetInputData(aGrid);
5239 aWriter->SetFileTypeToBinary();
5241 char* str = aWriter->GetOutputString();
5242 int size = aWriter->GetOutputStringLength();
5244 //Allocate octect buffer of required size
5245 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5246 //Copy ostrstream content to the octect buffer
5247 memcpy(OctetBuf, str, size);
5248 //Create and return TMPFile
5249 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5253 return SeqFile._retn();
5256 //=============================================================================
5257 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5258 * SMESH::ElementType type) */
5260 using namespace SMESH::Controls;
5261 //-----------------------------------------------------------------------------
5262 struct PredicateIterator : public SMDS_ElemIterator
5264 SMDS_ElemIteratorPtr _elemIter;
5265 PredicatePtr _predicate;
5266 const SMDS_MeshElement* _elem;
5268 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5269 PredicatePtr predicate):
5270 _elemIter(iterator), _predicate(predicate)
5278 virtual const SMDS_MeshElement* next()
5280 const SMDS_MeshElement* res = _elem;
5282 while ( _elemIter->more() && !_elem )
5284 _elem = _elemIter->next();
5285 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5292 //-----------------------------------------------------------------------------
5293 struct IDSourceIterator : public SMDS_ElemIterator
5295 const CORBA::Long* _idPtr;
5296 const CORBA::Long* _idEndPtr;
5297 SMESH::long_array_var _idArray;
5298 const SMDS_Mesh* _mesh;
5299 const SMDSAbs_ElementType _type;
5300 const SMDS_MeshElement* _elem;
5302 IDSourceIterator( const SMDS_Mesh* mesh,
5303 const CORBA::Long* ids,
5305 SMDSAbs_ElementType type):
5306 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5308 if ( _idPtr && nbIds && _mesh )
5311 IDSourceIterator( const SMDS_Mesh* mesh,
5312 SMESH::long_array* idArray,
5313 SMDSAbs_ElementType type):
5314 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5316 if ( idArray && _mesh )
5318 _idPtr = &_idArray[0];
5319 _idEndPtr = _idPtr + _idArray->length();
5327 virtual const SMDS_MeshElement* next()
5329 const SMDS_MeshElement* res = _elem;
5331 while ( _idPtr < _idEndPtr && !_elem )
5333 if ( _type == SMDSAbs_Node )
5335 _elem = _mesh->FindNode( *_idPtr++ );
5337 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5338 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5346 //-----------------------------------------------------------------------------
5348 struct NodeOfElemIterator : public SMDS_ElemIterator
5350 TColStd_MapOfInteger _checkedNodeIDs;
5351 SMDS_ElemIteratorPtr _elemIter;
5352 SMDS_ElemIteratorPtr _nodeIter;
5353 const SMDS_MeshElement* _node;
5355 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5357 if ( _elemIter && _elemIter->more() )
5359 _nodeIter = _elemIter->next()->nodesIterator();
5367 virtual const SMDS_MeshElement* next()
5369 const SMDS_MeshElement* res = _node;
5371 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5373 if ( _nodeIter->more() )
5375 _node = _nodeIter->next();
5376 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5381 _nodeIter = _elemIter->next()->nodesIterator();
5389 //=============================================================================
5391 * Return iterator on elements of given type in given object
5393 //=============================================================================
5395 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5396 SMESH::ElementType theType)
5398 SMDS_ElemIteratorPtr elemIt;
5399 bool typeOK = false;
5400 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5402 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5403 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5404 if ( !mesh_i ) return elemIt;
5405 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5407 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5409 elemIt = meshDS->elementsIterator( elemType );
5412 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5414 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5417 elemIt = sm->GetElements();
5418 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5420 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5421 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5425 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5427 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5428 if ( groupDS && ( elemType == groupDS->GetType() ||
5429 elemType == SMDSAbs_Node ||
5430 elemType == SMDSAbs_All ))
5432 elemIt = groupDS->GetElements();
5433 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5436 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5438 if ( filter_i->GetElementType() == theType ||
5439 elemType == SMDSAbs_Node ||
5440 elemType == SMDSAbs_All)
5442 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5443 if ( pred_i && pred_i->GetPredicate() )
5445 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5446 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5447 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5448 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5454 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5455 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5456 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5458 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5461 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5462 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5466 SMESH::long_array_var ids = theObject->GetIDs();
5467 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5469 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5472 if ( elemIt && elemIt->more() && !typeOK )
5474 if ( elemType == SMDSAbs_Node )
5476 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5480 elemIt = SMDS_ElemIteratorPtr();
5486 //=============================================================================
5487 namespace // Finding concurrent hypotheses
5488 //=============================================================================
5492 * \brief mapping of mesh dimension into shape type
5494 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5496 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5498 case 0: aType = TopAbs_VERTEX; break;
5499 case 1: aType = TopAbs_EDGE; break;
5500 case 2: aType = TopAbs_FACE; break;
5502 default:aType = TopAbs_SOLID; break;
5507 //-----------------------------------------------------------------------------
5509 * \brief Internal structure used to find concurent submeshes
5511 * It represents a pair < submesh, concurent dimension >, where
5512 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5513 * with another submesh. In other words, it is dimension of a hypothesis assigned
5520 int _dim; //!< a dimension the algo can build (concurrent dimension)
5521 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5522 TopTools_MapOfShape _shapeMap;
5523 SMESH_subMesh* _subMesh;
5524 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5526 //-----------------------------------------------------------------------------
5527 // Return the algorithm
5528 const SMESH_Algo* GetAlgo() const
5529 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5531 //-----------------------------------------------------------------------------
5533 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5535 const TopoDS_Shape& theShape)
5537 _subMesh = (SMESH_subMesh*)theSubMesh;
5538 SetShape( theDim, theShape );
5541 //-----------------------------------------------------------------------------
5543 void SetShape(const int theDim,
5544 const TopoDS_Shape& theShape)
5547 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5548 if (_dim >= _ownDim)
5549 _shapeMap.Add( theShape );
5551 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5552 for( ; anExp.More(); anExp.Next() )
5553 _shapeMap.Add( anExp.Current() );
5557 //-----------------------------------------------------------------------------
5558 //! Check sharing of sub-shapes
5559 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5560 const TopTools_MapOfShape& theToFind,
5561 const TopAbs_ShapeEnum theType)
5563 bool isShared = false;
5564 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5565 for (; !isShared && anItr.More(); anItr.Next() )
5567 const TopoDS_Shape aSubSh = anItr.Key();
5568 // check for case when concurrent dimensions are same
5569 isShared = theToFind.Contains( aSubSh );
5570 // check for sub-shape with concurrent dimension
5571 TopExp_Explorer anExp( aSubSh, theType );
5572 for ( ; !isShared && anExp.More(); anExp.Next() )
5573 isShared = theToFind.Contains( anExp.Current() );
5578 //-----------------------------------------------------------------------------
5579 //! check algorithms
5580 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5581 const SMESHDS_Hypothesis* theA2)
5583 if ( !theA1 || !theA2 ||
5584 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5585 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5586 return false; // one of the hypothesis is not algorithm
5587 // check algorithm names (should be equal)
5588 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5592 //-----------------------------------------------------------------------------
5593 //! Check if sub-shape hypotheses are concurrent
5594 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5596 if ( _subMesh == theOther->_subMesh )
5597 return false; // same sub-shape - should not be
5599 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5600 // any of the two submeshes is not on COMPOUND shape )
5601 // -> no concurrency
5602 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5603 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5604 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5605 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5606 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5609 // bool checkSubShape = ( _dim >= theOther->_dim )
5610 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5611 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5612 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5613 if ( !checkSubShape )
5616 // check algorithms to be same
5617 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5618 return true; // different algorithms -> concurrency !
5620 // check hypothesises for concurrence (skip first as algorithm)
5622 // pointers should be same, because it is referened from mesh hypothesis partition
5623 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5624 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5625 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5626 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5628 // the submeshes are concurrent if their algorithms has different parameters
5629 return nbSame != theOther->_hypotheses.size() - 1;
5632 // Return true if algorithm of this SMESH_DimHyp is used if no
5633 // sub-mesh order is imposed by the user
5634 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5636 // NeedDiscreteBoundary() algo has a higher priority
5637 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5638 theOther->GetAlgo()->NeedDiscreteBoundary() )
5639 return !this->GetAlgo()->NeedDiscreteBoundary();
5641 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5644 }; // end of SMESH_DimHyp
5645 //-----------------------------------------------------------------------------
5647 typedef list<const SMESH_DimHyp*> TDimHypList;
5649 //-----------------------------------------------------------------------------
5651 void addDimHypInstance(const int theDim,
5652 const TopoDS_Shape& theShape,
5653 const SMESH_Algo* theAlgo,
5654 const SMESH_subMesh* theSubMesh,
5655 const list <const SMESHDS_Hypothesis*>& theHypList,
5656 TDimHypList* theDimHypListArr )
5658 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5659 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5660 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5661 dimHyp->_hypotheses.push_front(theAlgo);
5662 listOfdimHyp.push_back( dimHyp );
5665 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5666 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5667 theHypList.begin(), theHypList.end() );
5670 //-----------------------------------------------------------------------------
5671 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5672 TDimHypList& theListOfConcurr)
5674 if ( theListOfConcurr.empty() )
5676 theListOfConcurr.push_back( theDimHyp );
5680 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5681 while ( hypIt != theListOfConcurr.end() &&
5682 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5684 theListOfConcurr.insert( hypIt, theDimHyp );
5688 //-----------------------------------------------------------------------------
5689 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5690 const TDimHypList& theListOfDimHyp,
5691 TDimHypList& theListOfConcurrHyp,
5692 set<int>& theSetOfConcurrId )
5694 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5695 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5697 const SMESH_DimHyp* curDimHyp = *rIt;
5698 if ( curDimHyp == theDimHyp )
5699 break; // meet own dimHyp pointer in same dimension
5701 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5702 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5704 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5709 //-----------------------------------------------------------------------------
5710 void unionLists(TListOfInt& theListOfId,
5711 TListOfListOfInt& theListOfListOfId,
5714 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5715 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5717 continue; //skip already treated lists
5718 // check if other list has any same submesh object
5719 TListOfInt& otherListOfId = *it;
5720 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5721 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5724 // union two lists (from source into target)
5725 TListOfInt::iterator it2 = otherListOfId.begin();
5726 for ( ; it2 != otherListOfId.end(); it2++ ) {
5727 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5728 theListOfId.push_back(*it2);
5730 // clear source list
5731 otherListOfId.clear();
5734 //-----------------------------------------------------------------------------
5736 //! free memory allocated for dimension-hypothesis objects
5737 void removeDimHyps( TDimHypList* theArrOfList )
5739 for (int i = 0; i < 4; i++ ) {
5740 TDimHypList& listOfdimHyp = theArrOfList[i];
5741 TDimHypList::const_iterator it = listOfdimHyp.begin();
5742 for ( ; it != listOfdimHyp.end(); it++ )
5747 //-----------------------------------------------------------------------------
5749 * \brief find common submeshes with given submesh
5750 * \param theSubMeshList list of already collected submesh to check
5751 * \param theSubMesh given submesh to intersect with other
5752 * \param theCommonSubMeshes collected common submeshes
5754 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5755 const SMESH_subMesh* theSubMesh,
5756 set<const SMESH_subMesh*>& theCommon )
5760 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5761 for ( ; it != theSubMeshList.end(); it++ )
5762 theSubMesh->FindIntersection( *it, theCommon );
5763 theSubMeshList.push_back( theSubMesh );
5764 //theCommon.insert( theSubMesh );
5767 //-----------------------------------------------------------------------------
5768 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5770 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5771 for ( ; listsIt != smLists.end(); ++listsIt )
5773 const TListOfInt& smIDs = *listsIt;
5774 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5782 //=============================================================================
5784 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5786 //=============================================================================
5788 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5790 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5791 if ( isSubMeshInList( submeshID, anOrder ))
5794 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5795 return isSubMeshInList( submeshID, allConurrent );
5798 //=============================================================================
5800 * \brief Return submesh objects list in meshing order
5802 //=============================================================================
5804 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5806 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5808 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5810 return aResult._retn();
5812 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5813 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5814 anOrder.splice( anOrder.end(), allConurrent );
5817 TListOfListOfInt::iterator listIt = anOrder.begin();
5818 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5819 unionLists( *listIt, anOrder, listIndx + 1 );
5821 // convert submesh ids into interface instances
5822 // and dump command into python
5823 convertMeshOrder( anOrder, aResult, false );
5825 return aResult._retn();
5828 //=============================================================================
5830 * \brief Finds concurrent sub-meshes
5832 //=============================================================================
5834 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5836 TListOfListOfInt anOrder;
5837 ::SMESH_Mesh& mesh = GetImpl();
5839 // collect submeshes and detect concurrent algorithms and hypothesises
5840 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5842 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5843 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5844 ::SMESH_subMesh* sm = (*i_sm).second;
5846 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5848 // list of assigned hypothesises
5849 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5850 // Find out dimensions where the submesh can be concurrent.
5851 // We define the dimensions by algo of each of hypotheses in hypList
5852 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5853 for( ; hypIt != hypList.end(); hypIt++ ) {
5854 SMESH_Algo* anAlgo = 0;
5855 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5856 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5857 // hyp it-self is algo
5858 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5860 // try to find algorithm with help of sub-shapes
5861 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5862 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5863 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5866 continue; // no algorithm assigned to a current submesh
5868 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5869 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5871 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5872 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5873 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5875 } // end iterations on submesh
5877 // iterate on created dimension-hypotheses and check for concurrents
5878 for ( int i = 0; i < 4; i++ ) {
5879 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5880 // check for concurrents in own and other dimensions (step-by-step)
5881 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5882 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5883 const SMESH_DimHyp* dimHyp = *dhIt;
5884 TDimHypList listOfConcurr;
5885 set<int> setOfConcurrIds;
5886 // looking for concurrents and collect into own list
5887 for ( int j = i; j < 4; j++ )
5888 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5889 // check if any concurrents found
5890 if ( listOfConcurr.size() > 0 ) {
5891 // add own submesh to list of concurrent
5892 addInOrderOfPriority( dimHyp, listOfConcurr );
5893 list<int> listOfConcurrIds;
5894 TDimHypList::iterator hypIt = listOfConcurr.begin();
5895 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5896 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5897 anOrder.push_back( listOfConcurrIds );
5902 removeDimHyps(dimHypListArr);
5904 // now, minimise the number of concurrent groups
5905 // Here we assume that lists of submeshes can have same submesh
5906 // in case of multi-dimension algorithms, as result
5907 // list with common submesh has to be united into one list
5909 TListOfListOfInt::iterator listIt = anOrder.begin();
5910 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5911 unionLists( *listIt, anOrder, listIndx + 1 );
5917 //=============================================================================
5919 * \brief Set submesh object order
5920 * \param theSubMeshArray submesh array order
5922 //=============================================================================
5924 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5927 _preMeshInfo->ForgetOrLoad();
5930 ::SMESH_Mesh& mesh = GetImpl();
5932 TPythonDump aPythonDump; // prevent dump of called methods
5933 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5935 TListOfListOfInt subMeshOrder;
5936 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5938 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5939 TListOfInt subMeshIds;
5941 aPythonDump << ", ";
5942 aPythonDump << "[ ";
5943 // Collect subMeshes which should be clear
5944 // do it list-by-list, because modification of submesh order
5945 // take effect between concurrent submeshes only
5946 set<const SMESH_subMesh*> subMeshToClear;
5947 list<const SMESH_subMesh*> subMeshList;
5948 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5950 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5952 aPythonDump << ", ";
5953 aPythonDump << subMesh;
5954 subMeshIds.push_back( subMesh->GetId() );
5955 // detect common parts of submeshes
5956 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5957 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5959 aPythonDump << " ]";
5960 subMeshOrder.push_back( subMeshIds );
5962 // clear collected submeshes
5963 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5964 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5965 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5966 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5968 aPythonDump << " ])";
5970 mesh.SetMeshOrder( subMeshOrder );
5976 //=============================================================================
5978 * \brief Convert submesh ids into submesh interfaces
5980 //=============================================================================
5982 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5983 SMESH::submesh_array_array& theResOrder,
5984 const bool theIsDump)
5986 int nbSet = theIdsOrder.size();
5987 TPythonDump aPythonDump; // prevent dump of called methods
5989 aPythonDump << "[ ";
5990 theResOrder.length(nbSet);
5991 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5993 for( ; it != theIdsOrder.end(); it++ ) {
5994 // translate submesh identificators into submesh objects
5995 // takeing into account real number of concurrent lists
5996 const TListOfInt& aSubOrder = (*it);
5997 if (!aSubOrder.size())
6000 aPythonDump << "[ ";
6001 // convert shape indeces into interfaces
6002 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6003 aResSubSet->length(aSubOrder.size());
6004 TListOfInt::const_iterator subIt = aSubOrder.begin();
6006 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6007 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6009 SMESH::SMESH_subMesh_var subMesh =
6010 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6013 aPythonDump << ", ";
6014 aPythonDump << subMesh;
6016 aResSubSet[ j++ ] = subMesh;
6019 aPythonDump << " ]";
6021 theResOrder[ listIndx++ ] = aResSubSet;
6023 // correct number of lists
6024 theResOrder.length( listIndx );
6027 // finilise python dump
6028 aPythonDump << " ]";
6029 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6033 //================================================================================
6035 // Implementation of SMESH_MeshPartDS
6037 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6038 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6040 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6041 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6043 _meshDS = mesh_i->GetImpl().GetMeshDS();
6045 SetPersistentId( _meshDS->GetPersistentId() );
6047 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6049 // <meshPart> is the whole mesh
6050 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6052 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6053 myGroupSet = _meshDS->GetGroups();
6058 SMESH::long_array_var anIDs = meshPart->GetIDs();
6059 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6060 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6062 for (int i=0; i < anIDs->length(); i++)
6063 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6064 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6069 for (int i=0; i < anIDs->length(); i++)
6070 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6071 if ( _elements[ e->GetType() ].insert( e ).second )
6074 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6075 while ( nIt->more() )
6077 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6078 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6085 ShapeToMesh( _meshDS->ShapeToMesh() );
6087 _meshDS = 0; // to enforce iteration on _elements and _nodes
6090 // -------------------------------------------------------------------------------------
6091 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6092 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6095 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6096 for ( ; partIt != meshPart.end(); ++partIt )
6097 if ( const SMDS_MeshElement * e = *partIt )
6098 if ( _elements[ e->GetType() ].insert( e ).second )
6101 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6102 while ( nIt->more() )
6104 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6105 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6111 // -------------------------------------------------------------------------------------
6112 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6114 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6116 typedef SMDS_SetIterator
6117 <const SMDS_MeshElement*,
6118 TIDSortedElemSet::const_iterator,
6119 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6120 SMDS_MeshElement::GeomFilter
6123 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6125 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6126 _elements[type].end(),
6127 SMDS_MeshElement::GeomFilter( geomType )));
6129 // -------------------------------------------------------------------------------------
6130 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6132 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6134 typedef SMDS_SetIterator
6135 <const SMDS_MeshElement*,
6136 TIDSortedElemSet::const_iterator,
6137 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6138 SMDS_MeshElement::EntityFilter
6141 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6143 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6144 _elements[type].end(),
6145 SMDS_MeshElement::EntityFilter( entity )));
6147 // -------------------------------------------------------------------------------------
6148 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6150 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6151 if ( type == SMDSAbs_All && !_meshDS )
6153 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6155 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6156 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6158 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6160 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6161 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6163 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6164 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6166 // -------------------------------------------------------------------------------------
6167 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6168 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6170 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6171 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6172 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6174 // -------------------------------------------------------------------------------------
6175 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6176 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6177 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6178 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6179 #undef _GET_ITER_DEFINE
6181 // END Implementation of SMESH_MeshPartDS
6183 //================================================================================