1 // Copyright (C) 2007-2016 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->ForgetOrLoad(); // load in case if !HasShapeToMesh()
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() >= (int) 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 ( CORBA::ULong 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 ( CORBA::ULong 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 >= (int) 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 >= (int) 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() throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbPolygons();
3774 return _impl->NbPolygons();
3777 CORBA::Long SMESH_Mesh_i::NbPolygonsOfOrder(SMESH::ElementOrder order) throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbPolygons((SMDSAbs_ElementOrder) order);
3783 return _impl->NbPolygons((SMDSAbs_ElementOrder)order);
3786 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3787 throw(SALOME::SALOME_Exception)
3789 Unexpect aCatch(SALOME_SalomeException);
3791 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3793 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3796 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3797 throw(SALOME::SALOME_Exception)
3799 Unexpect aCatch(SALOME_SalomeException);
3801 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3803 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3806 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3807 throw(SALOME::SALOME_Exception)
3809 Unexpect aCatch(SALOME_SalomeException);
3811 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3813 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3816 //=============================================================================
3818 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3820 Unexpect aCatch(SALOME_SalomeException);
3822 return _preMeshInfo->NbVolumes();
3824 return _impl->NbVolumes();
3827 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3829 Unexpect aCatch(SALOME_SalomeException);
3831 return _preMeshInfo->NbTetras();
3833 return _impl->NbTetras();
3836 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3838 Unexpect aCatch(SALOME_SalomeException);
3840 return _preMeshInfo->NbHexas();
3842 return _impl->NbHexas();
3845 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3847 Unexpect aCatch(SALOME_SalomeException);
3849 return _preMeshInfo->NbTriQuadHexas();
3851 return _impl->NbTriQuadraticHexas();
3854 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3856 Unexpect aCatch(SALOME_SalomeException);
3858 return _preMeshInfo->NbPyramids();
3860 return _impl->NbPyramids();
3863 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbPrisms();
3869 return _impl->NbPrisms();
3872 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3874 Unexpect aCatch(SALOME_SalomeException);
3876 return _preMeshInfo->NbHexPrisms();
3878 return _impl->NbHexagonalPrisms();
3881 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3883 Unexpect aCatch(SALOME_SalomeException);
3885 return _preMeshInfo->NbPolyhedrons();
3887 return _impl->NbPolyhedrons();
3890 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3891 throw(SALOME::SALOME_Exception)
3893 Unexpect aCatch(SALOME_SalomeException);
3895 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3897 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3900 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3901 throw(SALOME::SALOME_Exception)
3903 Unexpect aCatch(SALOME_SalomeException);
3905 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3907 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3910 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3911 throw(SALOME::SALOME_Exception)
3913 Unexpect aCatch(SALOME_SalomeException);
3915 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3917 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3920 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3921 throw(SALOME::SALOME_Exception)
3923 Unexpect aCatch(SALOME_SalomeException);
3925 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3927 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3930 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3931 throw(SALOME::SALOME_Exception)
3933 Unexpect aCatch(SALOME_SalomeException);
3935 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3937 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3940 //=============================================================================
3942 * Returns nb of published sub-meshes
3944 //=============================================================================
3946 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3948 Unexpect aCatch(SALOME_SalomeException);
3949 return _mapSubMesh_i.size();
3952 //=============================================================================
3954 * Dumps mesh into a string
3956 //=============================================================================
3958 char* SMESH_Mesh_i::Dump()
3962 return CORBA::string_dup( os.str().c_str() );
3965 //=============================================================================
3967 * Method of SMESH_IDSource interface
3969 //=============================================================================
3971 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3973 return GetElementsId();
3976 //=============================================================================
3978 * Returns ids of all elements
3980 //=============================================================================
3982 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3983 throw (SALOME::SALOME_Exception)
3985 Unexpect aCatch(SALOME_SalomeException);
3987 _preMeshInfo->FullLoadFromFile();
3989 SMESH::long_array_var aResult = new SMESH::long_array();
3990 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3992 if ( aSMESHDS_Mesh == NULL )
3993 return aResult._retn();
3995 long nbElements = NbElements();
3996 aResult->length( nbElements );
3997 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3998 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3999 aResult[i] = anIt->next()->GetID();
4001 return aResult._retn();
4005 //=============================================================================
4007 * Returns ids of all elements of given type
4009 //=============================================================================
4011 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
4012 throw (SALOME::SALOME_Exception)
4014 Unexpect aCatch(SALOME_SalomeException);
4016 _preMeshInfo->FullLoadFromFile();
4018 SMESH::long_array_var aResult = new SMESH::long_array();
4019 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4021 if ( aSMESHDS_Mesh == NULL )
4022 return aResult._retn();
4024 long nbElements = NbElements();
4026 // No sense in returning ids of elements along with ids of nodes:
4027 // when theElemType == SMESH::ALL, return node ids only if
4028 // there are no elements
4029 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
4030 return GetNodesId();
4032 aResult->length( nbElements );
4036 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
4037 while ( i < nbElements && anIt->more() )
4038 aResult[i++] = anIt->next()->GetID();
4040 aResult->length( i );
4042 return aResult._retn();
4045 //=============================================================================
4047 * Returns ids of all nodes
4049 //=============================================================================
4051 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4052 throw (SALOME::SALOME_Exception)
4054 Unexpect aCatch(SALOME_SalomeException);
4056 _preMeshInfo->FullLoadFromFile();
4058 SMESH::long_array_var aResult = new SMESH::long_array();
4059 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4061 if ( aSMESHDS_Mesh == NULL )
4062 return aResult._retn();
4064 long nbNodes = NbNodes();
4065 aResult->length( nbNodes );
4066 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4067 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4068 aResult[i] = anIt->next()->GetID();
4070 return aResult._retn();
4073 //=============================================================================
4077 //=============================================================================
4079 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4080 throw (SALOME::SALOME_Exception)
4082 SMESH::ElementType type;
4086 _preMeshInfo->FullLoadFromFile();
4088 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4090 SMESH_CATCH( SMESH::throwCorbaException );
4095 //=============================================================================
4099 //=============================================================================
4101 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4102 throw (SALOME::SALOME_Exception)
4105 _preMeshInfo->FullLoadFromFile();
4107 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4109 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4111 return ( SMESH::EntityType ) e->GetEntityType();
4114 //=============================================================================
4118 //=============================================================================
4120 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4121 throw (SALOME::SALOME_Exception)
4124 _preMeshInfo->FullLoadFromFile();
4126 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4128 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4130 return ( SMESH::GeometryType ) e->GetGeomType();
4133 //=============================================================================
4135 * Returns ID of elements for given submesh
4137 //=============================================================================
4138 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4139 throw (SALOME::SALOME_Exception)
4141 SMESH::long_array_var aResult = new SMESH::long_array();
4145 _preMeshInfo->FullLoadFromFile();
4147 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4148 if(!SM) return aResult._retn();
4150 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4151 if(!SDSM) return aResult._retn();
4153 aResult->length(SDSM->NbElements());
4155 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4157 while ( eIt->more() ) {
4158 aResult[i++] = eIt->next()->GetID();
4161 SMESH_CATCH( SMESH::throwCorbaException );
4163 return aResult._retn();
4166 //=============================================================================
4168 * Returns ID of nodes for given submesh
4169 * If param all==true - returns all nodes, else -
4170 * returns only nodes on shapes.
4172 //=============================================================================
4174 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4176 throw (SALOME::SALOME_Exception)
4178 SMESH::long_array_var aResult = new SMESH::long_array();
4182 _preMeshInfo->FullLoadFromFile();
4184 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4185 if(!SM) return aResult._retn();
4187 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4188 if(!SDSM) return aResult._retn();
4191 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4192 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4193 while ( nIt->more() ) {
4194 const SMDS_MeshNode* elem = nIt->next();
4195 theElems.insert( elem->GetID() );
4198 else { // all nodes of submesh elements
4199 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4200 while ( eIt->more() ) {
4201 const SMDS_MeshElement* anElem = eIt->next();
4202 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4203 while ( nIt->more() ) {
4204 const SMDS_MeshElement* elem = nIt->next();
4205 theElems.insert( elem->GetID() );
4210 aResult->length(theElems.size());
4211 set<int>::iterator itElem;
4213 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4214 aResult[i++] = *itElem;
4216 SMESH_CATCH( SMESH::throwCorbaException );
4218 return aResult._retn();
4221 //=============================================================================
4223 * Returns type of elements for given submesh
4225 //=============================================================================
4227 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4228 throw (SALOME::SALOME_Exception)
4230 SMESH::ElementType type;
4234 _preMeshInfo->FullLoadFromFile();
4236 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4237 if(!SM) return SMESH::ALL;
4239 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4240 if(!SDSM) return SMESH::ALL;
4242 if(SDSM->NbElements()==0)
4243 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4245 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4246 const SMDS_MeshElement* anElem = eIt->next();
4248 type = ( SMESH::ElementType ) anElem->GetType();
4250 SMESH_CATCH( SMESH::throwCorbaException );
4256 //=============================================================================
4258 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4260 //=============================================================================
4262 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4265 _preMeshInfo->FullLoadFromFile();
4267 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4269 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4274 //=============================================================================
4276 * Get XYZ coordinates of node as list of double
4277 * If there is not node for given ID - returns empty list
4279 //=============================================================================
4281 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4284 _preMeshInfo->FullLoadFromFile();
4286 SMESH::double_array_var aResult = new SMESH::double_array();
4287 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4288 if ( aSMESHDS_Mesh == NULL )
4289 return aResult._retn();
4292 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4294 return aResult._retn();
4298 aResult[0] = aNode->X();
4299 aResult[1] = aNode->Y();
4300 aResult[2] = aNode->Z();
4301 return aResult._retn();
4305 //=============================================================================
4307 * For given node returns list of IDs of inverse elements
4308 * If there is not node for given ID - returns empty list
4310 //=============================================================================
4312 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4315 _preMeshInfo->FullLoadFromFile();
4317 SMESH::long_array_var aResult = new SMESH::long_array();
4318 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4319 if ( aSMESHDS_Mesh == NULL )
4320 return aResult._retn();
4323 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4325 return aResult._retn();
4327 // find inverse elements
4328 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4329 aResult->length( aNode->NbInverseElements() );
4330 for( int i = 0; eIt->more(); ++i )
4332 const SMDS_MeshElement* elem = eIt->next();
4333 aResult[ i ] = elem->GetID();
4335 return aResult._retn();
4338 //=============================================================================
4340 * \brief Return position of a node on shape
4342 //=============================================================================
4344 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4347 _preMeshInfo->FullLoadFromFile();
4349 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4350 aNodePosition->shapeID = 0;
4351 aNodePosition->shapeType = GEOM::SHAPE;
4353 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4354 if ( !mesh ) return aNodePosition;
4356 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4358 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4360 aNodePosition->shapeID = aNode->getshapeId();
4361 switch ( pos->GetTypeOfPosition() ) {
4363 aNodePosition->shapeType = GEOM::EDGE;
4364 aNodePosition->params.length(1);
4365 aNodePosition->params[0] =
4366 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4369 aNodePosition->shapeType = GEOM::FACE;
4370 aNodePosition->params.length(2);
4371 aNodePosition->params[0] =
4372 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4373 aNodePosition->params[1] =
4374 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4376 case SMDS_TOP_VERTEX:
4377 aNodePosition->shapeType = GEOM::VERTEX;
4379 case SMDS_TOP_3DSPACE:
4380 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4381 aNodePosition->shapeType = GEOM::SOLID;
4382 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4383 aNodePosition->shapeType = GEOM::SHELL;
4389 return aNodePosition;
4392 //=============================================================================
4394 * \brief Return position of an element on shape
4396 //=============================================================================
4398 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4401 _preMeshInfo->FullLoadFromFile();
4403 SMESH::ElementPosition anElementPosition;
4404 anElementPosition.shapeID = 0;
4405 anElementPosition.shapeType = GEOM::SHAPE;
4407 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4408 if ( !mesh ) return anElementPosition;
4410 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4412 anElementPosition.shapeID = anElem->getshapeId();
4413 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4414 if ( !aSp.IsNull() ) {
4415 switch ( aSp.ShapeType() ) {
4417 anElementPosition.shapeType = GEOM::EDGE;
4420 anElementPosition.shapeType = GEOM::FACE;
4423 anElementPosition.shapeType = GEOM::VERTEX;
4426 anElementPosition.shapeType = GEOM::SOLID;
4429 anElementPosition.shapeType = GEOM::SHELL;
4435 return anElementPosition;
4438 //=============================================================================
4440 * If given element is node returns IDs of shape from position
4441 * If there is not node for given ID - returns -1
4443 //=============================================================================
4445 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4448 _preMeshInfo->FullLoadFromFile();
4450 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4451 if ( aSMESHDS_Mesh == NULL )
4455 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4457 return aNode->getshapeId();
4464 //=============================================================================
4466 * For given element returns ID of result shape after
4467 * ::FindShape() from SMESH_MeshEditor
4468 * If there is not element for given ID - returns -1
4470 //=============================================================================
4472 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4475 _preMeshInfo->FullLoadFromFile();
4477 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4478 if ( aSMESHDS_Mesh == NULL )
4481 // try to find element
4482 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4486 ::SMESH_MeshEditor aMeshEditor(_impl);
4487 int index = aMeshEditor.FindShape( elem );
4495 //=============================================================================
4497 * Returns number of nodes for given element
4498 * If there is not element for given ID - returns -1
4500 //=============================================================================
4502 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4505 _preMeshInfo->FullLoadFromFile();
4507 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4508 if ( aSMESHDS_Mesh == NULL ) return -1;
4509 // try to find element
4510 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4511 if(!elem) return -1;
4512 return elem->NbNodes();
4516 //=============================================================================
4518 * Returns ID of node by given index for given element
4519 * If there is not element for given ID - returns -1
4520 * If there is not node for given index - returns -2
4522 //=============================================================================
4524 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4527 _preMeshInfo->FullLoadFromFile();
4529 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4530 if ( aSMESHDS_Mesh == NULL ) return -1;
4531 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4532 if(!elem) return -1;
4533 if( index>=elem->NbNodes() || index<0 ) return -1;
4534 return elem->GetNode(index)->GetID();
4537 //=============================================================================
4539 * Returns IDs of nodes of given element
4541 //=============================================================================
4543 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4546 _preMeshInfo->FullLoadFromFile();
4548 SMESH::long_array_var aResult = new SMESH::long_array();
4549 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4551 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4553 aResult->length( elem->NbNodes() );
4554 for ( int i = 0; i < elem->NbNodes(); ++i )
4555 aResult[ i ] = elem->GetNode( i )->GetID();
4558 return aResult._retn();
4561 //=============================================================================
4563 * Returns true if given node is medium node
4564 * in given quadratic element
4566 //=============================================================================
4568 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4571 _preMeshInfo->FullLoadFromFile();
4573 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4574 if ( aSMESHDS_Mesh == NULL ) return false;
4576 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4577 if(!aNode) return false;
4578 // try to find element
4579 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4580 if(!elem) return false;
4582 return elem->IsMediumNode(aNode);
4586 //=============================================================================
4588 * Returns true if given node is medium node
4589 * in one of quadratic elements
4591 //=============================================================================
4593 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4594 SMESH::ElementType theElemType)
4597 _preMeshInfo->FullLoadFromFile();
4599 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4600 if ( aSMESHDS_Mesh == NULL ) return false;
4603 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4604 if(!aNode) return false;
4606 SMESH_MesherHelper aHelper( *(_impl) );
4608 SMDSAbs_ElementType aType;
4609 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4610 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4611 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4612 else aType = SMDSAbs_All;
4614 return aHelper.IsMedium(aNode,aType);
4618 //=============================================================================
4620 * Returns number of edges for given element
4622 //=============================================================================
4624 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4627 _preMeshInfo->FullLoadFromFile();
4629 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4630 if ( aSMESHDS_Mesh == NULL ) return -1;
4631 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4632 if(!elem) return -1;
4633 return elem->NbEdges();
4637 //=============================================================================
4639 * Returns number of faces for given element
4641 //=============================================================================
4643 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4646 _preMeshInfo->FullLoadFromFile();
4648 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4649 if ( aSMESHDS_Mesh == NULL ) return -1;
4650 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4651 if(!elem) return -1;
4652 return elem->NbFaces();
4655 //=======================================================================
4656 //function : GetElemFaceNodes
4657 //purpose : Returns nodes of given face (counted from zero) for given element.
4658 //=======================================================================
4660 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4661 CORBA::Short faceIndex)
4664 _preMeshInfo->FullLoadFromFile();
4666 SMESH::long_array_var aResult = new SMESH::long_array();
4667 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4669 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4671 SMDS_VolumeTool vtool( elem );
4672 if ( faceIndex < vtool.NbFaces() )
4674 aResult->length( vtool.NbFaceNodes( faceIndex ));
4675 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4676 for ( CORBA::ULong i = 0; i < aResult->length(); ++i )
4677 aResult[ i ] = nn[ i ]->GetID();
4681 return aResult._retn();
4684 //=======================================================================
4685 //function : GetElemFaceNodes
4686 //purpose : Returns three components of normal of given mesh face.
4687 //=======================================================================
4689 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4690 CORBA::Boolean normalized)
4693 _preMeshInfo->FullLoadFromFile();
4695 SMESH::double_array_var aResult = new SMESH::double_array();
4697 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4700 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4702 aResult->length( 3 );
4703 aResult[ 0 ] = normal.X();
4704 aResult[ 1 ] = normal.Y();
4705 aResult[ 2 ] = normal.Z();
4708 return aResult._retn();
4711 //=======================================================================
4712 //function : FindElementByNodes
4713 //purpose : Returns an element based on all given nodes.
4714 //=======================================================================
4716 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4719 _preMeshInfo->FullLoadFromFile();
4721 CORBA::Long elemID(0);
4722 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4724 vector< const SMDS_MeshNode * > nn( nodes.length() );
4725 for ( CORBA::ULong i = 0; i < nodes.length(); ++i )
4726 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4729 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4730 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4731 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4732 _impl->NbVolumes( ORDER_QUADRATIC )))
4733 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4735 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4740 //=============================================================================
4742 * Returns true if given element is polygon
4744 //=============================================================================
4746 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4749 _preMeshInfo->FullLoadFromFile();
4751 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4752 if ( aSMESHDS_Mesh == NULL ) return false;
4753 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4754 if(!elem) return false;
4755 return elem->IsPoly();
4759 //=============================================================================
4761 * Returns true if given element is quadratic
4763 //=============================================================================
4765 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4768 _preMeshInfo->FullLoadFromFile();
4770 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4771 if ( aSMESHDS_Mesh == NULL ) return false;
4772 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4773 if(!elem) return false;
4774 return elem->IsQuadratic();
4777 //=============================================================================
4779 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4781 //=============================================================================
4783 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4786 _preMeshInfo->FullLoadFromFile();
4788 if ( const SMDS_BallElement* ball =
4789 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4790 return ball->GetDiameter();
4795 //=============================================================================
4797 * Returns bary center for given element
4799 //=============================================================================
4801 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4804 _preMeshInfo->FullLoadFromFile();
4806 SMESH::double_array_var aResult = new SMESH::double_array();
4807 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4808 if ( aSMESHDS_Mesh == NULL )
4809 return aResult._retn();
4811 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4813 return aResult._retn();
4815 if(elem->GetType()==SMDSAbs_Volume) {
4816 SMDS_VolumeTool aTool;
4817 if(aTool.Set(elem)) {
4819 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4824 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4826 double x=0., y=0., z=0.;
4827 for(; anIt->more(); ) {
4829 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4843 return aResult._retn();
4846 //================================================================================
4848 * \brief Create a group of elements preventing computation of a sub-shape
4850 //================================================================================
4852 SMESH::ListOfGroups*
4853 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4854 const char* theGroupName )
4855 throw ( SALOME::SALOME_Exception )
4857 Unexpect aCatch(SALOME_SalomeException);
4859 if ( !theGroupName || strlen( theGroupName) == 0 )
4860 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4862 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4863 ::SMESH_MeshEditor::ElemFeatures elemType;
4865 // submesh by subshape id
4866 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4867 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4870 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4871 if ( error && !error->myBadElements.empty())
4873 // sort bad elements by type
4874 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4875 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4876 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4877 for ( ; elemIt != elemEnd; ++elemIt )
4879 const SMDS_MeshElement* elem = *elemIt;
4880 if ( !elem ) continue;
4882 if ( elem->GetID() < 1 )
4884 // elem is a temporary element, make a real element
4885 vector< const SMDS_MeshNode* > nodes;
4886 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4887 while ( nIt->more() && elem )
4889 nodes.push_back( nIt->next() );
4890 if ( nodes.back()->GetID() < 1 )
4891 elem = 0; // a temporary element on temporary nodes
4895 ::SMESH_MeshEditor editor( _impl );
4896 elem = editor.AddElement( nodes, elemType.Init( elem ));
4900 elemsByType[ elem->GetType() ].push_back( elem );
4903 // how many groups to create?
4905 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4906 nbTypes += int( !elemsByType[ i ].empty() );
4907 groups->length( nbTypes );
4910 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4912 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4913 if ( elems.empty() ) continue;
4915 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4916 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4918 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4919 SMESH::SMESH_Mesh_var mesh = _this();
4920 SALOMEDS::SObject_wrap aSO =
4921 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4922 GEOM::GEOM_Object::_nil(), theGroupName);
4924 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4925 if ( !grp_i ) continue;
4927 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4928 for ( size_t iE = 0; iE < elems.size(); ++iE )
4929 grpDS->SMDSGroup().Add( elems[ iE ]);
4934 return groups._retn();
4937 //=============================================================================
4939 * Create and publish group servants if any groups were imported or created anyhow
4941 //=============================================================================
4943 void SMESH_Mesh_i::CreateGroupServants()
4945 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4946 SMESH::SMESH_Mesh_var aMesh = _this();
4949 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4950 while ( groupIt->more() )
4952 ::SMESH_Group* group = groupIt->next();
4953 int anId = group->GetGroupDS()->GetID();
4955 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4956 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4958 addedIDs.insert( anId );
4960 SMESH_GroupBase_i* aGroupImpl;
4962 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4963 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4965 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4966 shape = groupOnGeom->GetShape();
4969 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4972 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4973 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4974 aGroupImpl->Register();
4976 // register CORBA object for persistence
4977 int nextId = _gen_i->RegisterObject( groupVar );
4978 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4979 else { nextId = 0; } // avoid "unused variable" warning in release mode
4981 // publishing the groups in the study
4982 if ( !aStudy->_is_nil() ) {
4983 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4984 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4987 if ( !addedIDs.empty() )
4990 set<int>::iterator id = addedIDs.begin();
4991 for ( ; id != addedIDs.end(); ++id )
4993 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4994 int i = std::distance( _mapGroups.begin(), it );
4995 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
5000 //=============================================================================
5002 * \brief Return groups cantained in _mapGroups by their IDs
5004 //=============================================================================
5006 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
5008 int nbGroups = groupIDs.size();
5009 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
5010 aList->length( nbGroups );
5012 list<int>::const_iterator ids = groupIDs.begin();
5013 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
5015 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
5016 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
5017 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
5019 aList->length( nbGroups );
5020 return aList._retn();
5023 //=============================================================================
5025 * \brief Return information about imported file
5027 //=============================================================================
5029 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
5031 SMESH::MedFileInfo_var res( _medFileInfo );
5032 if ( !res.operator->() ) {
5033 res = new SMESH::MedFileInfo;
5035 res->fileSize = res->major = res->minor = res->release = -1;
5040 //=============================================================================
5042 * \brief Pass names of mesh groups from study to mesh DS
5044 //=============================================================================
5046 void SMESH_Mesh_i::checkGroupNames()
5048 int nbGrp = NbGroups();
5052 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5053 if ( aStudy->_is_nil() )
5054 return; // nothing to do
5056 SMESH::ListOfGroups* grpList = 0;
5057 // avoid dump of "GetGroups"
5059 // store python dump into a local variable inside local scope
5060 SMESH::TPythonDump pDump; // do not delete this line of code
5061 grpList = GetGroups();
5064 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5065 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5068 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5069 if ( aGrpSO->_is_nil() )
5071 // correct name of the mesh group if necessary
5072 const char* guiName = aGrpSO->GetName();
5073 if ( strcmp(guiName, aGrp->GetName()) )
5074 aGrp->SetName( guiName );
5078 //=============================================================================
5080 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5082 //=============================================================================
5083 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5085 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5089 //=============================================================================
5091 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5093 //=============================================================================
5095 char* SMESH_Mesh_i::GetParameters()
5097 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5100 //=============================================================================
5102 * \brief Returns list of notebook variables used for last Mesh operation
5104 //=============================================================================
5105 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5107 SMESH::string_array_var aResult = new SMESH::string_array();
5108 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5110 CORBA::String_var aParameters = GetParameters();
5111 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5112 if ( !aStudy->_is_nil()) {
5113 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5114 if ( aSections->length() > 0 ) {
5115 SALOMEDS::ListOfStrings aVars = aSections[ aSections->length() - 1 ];
5116 aResult->length( aVars.length() );
5117 for ( CORBA::ULong i = 0;i < aVars.length(); i++ )
5118 aResult[i] = CORBA::string_dup( aVars[i] );
5122 return aResult._retn();
5125 //=======================================================================
5126 //function : GetTypes
5127 //purpose : Returns types of elements it contains
5128 //=======================================================================
5130 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5133 return _preMeshInfo->GetTypes();
5135 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5139 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5140 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5141 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5142 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5143 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5144 if (_impl->NbNodes() &&
5145 nbTypes == 0 ) types[nbTypes++] = SMESH::NODE;
5146 types->length( nbTypes );
5148 return types._retn();
5151 //=======================================================================
5152 //function : GetMesh
5153 //purpose : Returns self
5154 //=======================================================================
5156 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5158 return SMESH::SMESH_Mesh::_duplicate( _this() );
5161 //=======================================================================
5162 //function : IsMeshInfoCorrect
5163 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5164 // * happen if mesh data is not yet fully loaded from the file of study.
5165 //=======================================================================
5167 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5169 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5172 //=============================================================================
5174 * \brief Returns number of mesh elements per each \a EntityType
5176 //=============================================================================
5178 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5181 return _preMeshInfo->GetMeshInfo();
5183 SMESH::long_array_var aRes = new SMESH::long_array();
5184 aRes->length(SMESH::Entity_Last);
5185 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5187 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5189 return aRes._retn();
5190 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5191 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5192 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5193 return aRes._retn();
5196 //=============================================================================
5198 * \brief Returns number of mesh elements per each \a ElementType
5200 //=============================================================================
5202 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5204 SMESH::long_array_var aRes = new SMESH::long_array();
5205 aRes->length(SMESH::NB_ELEMENT_TYPES);
5206 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5209 const SMDS_MeshInfo* meshInfo = 0;
5211 meshInfo = _preMeshInfo;
5212 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5213 meshInfo = & meshDS->GetMeshInfo();
5216 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5217 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5219 return aRes._retn();
5222 //=============================================================================
5224 * Collect statistic of mesh elements given by iterator
5226 //=============================================================================
5228 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5229 SMESH::long_array& theInfo)
5231 if (!theItr) return;
5232 while (theItr->more())
5233 theInfo[ theItr->next()->GetEntityType() ]++;
5235 //=============================================================================
5237 * Returns mesh unstructed grid information.
5239 //=============================================================================
5241 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5243 SALOMEDS::TMPFile_var SeqFile;
5244 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5245 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5247 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5248 aWriter->WriteToOutputStringOn();
5249 aWriter->SetInputData(aGrid);
5250 aWriter->SetFileTypeToBinary();
5252 char* str = aWriter->GetOutputString();
5253 int size = aWriter->GetOutputStringLength();
5255 //Allocate octect buffer of required size
5256 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5257 //Copy ostrstream content to the octect buffer
5258 memcpy(OctetBuf, str, size);
5259 //Create and return TMPFile
5260 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5264 return SeqFile._retn();
5267 //=============================================================================
5268 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5269 * SMESH::ElementType type) */
5271 using namespace SMESH::Controls;
5272 //-----------------------------------------------------------------------------
5273 struct PredicateIterator : public SMDS_ElemIterator
5275 SMDS_ElemIteratorPtr _elemIter;
5276 PredicatePtr _predicate;
5277 const SMDS_MeshElement* _elem;
5279 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5280 PredicatePtr predicate):
5281 _elemIter(iterator), _predicate(predicate)
5289 virtual const SMDS_MeshElement* next()
5291 const SMDS_MeshElement* res = _elem;
5293 while ( _elemIter->more() && !_elem )
5295 _elem = _elemIter->next();
5296 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5303 //-----------------------------------------------------------------------------
5304 struct IDSourceIterator : public SMDS_ElemIterator
5306 const CORBA::Long* _idPtr;
5307 const CORBA::Long* _idEndPtr;
5308 SMESH::long_array_var _idArray;
5309 const SMDS_Mesh* _mesh;
5310 const SMDSAbs_ElementType _type;
5311 const SMDS_MeshElement* _elem;
5313 IDSourceIterator( const SMDS_Mesh* mesh,
5314 const CORBA::Long* ids,
5316 SMDSAbs_ElementType type):
5317 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5319 if ( _idPtr && nbIds && _mesh )
5322 IDSourceIterator( const SMDS_Mesh* mesh,
5323 SMESH::long_array* idArray,
5324 SMDSAbs_ElementType type):
5325 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5327 if ( idArray && _mesh )
5329 _idPtr = &_idArray[0];
5330 _idEndPtr = _idPtr + _idArray->length();
5338 virtual const SMDS_MeshElement* next()
5340 const SMDS_MeshElement* res = _elem;
5342 while ( _idPtr < _idEndPtr && !_elem )
5344 if ( _type == SMDSAbs_Node )
5346 _elem = _mesh->FindNode( *_idPtr++ );
5348 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5349 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5357 //-----------------------------------------------------------------------------
5359 struct NodeOfElemIterator : public SMDS_ElemIterator
5361 TColStd_MapOfInteger _checkedNodeIDs;
5362 SMDS_ElemIteratorPtr _elemIter;
5363 SMDS_ElemIteratorPtr _nodeIter;
5364 const SMDS_MeshElement* _node;
5366 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5368 if ( _elemIter && _elemIter->more() )
5370 _nodeIter = _elemIter->next()->nodesIterator();
5378 virtual const SMDS_MeshElement* next()
5380 const SMDS_MeshElement* res = _node;
5382 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5384 if ( _nodeIter->more() )
5386 _node = _nodeIter->next();
5387 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5392 _nodeIter = _elemIter->next()->nodesIterator();
5400 //=============================================================================
5402 * Return iterator on elements of given type in given object
5404 //=============================================================================
5406 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5407 SMESH::ElementType theType)
5409 SMDS_ElemIteratorPtr elemIt;
5410 bool typeOK = ( theType == SMESH::ALL );
5411 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5413 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5414 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5415 if ( !mesh_i ) return elemIt;
5416 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5418 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5420 elemIt = meshDS->elementsIterator( elemType );
5423 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5425 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5428 elemIt = sm->GetElements();
5429 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5431 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5432 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5436 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5438 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5439 if ( groupDS && ( elemType == groupDS->GetType() ||
5440 elemType == SMDSAbs_Node ||
5441 elemType == SMDSAbs_All ))
5443 elemIt = groupDS->GetElements();
5444 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5447 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5449 if ( filter_i->GetElementType() == theType ||
5450 elemType == SMDSAbs_Node ||
5451 elemType == SMDSAbs_All)
5453 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5454 if ( pred_i && pred_i->GetPredicate() )
5456 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5457 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5458 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5459 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5465 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5466 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5467 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5469 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5472 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5473 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5477 SMESH::long_array_var ids = theObject->GetIDs();
5478 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5480 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5483 if ( elemIt && elemIt->more() && !typeOK )
5485 if ( elemType == SMDSAbs_Node )
5487 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5491 elemIt = SMDS_ElemIteratorPtr();
5497 //=============================================================================
5498 namespace // Finding concurrent hypotheses
5499 //=============================================================================
5503 * \brief mapping of mesh dimension into shape type
5505 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5507 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5509 case 0: aType = TopAbs_VERTEX; break;
5510 case 1: aType = TopAbs_EDGE; break;
5511 case 2: aType = TopAbs_FACE; break;
5513 default:aType = TopAbs_SOLID; break;
5518 //-----------------------------------------------------------------------------
5520 * \brief Internal structure used to find concurent submeshes
5522 * It represents a pair < submesh, concurent dimension >, where
5523 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5524 * with another submesh. In other words, it is dimension of a hypothesis assigned
5531 int _dim; //!< a dimension the algo can build (concurrent dimension)
5532 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5533 TopTools_MapOfShape _shapeMap;
5534 SMESH_subMesh* _subMesh;
5535 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5537 //-----------------------------------------------------------------------------
5538 // Return the algorithm
5539 const SMESH_Algo* GetAlgo() const
5540 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5542 //-----------------------------------------------------------------------------
5544 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5546 const TopoDS_Shape& theShape)
5548 _subMesh = (SMESH_subMesh*)theSubMesh;
5549 SetShape( theDim, theShape );
5552 //-----------------------------------------------------------------------------
5554 void SetShape(const int theDim,
5555 const TopoDS_Shape& theShape)
5558 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5559 if (_dim >= _ownDim)
5560 _shapeMap.Add( theShape );
5562 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5563 for( ; anExp.More(); anExp.Next() )
5564 _shapeMap.Add( anExp.Current() );
5568 //-----------------------------------------------------------------------------
5569 //! Check sharing of sub-shapes
5570 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5571 const TopTools_MapOfShape& theToFind,
5572 const TopAbs_ShapeEnum theType)
5574 bool isShared = false;
5575 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5576 for (; !isShared && anItr.More(); anItr.Next() )
5578 const TopoDS_Shape aSubSh = anItr.Key();
5579 // check for case when concurrent dimensions are same
5580 isShared = theToFind.Contains( aSubSh );
5581 // check for sub-shape with concurrent dimension
5582 TopExp_Explorer anExp( aSubSh, theType );
5583 for ( ; !isShared && anExp.More(); anExp.Next() )
5584 isShared = theToFind.Contains( anExp.Current() );
5589 //-----------------------------------------------------------------------------
5590 //! check algorithms
5591 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5592 const SMESHDS_Hypothesis* theA2)
5594 if ( !theA1 || !theA2 ||
5595 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5596 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5597 return false; // one of the hypothesis is not algorithm
5598 // check algorithm names (should be equal)
5599 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5603 //-----------------------------------------------------------------------------
5604 //! Check if sub-shape hypotheses are concurrent
5605 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5607 if ( _subMesh == theOther->_subMesh )
5608 return false; // same sub-shape - should not be
5610 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5611 // any of the two submeshes is not on COMPOUND shape )
5612 // -> no concurrency
5613 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5614 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5615 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5616 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5617 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5620 // bool checkSubShape = ( _dim >= theOther->_dim )
5621 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5622 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5623 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5624 if ( !checkSubShape )
5627 // check algorithms to be same
5628 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5629 return true; // different algorithms -> concurrency !
5631 // check hypothesises for concurrence (skip first as algorithm)
5633 // pointers should be same, because it is referened from mesh hypothesis partition
5634 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5635 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5636 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5637 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5639 // the submeshes are concurrent if their algorithms has different parameters
5640 return nbSame != (int)theOther->_hypotheses.size() - 1;
5643 // Return true if algorithm of this SMESH_DimHyp is used if no
5644 // sub-mesh order is imposed by the user
5645 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5647 // NeedDiscreteBoundary() algo has a higher priority
5648 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5649 theOther->GetAlgo()->NeedDiscreteBoundary() )
5650 return !this->GetAlgo()->NeedDiscreteBoundary();
5652 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5655 }; // end of SMESH_DimHyp
5656 //-----------------------------------------------------------------------------
5658 typedef list<const SMESH_DimHyp*> TDimHypList;
5660 //-----------------------------------------------------------------------------
5662 void addDimHypInstance(const int theDim,
5663 const TopoDS_Shape& theShape,
5664 const SMESH_Algo* theAlgo,
5665 const SMESH_subMesh* theSubMesh,
5666 const list <const SMESHDS_Hypothesis*>& theHypList,
5667 TDimHypList* theDimHypListArr )
5669 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5670 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5671 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5672 dimHyp->_hypotheses.push_front(theAlgo);
5673 listOfdimHyp.push_back( dimHyp );
5676 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5677 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5678 theHypList.begin(), theHypList.end() );
5681 //-----------------------------------------------------------------------------
5682 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5683 TDimHypList& theListOfConcurr)
5685 if ( theListOfConcurr.empty() )
5687 theListOfConcurr.push_back( theDimHyp );
5691 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5692 while ( hypIt != theListOfConcurr.end() &&
5693 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5695 theListOfConcurr.insert( hypIt, theDimHyp );
5699 //-----------------------------------------------------------------------------
5700 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5701 const TDimHypList& theListOfDimHyp,
5702 TDimHypList& theListOfConcurrHyp,
5703 set<int>& theSetOfConcurrId )
5705 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5706 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5708 const SMESH_DimHyp* curDimHyp = *rIt;
5709 if ( curDimHyp == theDimHyp )
5710 break; // meet own dimHyp pointer in same dimension
5712 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5713 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5715 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5720 //-----------------------------------------------------------------------------
5721 void unionLists(TListOfInt& theListOfId,
5722 TListOfListOfInt& theListOfListOfId,
5725 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5726 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5728 continue; //skip already treated lists
5729 // check if other list has any same submesh object
5730 TListOfInt& otherListOfId = *it;
5731 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5732 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5735 // union two lists (from source into target)
5736 TListOfInt::iterator it2 = otherListOfId.begin();
5737 for ( ; it2 != otherListOfId.end(); it2++ ) {
5738 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5739 theListOfId.push_back(*it2);
5741 // clear source list
5742 otherListOfId.clear();
5745 //-----------------------------------------------------------------------------
5747 //! free memory allocated for dimension-hypothesis objects
5748 void removeDimHyps( TDimHypList* theArrOfList )
5750 for (int i = 0; i < 4; i++ ) {
5751 TDimHypList& listOfdimHyp = theArrOfList[i];
5752 TDimHypList::const_iterator it = listOfdimHyp.begin();
5753 for ( ; it != listOfdimHyp.end(); it++ )
5758 //-----------------------------------------------------------------------------
5760 * \brief find common submeshes with given submesh
5761 * \param theSubMeshList list of already collected submesh to check
5762 * \param theSubMesh given submesh to intersect with other
5763 * \param theCommonSubMeshes collected common submeshes
5765 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5766 const SMESH_subMesh* theSubMesh,
5767 set<const SMESH_subMesh*>& theCommon )
5771 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5772 for ( ; it != theSubMeshList.end(); it++ )
5773 theSubMesh->FindIntersection( *it, theCommon );
5774 theSubMeshList.push_back( theSubMesh );
5775 //theCommon.insert( theSubMesh );
5778 //-----------------------------------------------------------------------------
5779 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5781 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5782 for ( ; listsIt != smLists.end(); ++listsIt )
5784 const TListOfInt& smIDs = *listsIt;
5785 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5793 //=============================================================================
5795 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5797 //=============================================================================
5799 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5801 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5802 if ( isSubMeshInList( submeshID, anOrder ))
5805 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5806 return isSubMeshInList( submeshID, allConurrent );
5809 //=============================================================================
5811 * \brief Return submesh objects list in meshing order
5813 //=============================================================================
5815 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5817 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5819 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5821 return aResult._retn();
5823 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5824 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5825 anOrder.splice( anOrder.end(), allConurrent );
5828 TListOfListOfInt::iterator listIt = anOrder.begin();
5829 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5830 unionLists( *listIt, anOrder, listIndx + 1 );
5832 // convert submesh ids into interface instances
5833 // and dump command into python
5834 convertMeshOrder( anOrder, aResult, false );
5836 return aResult._retn();
5839 //=============================================================================
5841 * \brief Finds concurrent sub-meshes
5843 //=============================================================================
5845 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5847 TListOfListOfInt anOrder;
5848 ::SMESH_Mesh& mesh = GetImpl();
5850 // collect submeshes and detect concurrent algorithms and hypothesises
5851 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5853 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5854 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5855 ::SMESH_subMesh* sm = (*i_sm).second;
5857 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5859 // list of assigned hypothesises
5860 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5861 // Find out dimensions where the submesh can be concurrent.
5862 // We define the dimensions by algo of each of hypotheses in hypList
5863 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5864 for( ; hypIt != hypList.end(); hypIt++ ) {
5865 SMESH_Algo* anAlgo = 0;
5866 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5867 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5868 // hyp it-self is algo
5869 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5871 // try to find algorithm with help of sub-shapes
5872 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5873 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5874 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5877 continue; // no algorithm assigned to a current submesh
5879 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5880 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5882 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5883 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5884 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5886 } // end iterations on submesh
5888 // iterate on created dimension-hypotheses and check for concurrents
5889 for ( int i = 0; i < 4; i++ ) {
5890 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5891 // check for concurrents in own and other dimensions (step-by-step)
5892 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5893 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5894 const SMESH_DimHyp* dimHyp = *dhIt;
5895 TDimHypList listOfConcurr;
5896 set<int> setOfConcurrIds;
5897 // looking for concurrents and collect into own list
5898 for ( int j = i; j < 4; j++ )
5899 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5900 // check if any concurrents found
5901 if ( listOfConcurr.size() > 0 ) {
5902 // add own submesh to list of concurrent
5903 addInOrderOfPriority( dimHyp, listOfConcurr );
5904 list<int> listOfConcurrIds;
5905 TDimHypList::iterator hypIt = listOfConcurr.begin();
5906 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5907 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5908 anOrder.push_back( listOfConcurrIds );
5913 removeDimHyps(dimHypListArr);
5915 // now, minimise the number of concurrent groups
5916 // Here we assume that lists of submeshes can have same submesh
5917 // in case of multi-dimension algorithms, as result
5918 // list with common submesh has to be united into one list
5920 TListOfListOfInt::iterator listIt = anOrder.begin();
5921 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5922 unionLists( *listIt, anOrder, listIndx + 1 );
5928 //=============================================================================
5930 * \brief Set submesh object order
5931 * \param theSubMeshArray submesh array order
5933 //=============================================================================
5935 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5938 _preMeshInfo->ForgetOrLoad();
5941 ::SMESH_Mesh& mesh = GetImpl();
5943 TPythonDump aPythonDump; // prevent dump of called methods
5944 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5946 TListOfListOfInt subMeshOrder;
5947 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5949 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5950 TListOfInt subMeshIds;
5952 aPythonDump << ", ";
5953 aPythonDump << "[ ";
5954 // Collect subMeshes which should be clear
5955 // do it list-by-list, because modification of submesh order
5956 // take effect between concurrent submeshes only
5957 set<const SMESH_subMesh*> subMeshToClear;
5958 list<const SMESH_subMesh*> subMeshList;
5959 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5961 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5963 aPythonDump << ", ";
5964 aPythonDump << subMesh;
5965 subMeshIds.push_back( subMesh->GetId() );
5966 // detect common parts of submeshes
5967 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5968 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5970 aPythonDump << " ]";
5971 subMeshOrder.push_back( subMeshIds );
5973 // clear collected submeshes
5974 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5975 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5976 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5977 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5979 aPythonDump << " ])";
5981 mesh.SetMeshOrder( subMeshOrder );
5987 //=============================================================================
5989 * \brief Convert submesh ids into submesh interfaces
5991 //=============================================================================
5993 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5994 SMESH::submesh_array_array& theResOrder,
5995 const bool theIsDump)
5997 int nbSet = theIdsOrder.size();
5998 TPythonDump aPythonDump; // prevent dump of called methods
6000 aPythonDump << "[ ";
6001 theResOrder.length(nbSet);
6002 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
6004 for( ; it != theIdsOrder.end(); it++ ) {
6005 // translate submesh identificators into submesh objects
6006 // takeing into account real number of concurrent lists
6007 const TListOfInt& aSubOrder = (*it);
6008 if (!aSubOrder.size())
6011 aPythonDump << "[ ";
6012 // convert shape indeces into interfaces
6013 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
6014 aResSubSet->length(aSubOrder.size());
6015 TListOfInt::const_iterator subIt = aSubOrder.begin();
6017 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
6018 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
6020 SMESH::SMESH_subMesh_var subMesh =
6021 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
6024 aPythonDump << ", ";
6025 aPythonDump << subMesh;
6027 aResSubSet[ j++ ] = subMesh;
6030 aPythonDump << " ]";
6032 theResOrder[ listIndx++ ] = aResSubSet;
6034 // correct number of lists
6035 theResOrder.length( listIndx );
6038 // finilise python dump
6039 aPythonDump << " ]";
6040 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
6044 //================================================================================
6046 // Implementation of SMESH_MeshPartDS
6048 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6049 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6051 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6052 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6054 _meshDS = mesh_i->GetImpl().GetMeshDS();
6056 SetPersistentId( _meshDS->GetPersistentId() );
6058 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6060 // <meshPart> is the whole mesh
6061 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6063 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6064 myGroupSet = _meshDS->GetGroups();
6069 SMESH::long_array_var anIDs = meshPart->GetIDs();
6070 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6071 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6073 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6074 if ( const SMDS_MeshNode * n = _meshDS->FindNode( anIDs[i] ))
6075 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6080 for ( CORBA::ULong i=0; i < anIDs->length(); i++ )
6081 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6082 if ( _elements[ e->GetType() ].insert( e ).second )
6085 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6086 while ( nIt->more() )
6088 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6089 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6096 ShapeToMesh( _meshDS->ShapeToMesh() );
6098 _meshDS = 0; // to enforce iteration on _elements and _nodes
6101 // -------------------------------------------------------------------------------------
6102 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6103 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6106 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6107 for ( ; partIt != meshPart.end(); ++partIt )
6108 if ( const SMDS_MeshElement * e = *partIt )
6109 if ( _elements[ e->GetType() ].insert( e ).second )
6112 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6113 while ( nIt->more() )
6115 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6116 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6122 // -------------------------------------------------------------------------------------
6123 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6125 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6127 typedef SMDS_SetIterator
6128 <const SMDS_MeshElement*,
6129 TIDSortedElemSet::const_iterator,
6130 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6131 SMDS_MeshElement::GeomFilter
6134 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6136 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6137 _elements[type].end(),
6138 SMDS_MeshElement::GeomFilter( geomType )));
6140 // -------------------------------------------------------------------------------------
6141 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6143 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6145 typedef SMDS_SetIterator
6146 <const SMDS_MeshElement*,
6147 TIDSortedElemSet::const_iterator,
6148 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6149 SMDS_MeshElement::EntityFilter
6152 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6154 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6155 _elements[type].end(),
6156 SMDS_MeshElement::EntityFilter( entity )));
6158 // -------------------------------------------------------------------------------------
6159 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6161 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6162 if ( type == SMDSAbs_All && !_meshDS )
6164 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6166 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6167 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6169 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6171 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6172 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6174 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6175 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6177 // -------------------------------------------------------------------------------------
6178 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6179 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6181 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6182 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6183 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6185 // -------------------------------------------------------------------------------------
6186 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6187 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6188 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6189 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6190 #undef _GET_ITER_DEFINE
6192 // END Implementation of SMESH_MeshPartDS
6194 //================================================================================