1 // Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License, or (at your option) any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : SMESH_Mesh_i.cxx
23 // Author : Paul RASCLE, EDF
26 #include "SMESH_Mesh_i.hxx"
28 #include "DriverMED_R_SMESHDS_Mesh.h"
29 #include "DriverMED_W_Field.h"
30 #include "DriverMED_W_SMESHDS_Mesh.h"
31 #include "MED_Factory.hxx"
32 #include "SMDS_EdgePosition.hxx"
33 #include "SMDS_ElemIterator.hxx"
34 #include "SMDS_FacePosition.hxx"
35 #include "SMDS_IteratorOnIterators.hxx"
36 #include "SMDS_MeshGroup.hxx"
37 #include "SMDS_SetIterator.hxx"
38 #include "SMDS_VolumeTool.hxx"
39 #include "SMESHDS_Command.hxx"
40 #include "SMESHDS_CommandType.hxx"
41 #include "SMESHDS_Group.hxx"
42 #include "SMESHDS_GroupOnGeom.hxx"
43 #include "SMESH_Controls.hxx"
44 #include "SMESH_File.hxx"
45 #include "SMESH_Filter_i.hxx"
46 #include "SMESH_Gen_i.hxx"
47 #include "SMESH_Group.hxx"
48 #include "SMESH_Group_i.hxx"
49 #include "SMESH_Mesh.hxx"
50 #include "SMESH_MeshAlgos.hxx"
51 #include "SMESH_MeshEditor.hxx"
52 #include "SMESH_MeshEditor_i.hxx"
53 #include "SMESH_MeshPartDS.hxx"
54 #include "SMESH_MesherHelper.hxx"
55 #include "SMESH_PreMeshInfo.hxx"
56 #include "SMESH_PythonDump.hxx"
57 #include "SMESH_subMesh_i.hxx"
59 #include <SALOMEDS_Attributes_wrap.hxx>
60 #include <SALOMEDS_wrap.hxx>
61 #include <Utils_ExceptHandlers.hxx>
62 #include <utilities.h>
64 #include <GEOMImpl_Types.hxx>
65 #include <GEOM_wrap.hxx>
68 #include <BRep_Builder.hxx>
69 #include <Standard_ErrorHandler.hxx>
70 #include <TColStd_MapOfInteger.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopTools_MapIteratorOfMapOfShape.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopoDS_Compound.hxx>
82 #include <vtkUnstructuredGridWriter.h>
84 // to pass CORBA exception through SMESH_TRY
85 #define SMY_OWN_CATCH catch( SALOME::SALOME_Exception& se ) { throw se; }
87 #include "SMESH_TryCatch.hxx" // include after OCCT headers!
90 static int MYDEBUG = 0;
92 static int MYDEBUG = 0;
96 using SMESH::TPythonDump;
98 int SMESH_Mesh_i::_idGenerator = 0;
100 //=============================================================================
104 //=============================================================================
106 SMESH_Mesh_i::SMESH_Mesh_i( PortableServer::POA_ptr thePOA,
108 CORBA::Long studyId )
109 : SALOME::GenericObj_i( thePOA )
111 MESSAGE("SMESH_Mesh_i");
114 _id = _idGenerator++;
117 _previewEditor = NULL;
122 //=============================================================================
126 //=============================================================================
128 SMESH_Mesh_i::~SMESH_Mesh_i()
130 MESSAGE("~SMESH_Mesh_i");
133 map<int, SMESH::SMESH_GroupBase_ptr>::iterator itGr;
134 for (itGr = _mapGroups.begin(); itGr != _mapGroups.end(); itGr++)
135 if (SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>(itGr->second))
137 aGroup->UnRegister();
138 SMESH::SMESH_GroupBase_var( itGr->second );
143 map<int, SMESH::SMESH_subMesh_ptr>::iterator itSM;
144 for ( itSM = _mapSubMeshIor.begin(); itSM != _mapSubMeshIor.end(); itSM++ )
145 if ( SMESH_subMesh_i* aSubMesh = SMESH::DownCast<SMESH_subMesh_i*>( itSM->second ))
147 aSubMesh->UnRegister();
148 SMESH::SMESH_subMesh_var( itSM->second );
150 _mapSubMeshIor.clear();
152 // destroy hypotheses. _mapHypo contains all hyps ever been assigned
153 map<int, SMESH::SMESH_Hypothesis_ptr>::iterator itH;
154 for ( itH = _mapHypo.begin(); itH != _mapHypo.end(); itH++ ) {
155 if ( SMESH_Hypothesis_i* hyp_i = SMESH::DownCast<SMESH_Hypothesis_i*>( itH->second ))
156 if ( SMESH_Hypothesis * smHyp = _impl->GetHypothesis( itH->first ))
157 if ( _impl->GetMeshDS()->IsUsedHypothesis( smHyp ))
160 SMESH::SMESH_Hypothesis_var( itH->second ); // decref CORBA object
164 // clear cashed shapes if no more meshes remain; (the cash is blame,
165 // together with publishing, of spent time increasing in issue 22874)
166 if ( _impl->NbMeshes() == 1 )
167 _gen_i->GetShapeReader()->ClearClientBuffer();
169 delete _editor; _editor = NULL;
170 delete _previewEditor; _previewEditor = NULL;
171 delete _impl; _impl = NULL;
172 delete _preMeshInfo; _preMeshInfo = NULL;
175 //=============================================================================
179 * Associates <this> mesh with <theShape> and puts a reference
180 * to <theShape> into the current study;
181 * the previous shape is substituted by the new one.
183 //=============================================================================
185 void SMESH_Mesh_i::SetShape( GEOM::GEOM_Object_ptr theShapeObject )
186 throw (SALOME::SALOME_Exception)
188 Unexpect aCatch(SALOME_SalomeException);
190 _impl->ShapeToMesh( _gen_i->GeomObjectToShape( theShapeObject ));
192 catch(SALOME_Exception & S_ex) {
193 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
195 // to track changes of GEOM groups
196 SMESH::SMESH_Mesh_var mesh = _this();
197 addGeomGroupData( theShapeObject, mesh );
198 if ( !CORBA::is_nil( theShapeObject ))
199 _mainShapeTick = theShapeObject->GetTick();
202 //================================================================================
204 * \brief return true if mesh has a shape to build a shape on
206 //================================================================================
208 CORBA::Boolean SMESH_Mesh_i::HasShapeToMesh()
209 throw (SALOME::SALOME_Exception)
211 Unexpect aCatch(SALOME_SalomeException);
214 res = _impl->HasShapeToMesh();
216 catch(SALOME_Exception & S_ex) {
217 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
222 //=======================================================================
223 //function : GetShapeToMesh
225 //=======================================================================
227 GEOM::GEOM_Object_ptr SMESH_Mesh_i::GetShapeToMesh()
228 throw (SALOME::SALOME_Exception)
230 Unexpect aCatch(SALOME_SalomeException);
231 GEOM::GEOM_Object_var aShapeObj;
233 TopoDS_Shape S = _impl->GetMeshDS()->ShapeToMesh();
235 aShapeObj = _gen_i->ShapeToGeomObject( S );
237 catch(SALOME_Exception & S_ex) {
238 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
240 return aShapeObj._retn();
243 //================================================================================
245 * \brief Return false if the mesh is not yet fully loaded from the study file
247 //================================================================================
249 CORBA::Boolean SMESH_Mesh_i::IsLoaded() throw (SALOME::SALOME_Exception)
251 Unexpect aCatch(SALOME_SalomeException);
252 return !_preMeshInfo;
255 //================================================================================
257 * \brief Load full mesh data from the study file
259 //================================================================================
261 void SMESH_Mesh_i::Load() throw (SALOME::SALOME_Exception)
263 Unexpect aCatch(SALOME_SalomeException);
265 _preMeshInfo->FullLoadFromFile();
268 //================================================================================
270 * \brief Remove all nodes and elements
272 //================================================================================
274 void SMESH_Mesh_i::Clear() throw (SALOME::SALOME_Exception)
276 Unexpect aCatch(SALOME_SalomeException);
278 _preMeshInfo->ForgetAllData();
282 //CheckGeomGroupModif(); // issue 20145
284 catch(SALOME_Exception & S_ex) {
285 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
287 _impl->GetMeshDS()->Modified();
289 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".Clear()";
292 //================================================================================
294 * \brief Remove all nodes and elements for indicated shape
296 //================================================================================
298 void SMESH_Mesh_i::ClearSubMesh(CORBA::Long ShapeID)
299 throw (SALOME::SALOME_Exception)
301 Unexpect aCatch(SALOME_SalomeException);
303 _preMeshInfo->FullLoadFromFile();
306 _impl->ClearSubMesh( ShapeID );
308 catch(SALOME_Exception & S_ex) {
309 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
311 _impl->GetMeshDS()->Modified();
313 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ClearSubMesh( " << ShapeID << " )";
316 //=============================================================================
318 * Convert enum Driver_Mesh::Status to SMESH::DriverMED_ReadStatus
320 //=============================================================================
322 static SMESH::DriverMED_ReadStatus ConvertDriverMEDReadStatus (int theStatus)
324 SMESH::DriverMED_ReadStatus res;
327 case DriverMED_R_SMESHDS_Mesh::DRS_OK:
328 res = SMESH::DRS_OK; break;
329 case DriverMED_R_SMESHDS_Mesh::DRS_EMPTY:
330 res = SMESH::DRS_EMPTY; break;
331 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_RENUMBER:
332 res = SMESH::DRS_WARN_RENUMBER; break;
333 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_SKIP_ELEM:
334 res = SMESH::DRS_WARN_SKIP_ELEM; break;
335 case DriverMED_R_SMESHDS_Mesh::DRS_WARN_DESCENDING:
336 res = SMESH::DRS_WARN_DESCENDING; break;
337 case DriverMED_R_SMESHDS_Mesh::DRS_FAIL:
339 res = SMESH::DRS_FAIL; break;
344 //=============================================================================
346 * Convert ::SMESH_ComputeError to SMESH::ComputeError
348 //=============================================================================
350 static SMESH::ComputeError* ConvertComputeError( SMESH_ComputeErrorPtr errorPtr )
352 SMESH::ComputeError_var errVar = new SMESH::ComputeError();
353 errVar->subShapeID = -1;
354 errVar->hasBadMesh = false;
356 if ( !errorPtr || errorPtr->IsOK() )
358 errVar->code = SMESH::COMPERR_OK;
362 errVar->code = ConvertDriverMEDReadStatus( errorPtr->myName );
363 errVar->comment = errorPtr->myComment.c_str();
365 return errVar._retn();
368 //=============================================================================
372 * Imports mesh data from MED file
374 //=============================================================================
376 SMESH::DriverMED_ReadStatus
377 SMESH_Mesh_i::ImportMEDFile( const char* theFileName, const char* theMeshName )
378 throw ( SALOME::SALOME_Exception )
380 Unexpect aCatch(SALOME_SalomeException);
383 status = _impl->MEDToMesh( theFileName, theMeshName );
385 catch( SALOME_Exception& S_ex ) {
386 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
389 THROW_SALOME_CORBA_EXCEPTION("ImportMEDFile(): unknown exception", SALOME::BAD_PARAM);
392 CreateGroupServants();
394 int major, minor, release;
395 if( !MED::getMEDVersion( theFileName, major, minor, release ) )
396 major = minor = release = -1;
397 _medFileInfo = new SMESH::MedFileInfo();
398 _medFileInfo->fileName = theFileName;
399 _medFileInfo->fileSize = 0;
400 _medFileInfo->major = major;
401 _medFileInfo->minor = minor;
402 _medFileInfo->release = release;
403 _medFileInfo->fileSize = SMESH_File( theFileName ).size();
405 return ConvertDriverMEDReadStatus(status);
408 //================================================================================
410 * \brief Imports mesh data from the CGNS file
412 //================================================================================
414 SMESH::DriverMED_ReadStatus SMESH_Mesh_i::ImportCGNSFile( const char* theFileName,
415 const int theMeshIndex,
416 std::string& theMeshName )
417 throw ( SALOME::SALOME_Exception )
419 Unexpect aCatch(SALOME_SalomeException);
422 status = _impl->CGNSToMesh( theFileName, theMeshIndex, theMeshName );
424 catch( SALOME_Exception& S_ex ) {
425 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
428 THROW_SALOME_CORBA_EXCEPTION("ImportCGNSFile(): unknown exception", SALOME::BAD_PARAM);
431 CreateGroupServants();
433 return ConvertDriverMEDReadStatus(status);
436 //================================================================================
438 * \brief Return string representation of a MED file version comprising nbDigits
440 //================================================================================
442 char* SMESH_Mesh_i::GetVersionString(SMESH::MED_VERSION version, CORBA::Short nbDigits)
444 string ver = DriverMED_W_SMESHDS_Mesh::GetVersionString(MED::EVersion(version),
446 return CORBA::string_dup( ver.c_str() );
449 //=============================================================================
453 * Imports mesh data from MED file
455 //=============================================================================
457 int SMESH_Mesh_i::ImportUNVFile( const char* theFileName )
458 throw ( SALOME::SALOME_Exception )
462 // Read mesh with name = <theMeshName> into SMESH_Mesh
463 _impl->UNVToMesh( theFileName );
465 CreateGroupServants();
467 SMESH_CATCH( SMESH::throwCorbaException );
472 //=============================================================================
476 * Imports mesh data from STL file
478 //=============================================================================
479 int SMESH_Mesh_i::ImportSTLFile( const char* theFileName )
480 throw ( SALOME::SALOME_Exception )
484 // Read mesh with name = <theMeshName> into SMESH_Mesh
485 _impl->STLToMesh( theFileName );
487 SMESH_CATCH( SMESH::throwCorbaException );
492 //================================================================================
494 * \brief Function used in SMESH_CATCH by ImportGMFFile()
496 //================================================================================
500 SMESH_ComputeErrorPtr exceptionToComputeError(const char* excText)
502 return SMESH_ComputeError::New( Driver_Mesh::DRS_FAIL, excText );
506 //================================================================================
508 * \brief Imports data from a GMF file and returns an error description
510 //================================================================================
512 SMESH::ComputeError* SMESH_Mesh_i::ImportGMFFile( const char* theFileName,
513 bool theMakeRequiredGroups )
514 throw (SALOME::SALOME_Exception)
516 SMESH_ComputeErrorPtr error;
519 #define SMESH_CAUGHT error =
522 error = _impl->GMFToMesh( theFileName, theMakeRequiredGroups );
524 SMESH_CATCH( exceptionToComputeError );
528 CreateGroupServants();
530 return ConvertComputeError( error );
533 //=============================================================================
537 //=============================================================================
539 #define RETURNCASE(hyp_stat) case SMESH_Hypothesis::hyp_stat: return SMESH::hyp_stat;
541 SMESH::Hypothesis_Status SMESH_Mesh_i::ConvertHypothesisStatus
542 (SMESH_Hypothesis::Hypothesis_Status theStatus)
545 RETURNCASE( HYP_OK );
546 RETURNCASE( HYP_MISSING );
547 RETURNCASE( HYP_CONCURENT );
548 RETURNCASE( HYP_BAD_PARAMETER );
549 RETURNCASE( HYP_HIDDEN_ALGO );
550 RETURNCASE( HYP_HIDING_ALGO );
551 RETURNCASE( HYP_UNKNOWN_FATAL );
552 RETURNCASE( HYP_INCOMPATIBLE );
553 RETURNCASE( HYP_NOTCONFORM );
554 RETURNCASE( HYP_ALREADY_EXIST );
555 RETURNCASE( HYP_BAD_DIM );
556 RETURNCASE( HYP_BAD_SUBSHAPE );
557 RETURNCASE( HYP_BAD_GEOMETRY );
558 RETURNCASE( HYP_NEED_SHAPE );
559 RETURNCASE( HYP_INCOMPAT_HYPS );
562 return SMESH::HYP_UNKNOWN_FATAL;
565 //=============================================================================
569 * calls internal addHypothesis() and then adds a reference to <anHyp> under
570 * the SObject actually having a reference to <aSubShape>.
571 * NB: For this method to work, it is necessary to add a reference to sub-shape first.
573 //=============================================================================
575 SMESH::Hypothesis_Status
576 SMESH_Mesh_i::AddHypothesis(GEOM::GEOM_Object_ptr aSubShape,
577 SMESH::SMESH_Hypothesis_ptr anHyp,
578 CORBA::String_out anErrorText)
579 throw(SALOME::SALOME_Exception)
581 Unexpect aCatch(SALOME_SalomeException);
583 _preMeshInfo->ForgetOrLoad();
586 SMESH_Hypothesis::Hypothesis_Status status = addHypothesis( aSubShape, anHyp, &error );
587 anErrorText = error.c_str();
589 SMESH::SMESH_Mesh_var mesh( _this() );
590 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
592 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
593 _gen_i->AddHypothesisToShape( study, mesh, aSubShape, anHyp );
595 if(MYDEBUG) MESSAGE( " AddHypothesis(): status = " << status );
597 // Update Python script
598 TPythonDump() << "status = " << mesh << ".AddHypothesis( "
599 << aSubShape << ", " << anHyp << " )";
601 return ConvertHypothesisStatus(status);
604 //=============================================================================
608 //=============================================================================
610 SMESH_Hypothesis::Hypothesis_Status
611 SMESH_Mesh_i::addHypothesis(GEOM::GEOM_Object_ptr aSubShape,
612 SMESH::SMESH_Hypothesis_ptr anHyp,
613 std::string* anErrorText)
615 if(MYDEBUG) MESSAGE("addHypothesis");
617 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
618 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference",SALOME::BAD_PARAM);
620 if (CORBA::is_nil( anHyp ))
621 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference",SALOME::BAD_PARAM);
623 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
626 TopoDS_Shape myLocSubShape;
627 //use PseudoShape in case if mesh has no shape
629 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape);
631 myLocSubShape = _impl->GetShapeToMesh();
633 const int hypId = anHyp->GetId();
635 status = _impl->AddHypothesis( myLocSubShape, hypId, &error );
636 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
638 _mapHypo[hypId] = SMESH::SMESH_Hypothesis::_duplicate( anHyp );
640 // assure there is a corresponding submesh
641 if ( !_impl->IsMainShape( myLocSubShape )) {
642 int shapeId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
643 if ( _mapSubMesh_i.find( shapeId ) == _mapSubMesh_i.end() )
644 SMESH::SMESH_subMesh_var( createSubMesh( aSubShape ));
647 else if ( anErrorText )
649 *anErrorText = error;
652 catch(SALOME_Exception & S_ex)
654 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
659 //=============================================================================
663 //=============================================================================
665 SMESH::Hypothesis_Status SMESH_Mesh_i::RemoveHypothesis(GEOM::GEOM_Object_ptr aSubShape,
666 SMESH::SMESH_Hypothesis_ptr anHyp)
667 throw(SALOME::SALOME_Exception)
669 Unexpect aCatch(SALOME_SalomeException);
671 _preMeshInfo->ForgetOrLoad();
673 SMESH_Hypothesis::Hypothesis_Status status = removeHypothesis( aSubShape, anHyp );
674 SMESH::SMESH_Mesh_var mesh = _this();
676 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
678 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
679 _gen_i->RemoveHypothesisFromShape( study, mesh, aSubShape, anHyp );
681 // Update Python script
682 if(_impl->HasShapeToMesh())
683 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
684 << aSubShape << ", " << anHyp << " )";
686 TPythonDump() << "status = " << mesh << ".RemoveHypothesis( "
689 return ConvertHypothesisStatus(status);
692 //=============================================================================
696 //=============================================================================
698 SMESH_Hypothesis::Hypothesis_Status
699 SMESH_Mesh_i::removeHypothesis(GEOM::GEOM_Object_ptr aSubShape,
700 SMESH::SMESH_Hypothesis_ptr anHyp)
702 if(MYDEBUG) MESSAGE("removeHypothesis()");
704 if (CORBA::is_nil( aSubShape ) && HasShapeToMesh())
705 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
707 if (CORBA::is_nil( anHyp ))
708 THROW_SALOME_CORBA_EXCEPTION("bad hypothesis reference", SALOME::BAD_PARAM);
710 SMESH_Hypothesis::Hypothesis_Status status = SMESH_Hypothesis::HYP_OK;
713 TopoDS_Shape myLocSubShape;
714 //use PseudoShape in case if mesh has no shape
715 if( _impl->HasShapeToMesh() )
716 myLocSubShape = _gen_i->GeomObjectToShape( aSubShape );
718 myLocSubShape = _impl->GetShapeToMesh();
720 const int hypId = anHyp->GetId();
721 status = _impl->RemoveHypothesis(myLocSubShape, hypId);
722 if ( !SMESH_Hypothesis::IsStatusFatal(status) )
724 // _mapHypo.erase( hypId ); EAP: hyp can be used on many sub-shapes
728 catch(SALOME_Exception & S_ex)
730 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
735 //=============================================================================
739 //=============================================================================
741 SMESH::ListOfHypothesis *
742 SMESH_Mesh_i::GetHypothesisList(GEOM::GEOM_Object_ptr aSubShape)
743 throw(SALOME::SALOME_Exception)
745 Unexpect aCatch(SALOME_SalomeException);
746 if (MYDEBUG) MESSAGE("GetHypothesisList");
747 if (_impl->HasShapeToMesh() && CORBA::is_nil(aSubShape))
748 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
750 SMESH::ListOfHypothesis_var aList = new SMESH::ListOfHypothesis();
753 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
754 if ( myLocSubShape.IsNull() && !_impl->HasShapeToMesh() )
755 myLocSubShape = _impl->GetShapeToMesh();
756 const list<const SMESHDS_Hypothesis*>& aLocalList = _impl->GetHypothesisList( myLocSubShape );
757 int i = 0, n = aLocalList.size();
760 list<const SMESHDS_Hypothesis*>::const_iterator aHyp = aLocalList.begin();
761 std::map<int, SMESH::SMESH_Hypothesis_ptr>::iterator id_hypptr;
762 for ( ; i < n && aHyp != aLocalList.end(); aHyp++ )
764 id_hypptr = _mapHypo.find( (*aHyp)->GetID() );
765 if ( id_hypptr != _mapHypo.end() )
766 aList[i++] = SMESH::SMESH_Hypothesis::_narrow( id_hypptr->second );
770 catch(SALOME_Exception & S_ex) {
771 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
774 return aList._retn();
777 SMESH::submesh_array* SMESH_Mesh_i::GetSubMeshes() throw (SALOME::SALOME_Exception)
779 Unexpect aCatch(SALOME_SalomeException);
780 if (MYDEBUG) MESSAGE("GetSubMeshes");
782 SMESH::submesh_array_var aList = new SMESH::submesh_array();
785 TPythonDump aPythonDump;
786 if ( !_mapSubMeshIor.empty() )
790 aList->length( _mapSubMeshIor.size() );
792 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.begin();
793 for ( ; it != _mapSubMeshIor.end(); it++ ) {
794 if ( CORBA::is_nil( it->second )) continue;
795 aList[i++] = SMESH::SMESH_subMesh::_duplicate( it->second );
797 if (i > 1) aPythonDump << ", ";
798 aPythonDump << it->second;
802 catch(SALOME_Exception & S_ex) {
803 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
806 // Update Python script
807 if ( !_mapSubMeshIor.empty() )
808 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var( _this() ) << ".GetSubMeshes()";
810 return aList._retn();
813 //=============================================================================
817 //=============================================================================
819 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::GetSubMesh(GEOM::GEOM_Object_ptr aSubShape,
820 const char* theName )
821 throw(SALOME::SALOME_Exception)
823 Unexpect aCatch(SALOME_SalomeException);
824 if (CORBA::is_nil(aSubShape))
825 THROW_SALOME_CORBA_EXCEPTION("bad Sub-shape reference", SALOME::BAD_PARAM);
827 SMESH::SMESH_subMesh_var subMesh;
828 SMESH::SMESH_Mesh_var aMesh = _this();
830 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(aSubShape);
832 //Get or Create the SMESH_subMesh object implementation
834 int subMeshId = _impl->GetMeshDS()->ShapeToIndex( myLocSubShape );
836 if ( !subMeshId && ! _impl->GetMeshDS()->IsGroupOfSubShapes( myLocSubShape ))
838 TopoDS_Iterator it( myLocSubShape );
840 THROW_SALOME_CORBA_EXCEPTION("not sub-shape of the main shape", SALOME::BAD_PARAM);
842 subMesh = getSubMesh( subMeshId );
844 // create a new subMesh object servant if there is none for the shape
845 if ( subMesh->_is_nil() )
846 subMesh = createSubMesh( aSubShape );
847 if ( _gen_i->CanPublishInStudy( subMesh ))
849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
850 SALOMEDS::SObject_wrap aSO =
851 _gen_i->PublishSubMesh( study, aMesh, subMesh, aSubShape, theName );
852 if ( !aSO->_is_nil()) {
853 // Update Python script
854 TPythonDump() << aSO << " = " << aMesh << ".GetSubMesh( "
855 << aSubShape << ", '" << theName << "' )";
859 catch(SALOME_Exception & S_ex) {
860 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
862 return subMesh._retn();
865 //=============================================================================
869 //=============================================================================
871 void SMESH_Mesh_i::RemoveSubMesh( SMESH::SMESH_subMesh_ptr theSubMesh )
872 throw (SALOME::SALOME_Exception)
876 if ( theSubMesh->_is_nil() )
879 GEOM::GEOM_Object_var aSubShape;
880 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
881 if ( !aStudy->_is_nil() ) {
882 // Remove submesh's SObject
883 SALOMEDS::SObject_wrap anSO = _gen_i->ObjectToSObject( aStudy, theSubMesh );
884 if ( !anSO->_is_nil() ) {
885 long aTag = SMESH_Gen_i::GetRefOnShapeTag();
886 SALOMEDS::SObject_wrap anObj, aRef;
887 if ( anSO->FindSubObject( aTag, anObj.inout() ) &&
888 anObj->ReferencedObject( aRef.inout() ))
890 CORBA::Object_var obj = aRef->GetObject();
891 aSubShape = GEOM::GEOM_Object::_narrow( obj );
893 // if ( aSubShape->_is_nil() ) // not published shape (IPAL13617)
894 // aSubShape = theSubMesh->GetSubShape();
896 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
897 builder->RemoveObjectWithChildren( anSO );
899 // Update Python script
900 TPythonDump() << SMESH::SMESH_Mesh_var( _this() ) << ".RemoveSubMesh( " << anSO << " )";
904 if ( removeSubMesh( theSubMesh, aSubShape.in() ))
906 _preMeshInfo->ForgetOrLoad();
908 SMESH_CATCH( SMESH::throwCorbaException );
911 //=============================================================================
915 //=============================================================================
917 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CreateGroup( SMESH::ElementType theElemType,
918 const char* theName )
919 throw(SALOME::SALOME_Exception)
921 Unexpect aCatch(SALOME_SalomeException);
923 _preMeshInfo->FullLoadFromFile();
925 SMESH::SMESH_Group_var aNewGroup =
926 SMESH::SMESH_Group::_narrow( createGroup( theElemType, theName ));
928 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
930 SMESH::SMESH_Mesh_var mesh = _this();
931 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
932 SALOMEDS::SObject_wrap aSO =
933 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName);
934 if ( !aSO->_is_nil())
935 // Update Python script
936 TPythonDump() << aSO << " = " << mesh << ".CreateGroup( "
937 << theElemType << ", '" << theName << "' )";
939 return aNewGroup._retn();
942 //=============================================================================
946 //=============================================================================
947 SMESH::SMESH_GroupOnGeom_ptr
948 SMESH_Mesh_i::CreateGroupFromGEOM (SMESH::ElementType theElemType,
950 GEOM::GEOM_Object_ptr theGeomObj)
951 throw(SALOME::SALOME_Exception)
953 Unexpect aCatch(SALOME_SalomeException);
955 _preMeshInfo->FullLoadFromFile();
957 SMESH::SMESH_GroupOnGeom_var aNewGroup;
959 TopoDS_Shape aShape = _gen_i->GeomObjectToShape( theGeomObj );
960 if ( !aShape.IsNull() )
963 SMESH::SMESH_GroupOnGeom::_narrow( createGroup( theElemType, theName, aShape ));
965 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
967 SMESH::SMESH_Mesh_var mesh = _this();
968 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
969 SALOMEDS::SObject_wrap aSO =
970 _gen_i->PublishGroup( study, mesh, aNewGroup, theGeomObj, theName );
971 if ( !aSO->_is_nil())
972 TPythonDump() << aSO << " = " << mesh << ".CreateGroupFromGEOM( "
973 << theElemType << ", '" << theName << "', " << theGeomObj << " )";
977 return aNewGroup._retn();
980 //================================================================================
982 * \brief Creates a group whose contents is defined by filter
983 * \param theElemType - group type
984 * \param theName - group name
985 * \param theFilter - the filter
986 * \retval SMESH::SMESH_GroupOnFilter_ptr - group defined by filter
988 //================================================================================
990 SMESH::SMESH_GroupOnFilter_ptr
991 SMESH_Mesh_i::CreateGroupFromFilter(SMESH::ElementType theElemType,
993 SMESH::Filter_ptr theFilter )
994 throw (SALOME::SALOME_Exception)
996 Unexpect aCatch(SALOME_SalomeException);
998 _preMeshInfo->FullLoadFromFile();
1000 if ( CORBA::is_nil( theFilter ))
1001 THROW_SALOME_CORBA_EXCEPTION("NULL filter", SALOME::BAD_PARAM);
1003 SMESH_PredicatePtr predicate = SMESH_GroupOnFilter_i::GetPredicate( theFilter );
1005 THROW_SALOME_CORBA_EXCEPTION("Invalid filter", SALOME::BAD_PARAM);
1007 SMESH::SMESH_GroupOnFilter_var aNewGroup = SMESH::SMESH_GroupOnFilter::_narrow
1008 ( createGroup( theElemType, theName, TopoDS_Shape(), predicate ));
1011 if ( !aNewGroup->_is_nil() )
1012 aNewGroup->SetFilter( theFilter );
1014 if ( _gen_i->CanPublishInStudy( aNewGroup ) )
1016 SMESH::SMESH_Mesh_var mesh = _this();
1017 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1018 SALOMEDS::SObject_wrap aSO =
1019 _gen_i->PublishGroup( study, mesh, aNewGroup, GEOM::GEOM_Object::_nil(), theName );
1021 if ( !aSO->_is_nil())
1022 pd << aSO << " = " << mesh << ".CreateGroupFromFilter( "
1023 << theElemType << ", '" << theName << "', " << theFilter << " )";
1025 return aNewGroup._retn();
1028 //=============================================================================
1032 //=============================================================================
1034 void SMESH_Mesh_i::RemoveGroup( SMESH::SMESH_GroupBase_ptr theGroup )
1035 throw (SALOME::SALOME_Exception)
1037 if ( theGroup->_is_nil() )
1042 SMESH_GroupBase_i* aGroup = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
1046 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
1047 if ( !aStudy->_is_nil() )
1049 SALOMEDS::SObject_wrap aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
1050 if ( !aGroupSO->_is_nil() )
1052 // Update Python script
1053 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".RemoveGroup( " << aGroupSO << " )";
1055 // Remove group's SObject
1056 SALOMEDS::StudyBuilder_var builder = aStudy->NewBuilder();
1057 builder->RemoveObjectWithChildren( aGroupSO );
1061 // Remove the group from SMESH data structures
1062 removeGroup( aGroup->GetLocalID() );
1064 SMESH_CATCH( SMESH::throwCorbaException );
1067 //=============================================================================
1069 * Remove group with its contents
1071 //=============================================================================
1073 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1074 throw (SALOME::SALOME_Exception)
1078 _preMeshInfo->FullLoadFromFile();
1080 if ( theGroup->_is_nil() )
1084 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1085 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1086 while ( elemIt->more() )
1087 _impl->GetMeshDS()->RemoveElement( elemIt->next() );
1089 TPythonDump pyDump; // Supress dump from RemoveGroup()
1091 // Update Python script (theGroup must be alive for this)
1092 pyDump << SMESH::SMESH_Mesh_var(_this())
1093 << ".RemoveGroupWithContents( " << theGroup << " )";
1096 RemoveGroup( theGroup );
1098 SMESH_CATCH( SMESH::throwCorbaException );
1101 //================================================================================
1103 * \brief Get the list of groups existing in the mesh
1104 * \retval SMESH::ListOfGroups * - list of groups
1106 //================================================================================
1108 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1110 Unexpect aCatch(SALOME_SalomeException);
1111 if (MYDEBUG) MESSAGE("GetGroups");
1113 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1116 TPythonDump aPythonDump;
1117 if ( !_mapGroups.empty() )
1119 aPythonDump << "[ ";
1121 aList->length( _mapGroups.size() );
1123 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1124 for ( ; it != _mapGroups.end(); it++ ) {
1125 if ( CORBA::is_nil( it->second )) continue;
1126 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1128 if (i > 1) aPythonDump << ", ";
1129 aPythonDump << it->second;
1133 catch(SALOME_Exception & S_ex) {
1134 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1136 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1138 return aList._retn();
1141 //=============================================================================
1143 * Get number of groups existing in the mesh
1145 //=============================================================================
1147 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1149 Unexpect aCatch(SALOME_SalomeException);
1150 return _mapGroups.size();
1153 //=============================================================================
1155 * New group including all mesh elements present in initial groups is created.
1157 //=============================================================================
1159 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1160 SMESH::SMESH_GroupBase_ptr theGroup2,
1161 const char* theName )
1162 throw (SALOME::SALOME_Exception)
1164 SMESH::SMESH_Group_var aResGrp;
1168 _preMeshInfo->FullLoadFromFile();
1170 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1171 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1173 if ( theGroup1->GetType() != theGroup2->GetType() )
1174 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1179 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1180 if ( aResGrp->_is_nil() )
1181 return SMESH::SMESH_Group::_nil();
1183 aResGrp->AddFrom( theGroup1 );
1184 aResGrp->AddFrom( theGroup2 );
1186 // Update Python script
1187 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1188 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1190 SMESH_CATCH( SMESH::throwCorbaException );
1192 return aResGrp._retn();
1195 //=============================================================================
1197 * \brief New group including all mesh elements present in initial groups is created.
1198 * \param theGroups list of groups
1199 * \param theName name of group to be created
1200 * \return pointer to the new group
1202 //=============================================================================
1204 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1205 const char* theName )
1206 throw (SALOME::SALOME_Exception)
1208 SMESH::SMESH_Group_var aResGrp;
1211 _preMeshInfo->FullLoadFromFile();
1214 return SMESH::SMESH_Group::_nil();
1219 SMESH::ElementType aType = SMESH::ALL;
1220 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1222 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1223 if ( CORBA::is_nil( aGrp ) )
1225 if ( aType == SMESH::ALL )
1226 aType = aGrp->GetType();
1227 else if ( aType != aGrp->GetType() )
1228 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1231 if ( aType == SMESH::ALL )
1232 return SMESH::SMESH_Group::_nil();
1237 aResGrp = CreateGroup( aType, theName );
1238 if ( aResGrp->_is_nil() )
1239 return SMESH::SMESH_Group::_nil();
1241 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1242 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1244 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1245 if ( !CORBA::is_nil( aGrp ) )
1247 aResGrp->AddFrom( aGrp );
1248 if ( g > 0 ) pyDump << ", ";
1252 pyDump << " ], '" << theName << "' )";
1254 SMESH_CATCH( SMESH::throwCorbaException );
1256 return aResGrp._retn();
1259 //=============================================================================
1261 * New group is created. All mesh elements that are
1262 * present in both initial groups are added to the new one.
1264 //=============================================================================
1266 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1267 SMESH::SMESH_GroupBase_ptr theGroup2,
1268 const char* theName )
1269 throw (SALOME::SALOME_Exception)
1271 SMESH::SMESH_Group_var aResGrp;
1276 _preMeshInfo->FullLoadFromFile();
1278 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1279 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1281 if ( theGroup1->GetType() != theGroup2->GetType() )
1282 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1286 // Create Intersection
1287 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1288 if ( aResGrp->_is_nil() )
1289 return aResGrp._retn();
1291 SMESHDS_GroupBase* groupDS1 = 0;
1292 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1293 groupDS1 = grp_i->GetGroupDS();
1295 SMESHDS_GroupBase* groupDS2 = 0;
1296 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1297 groupDS2 = grp_i->GetGroupDS();
1299 SMESHDS_Group* resGroupDS = 0;
1300 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1301 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1303 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1305 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1306 while ( elemIt1->more() )
1308 const SMDS_MeshElement* e = elemIt1->next();
1309 if ( groupDS2->Contains( e ))
1310 resGroupDS->SMDSGroup().Add( e );
1313 // Update Python script
1314 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1315 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1317 SMESH_CATCH( SMESH::throwCorbaException );
1319 return aResGrp._retn();
1322 //=============================================================================
1324 \brief Intersect list of groups. New group is created. All mesh elements that
1325 are present in all initial groups simultaneously are added to the new one.
1326 \param theGroups list of groups
1327 \param theName name of group to be created
1328 \return pointer on the group
1330 //=============================================================================
1331 SMESH::SMESH_Group_ptr
1332 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1333 const char* theName )
1334 throw (SALOME::SALOME_Exception)
1336 SMESH::SMESH_Group_var aResGrp;
1341 _preMeshInfo->FullLoadFromFile();
1344 return SMESH::SMESH_Group::_nil();
1346 // check types and get SMESHDS_GroupBase's
1347 SMESH::ElementType aType = SMESH::ALL;
1348 vector< SMESHDS_GroupBase* > groupVec;
1349 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1351 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1352 if ( CORBA::is_nil( aGrp ) )
1354 if ( aType == SMESH::ALL )
1355 aType = aGrp->GetType();
1356 else if ( aType != aGrp->GetType() )
1357 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1360 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1361 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1363 if ( grpDS->IsEmpty() )
1368 groupVec.push_back( grpDS );
1371 if ( aType == SMESH::ALL ) // all groups are nil
1372 return SMESH::SMESH_Group::_nil();
1377 aResGrp = CreateGroup( aType, theName );
1379 SMESHDS_Group* resGroupDS = 0;
1380 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1381 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1382 if ( !resGroupDS || groupVec.empty() )
1383 return aResGrp._retn();
1386 size_t i, nb = groupVec.size();
1387 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1388 while ( elemIt1->more() )
1390 const SMDS_MeshElement* e = elemIt1->next();
1392 for ( i = 1; ( i < nb && inAll ); ++i )
1393 inAll = groupVec[i]->Contains( e );
1396 resGroupDS->SMDSGroup().Add( e );
1399 // Update Python script
1400 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1401 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1403 SMESH_CATCH( SMESH::throwCorbaException );
1405 return aResGrp._retn();
1408 //=============================================================================
1410 * New group is created. All mesh elements that are present in
1411 * a main group but is not present in a tool group are added to the new one
1413 //=============================================================================
1415 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1416 SMESH::SMESH_GroupBase_ptr theGroup2,
1417 const char* theName )
1418 throw (SALOME::SALOME_Exception)
1420 SMESH::SMESH_Group_var aResGrp;
1425 _preMeshInfo->FullLoadFromFile();
1427 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1428 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1430 if ( theGroup1->GetType() != theGroup2->GetType() )
1431 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1435 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1436 if ( aResGrp->_is_nil() )
1437 return aResGrp._retn();
1439 SMESHDS_GroupBase* groupDS1 = 0;
1440 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1441 groupDS1 = grp_i->GetGroupDS();
1443 SMESHDS_GroupBase* groupDS2 = 0;
1444 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1445 groupDS2 = grp_i->GetGroupDS();
1447 SMESHDS_Group* resGroupDS = 0;
1448 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1449 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1451 if ( groupDS1 && groupDS2 && resGroupDS )
1453 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1454 while ( elemIt1->more() )
1456 const SMDS_MeshElement* e = elemIt1->next();
1457 if ( !groupDS2->Contains( e ))
1458 resGroupDS->SMDSGroup().Add( e );
1461 // Update Python script
1462 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1463 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1465 SMESH_CATCH( SMESH::throwCorbaException );
1467 return aResGrp._retn();
1470 //=============================================================================
1472 \brief Cut lists of groups. New group is created. All mesh elements that are
1473 present in main groups but do not present in tool groups are added to the new one
1474 \param theMainGroups list of main groups
1475 \param theToolGroups list of tool groups
1476 \param theName name of group to be created
1477 \return pointer on the group
1479 //=============================================================================
1480 SMESH::SMESH_Group_ptr
1481 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1482 const SMESH::ListOfGroups& theToolGroups,
1483 const char* theName )
1484 throw (SALOME::SALOME_Exception)
1486 SMESH::SMESH_Group_var aResGrp;
1491 _preMeshInfo->FullLoadFromFile();
1494 return SMESH::SMESH_Group::_nil();
1496 // check types and get SMESHDS_GroupBase's
1497 SMESH::ElementType aType = SMESH::ALL;
1498 vector< SMESHDS_GroupBase* > toolGroupVec;
1499 vector< SMDS_ElemIteratorPtr > mainIterVec;
1501 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1503 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1504 if ( CORBA::is_nil( aGrp ) )
1506 if ( aType == SMESH::ALL )
1507 aType = aGrp->GetType();
1508 else if ( aType != aGrp->GetType() )
1509 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1511 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1512 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1513 if ( !grpDS->IsEmpty() )
1514 mainIterVec.push_back( grpDS->GetElements() );
1516 if ( aType == SMESH::ALL ) // all main groups are nil
1517 return SMESH::SMESH_Group::_nil();
1518 if ( mainIterVec.empty() ) // all main groups are empty
1519 return aResGrp._retn();
1521 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1523 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1524 if ( CORBA::is_nil( aGrp ) )
1526 if ( aType != aGrp->GetType() )
1527 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1529 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1530 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1531 toolGroupVec.push_back( grpDS );
1537 aResGrp = CreateGroup( aType, theName );
1539 SMESHDS_Group* resGroupDS = 0;
1540 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1541 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1543 return aResGrp._retn();
1546 size_t i, nb = toolGroupVec.size();
1547 SMDS_ElemIteratorPtr mainElemIt
1548 ( new SMDS_IteratorOnIterators
1549 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1550 while ( mainElemIt->more() )
1552 const SMDS_MeshElement* e = mainElemIt->next();
1554 for ( i = 0; ( i < nb && !isIn ); ++i )
1555 isIn = toolGroupVec[i]->Contains( e );
1558 resGroupDS->SMDSGroup().Add( e );
1561 // Update Python script
1562 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1563 << ".CutListOfGroups( " << theMainGroups << ", "
1564 << theToolGroups << ", '" << theName << "' )";
1566 SMESH_CATCH( SMESH::throwCorbaException );
1568 return aResGrp._retn();
1571 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1573 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1574 bool & toStopChecking )
1576 toStopChecking = ( nbCommon < nbChecked );
1577 return nbCommon == nbNodes;
1579 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1580 bool & toStopChecking )
1582 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1583 return nbCommon == nbCorners;
1585 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1586 bool & toStopChecking )
1588 return nbCommon > 0;
1590 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1591 bool & toStopChecking )
1593 return nbCommon >= nbNodes / 2;
1597 //=============================================================================
1599 * Create a group of entities basing on nodes of other groups.
1600 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1601 * \param [in] anElemType - a type of elements to include to the new group.
1602 * \param [in] theName - a name of the new group.
1603 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1604 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1605 * new group provided that it is based on nodes of an element of \a aListOfGroups
1606 * \return SMESH_Group - the created group
1608 // IMP 19939, bug 22010, IMP 22635
1609 //=============================================================================
1611 SMESH::SMESH_Group_ptr
1612 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1613 SMESH::ElementType theElemType,
1614 const char* theName,
1615 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1616 CORBA::Boolean theUnderlyingOnly)
1617 throw (SALOME::SALOME_Exception)
1619 SMESH::SMESH_Group_var aResGrp;
1623 _preMeshInfo->FullLoadFromFile();
1625 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1627 if ( !theName || !aMeshDS )
1628 return SMESH::SMESH_Group::_nil();
1630 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1632 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1633 SMESH_Comment nbCoNoStr( "SMESH.");
1634 switch ( theNbCommonNodes ) {
1635 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1636 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1637 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1638 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1639 default: return aResGrp._retn();
1641 int nbChecked, nbCommon, nbNodes, nbCorners;
1647 aResGrp = CreateGroup( theElemType, theName );
1648 if ( aResGrp->_is_nil() )
1649 return SMESH::SMESH_Group::_nil();
1651 SMESHDS_GroupBase* groupBaseDS =
1652 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1653 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1655 vector<bool> isNodeInGroups;
1657 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1659 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1660 if ( CORBA::is_nil( aGrp ) )
1662 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1663 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1666 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1667 if ( !elIt ) continue;
1669 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1671 while ( elIt->more() ) {
1672 const SMDS_MeshElement* el = elIt->next();
1673 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1674 while ( nIt->more() )
1675 resGroupCore.Add( nIt->next() );
1678 // get elements of theElemType based on nodes of every element of group
1679 else if ( theUnderlyingOnly )
1681 while ( elIt->more() )
1683 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1684 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1685 TIDSortedElemSet checkedElems;
1686 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1687 while ( nIt->more() )
1689 const SMDS_MeshNode* n = nIt->next();
1690 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1691 // check nodes of elements of theElemType around el
1692 while ( elOfTypeIt->more() )
1694 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1695 if ( !checkedElems.insert( elOfType ).second ) continue;
1696 nbNodes = elOfType->NbNodes();
1697 nbCorners = elOfType->NbCornerNodes();
1699 bool toStopChecking = false;
1700 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1701 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1702 if ( elNodes.count( nIt2->next() ) &&
1703 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1705 resGroupCore.Add( elOfType );
1712 // get all nodes of elements of groups
1715 while ( elIt->more() )
1717 const SMDS_MeshElement* el = elIt->next(); // an element of group
1718 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1719 while ( nIt->more() )
1721 const SMDS_MeshNode* n = nIt->next();
1722 if ( n->GetID() >= isNodeInGroups.size() )
1723 isNodeInGroups.resize( n->GetID() + 1, false );
1724 isNodeInGroups[ n->GetID() ] = true;
1730 // Get elements of theElemType based on a certain number of nodes of elements of groups
1731 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1733 const SMDS_MeshNode* n;
1734 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1735 const int isNodeInGroupsSize = isNodeInGroups.size();
1736 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1738 if ( !isNodeInGroups[ iN ] ||
1739 !( n = aMeshDS->FindNode( iN )))
1742 // check nodes of elements of theElemType around n
1743 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1744 while ( elOfTypeIt->more() )
1746 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1747 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1752 nbNodes = elOfType->NbNodes();
1753 nbCorners = elOfType->NbCornerNodes();
1755 bool toStopChecking = false;
1756 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1757 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1759 const int nID = nIt->next()->GetID();
1760 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1761 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1763 resGroupCore.Add( elOfType );
1771 // Update Python script
1772 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1773 << ".CreateDimGroup( "
1774 << theGroups << ", " << theElemType << ", '" << theName << "', "
1775 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1777 SMESH_CATCH( SMESH::throwCorbaException );
1779 return aResGrp._retn();
1782 //================================================================================
1784 * \brief Remember GEOM group data
1786 //================================================================================
1788 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1789 CORBA::Object_ptr theSmeshObj)
1791 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1794 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1795 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1796 if ( groupSO->_is_nil() )
1799 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1800 GEOM::GEOM_IGroupOperations_wrap groupOp =
1801 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1802 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1805 _geomGroupData.push_back( TGeomGroupData() );
1806 TGeomGroupData & groupData = _geomGroupData.back();
1808 CORBA::String_var entry = groupSO->GetID();
1809 groupData._groupEntry = entry.in();
1811 for ( int i = 0; i < ids->length(); ++i )
1812 groupData._indices.insert( ids[i] );
1814 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1815 // shape index in SMESHDS
1816 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1817 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1820 //================================================================================
1822 * Remove GEOM group data relating to removed smesh object
1824 //================================================================================
1826 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1828 list<TGeomGroupData>::iterator
1829 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1830 for ( ; data != dataEnd; ++data ) {
1831 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1832 _geomGroupData.erase( data );
1838 //================================================================================
1840 * \brief Return new group contents if it has been changed and update group data
1842 //================================================================================
1844 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1846 TopoDS_Shape newShape;
1849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1850 if ( study->_is_nil() ) return newShape; // means "not changed"
1851 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1852 if ( !groupSO->_is_nil() )
1854 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1855 if ( CORBA::is_nil( groupObj )) return newShape;
1856 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1858 // get indices of group items
1859 set<int> curIndices;
1860 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1861 GEOM::GEOM_IGroupOperations_wrap groupOp =
1862 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1863 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1864 for ( int i = 0; i < ids->length(); ++i )
1865 curIndices.insert( ids[i] );
1867 if ( groupData._indices == curIndices )
1868 return newShape; // group not changed
1871 groupData._indices = curIndices;
1873 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1874 if ( !geomClient ) return newShape;
1875 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1876 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1877 newShape = _gen_i->GeomObjectToShape( geomGroup );
1880 if ( newShape.IsNull() ) {
1881 // geom group becomes empty - return empty compound
1882 TopoDS_Compound compound;
1883 BRep_Builder().MakeCompound(compound);
1884 newShape = compound;
1891 //-----------------------------------------------------------------------------
1893 * \brief Storage of shape and index used in CheckGeomGroupModif()
1895 struct TIndexedShape
1898 TopoDS_Shape _shape;
1899 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1901 //-----------------------------------------------------------------------------
1903 * \brief Data to re-create a group on geometry
1905 struct TGroupOnGeomData
1909 SMDSAbs_ElementType _type;
1911 Quantity_Color _color;
1915 //=============================================================================
1917 * \brief Update data if geometry changes
1921 //=============================================================================
1923 void SMESH_Mesh_i::CheckGeomModif()
1925 if ( !_impl->HasShapeToMesh() ) return;
1927 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1928 if ( study->_is_nil() ) return;
1930 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1931 if ( mainGO->_is_nil() ) return;
1933 if ( mainGO->GetType() == GEOM_GROUP ||
1934 mainGO->GetTick() == _mainShapeTick )
1936 CheckGeomGroupModif();
1940 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1941 if ( !geomClient ) return;
1942 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1943 if ( geomGen->_is_nil() ) return;
1945 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1946 geomClient->RemoveShapeFromBuffer( ior.in() );
1948 // Update data taking into account that
1949 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1952 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1953 if ( newShape.IsNull() )
1956 _mainShapeTick = mainGO->GetTick();
1958 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1960 // store data of groups on geometry
1961 vector< TGroupOnGeomData > groupsData;
1962 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1963 groupsData.reserve( groups.size() );
1964 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1965 for ( ; g != groups.end(); ++g )
1966 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1968 TGroupOnGeomData data;
1969 data._oldID = group->GetID();
1970 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1971 data._type = group->GetType();
1972 data._name = group->GetStoreName();
1973 data._color = group->GetColor();
1974 groupsData.push_back( data );
1976 // store assigned hypotheses
1977 vector< pair< int, THypList > > ids2Hyps;
1978 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1979 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1981 const TopoDS_Shape& s = s2hyps.Key();
1982 const THypList& hyps = s2hyps.ChangeValue();
1983 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1986 // change shape to mesh
1987 int oldNbSubShapes = meshDS->MaxShapeIndex();
1988 _impl->ShapeToMesh( TopoDS_Shape() );
1989 _impl->ShapeToMesh( newShape );
1991 // re-add shapes of geom groups
1992 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1993 for ( ; data != _geomGroupData.end(); ++data )
1995 TopoDS_Shape newShape = newGroupShape( *data );
1996 if ( !newShape.IsNull() )
1998 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2000 TopoDS_Compound compound;
2001 BRep_Builder().MakeCompound( compound );
2002 BRep_Builder().Add( compound, newShape );
2003 newShape = compound;
2005 _impl->GetSubMesh( newShape );
2008 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2009 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2010 SALOME::INTERNAL_ERROR );
2012 // re-assign hypotheses
2013 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2015 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2016 const THypList& hyps = ids2Hyps[i].second;
2017 THypList::const_iterator h = hyps.begin();
2018 for ( ; h != hyps.end(); ++h )
2019 _impl->AddHypothesis( s, (*h)->GetID() );
2023 for ( size_t i = 0; i < groupsData.size(); ++i )
2025 const TGroupOnGeomData& data = groupsData[i];
2027 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2028 if ( i2g == _mapGroups.end() ) continue;
2030 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2031 if ( !gr_i ) continue;
2034 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2035 meshDS->IndexToShape( data._shapeID ));
2038 _mapGroups.erase( i2g );
2042 g->GetGroupDS()->SetColor( data._color );
2043 gr_i->changeLocalId( id );
2044 _mapGroups[ id ] = i2g->second;
2045 if ( data._oldID != id )
2046 _mapGroups.erase( i2g );
2050 // update _mapSubMesh
2051 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2052 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2053 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2057 //=============================================================================
2059 * \brief Update objects depending on changed geom groups
2061 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2062 * issue 0020210: Update of a smesh group after modification of the associated geom group
2064 //=============================================================================
2066 void SMESH_Mesh_i::CheckGeomGroupModif()
2068 if ( !_impl->HasShapeToMesh() ) return;
2070 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2071 if ( study->_is_nil() ) return;
2073 CORBA::Long nbEntities = NbNodes() + NbElements();
2075 // Check if group contents changed
2077 typedef map< string, TopoDS_Shape > TEntry2Geom;
2078 TEntry2Geom newGroupContents;
2080 list<TGeomGroupData>::iterator
2081 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2082 for ( ; data != dataEnd; ++data )
2084 pair< TEntry2Geom::iterator, bool > it_new =
2085 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2086 bool processedGroup = !it_new.second;
2087 TopoDS_Shape& newShape = it_new.first->second;
2088 if ( !processedGroup )
2089 newShape = newGroupShape( *data );
2090 if ( newShape.IsNull() )
2091 continue; // no changes
2094 _preMeshInfo->ForgetOrLoad();
2096 if ( processedGroup ) { // update group indices
2097 list<TGeomGroupData>::iterator data2 = data;
2098 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2099 data->_indices = data2->_indices;
2102 // Update SMESH objects according to new GEOM group contents
2104 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2105 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2107 int oldID = submesh->GetId();
2108 if ( !_mapSubMeshIor.count( oldID ))
2110 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2112 // update hypotheses
2113 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2114 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2115 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2117 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2118 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2120 // care of submeshes
2121 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2122 int newID = newSubmesh->GetId();
2123 if ( newID != oldID ) {
2124 _mapSubMesh [ newID ] = newSubmesh;
2125 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2126 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2127 _mapSubMesh. erase(oldID);
2128 _mapSubMesh_i. erase(oldID);
2129 _mapSubMeshIor.erase(oldID);
2130 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2135 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2136 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2137 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2139 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2141 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2142 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2143 ds->SetShape( newShape );
2148 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2149 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2151 // Remove groups and submeshes basing on removed sub-shapes
2153 TopTools_MapOfShape newShapeMap;
2154 TopoDS_Iterator shapeIt( newShape );
2155 for ( ; shapeIt.More(); shapeIt.Next() )
2156 newShapeMap.Add( shapeIt.Value() );
2158 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2159 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2161 if ( newShapeMap.Contains( shapeIt.Value() ))
2163 TopTools_IndexedMapOfShape oldShapeMap;
2164 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2165 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2167 const TopoDS_Shape& oldShape = oldShapeMap(i);
2168 int oldInd = meshDS->ShapeToIndex( oldShape );
2170 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2171 if ( i_smIor != _mapSubMeshIor.end() ) {
2172 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2175 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2176 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2178 // check if a group bases on oldInd shape
2179 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2180 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2181 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2182 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2184 RemoveGroup( i_grp->second ); // several groups can base on same shape
2185 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2190 // Reassign hypotheses and update groups after setting the new shape to mesh
2192 // collect anassigned hypotheses
2193 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2194 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2195 TShapeHypList assignedHyps;
2196 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2198 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2199 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2200 if ( !hyps.empty() ) {
2201 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2202 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2203 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2206 // collect shapes supporting groups
2207 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2208 TShapeTypeList groupData;
2209 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2210 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2211 for ( ; grIt != groups.end(); ++grIt )
2213 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2215 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2217 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2218 _impl->ShapeToMesh( newShape );
2220 // reassign hypotheses
2221 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2222 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2224 TIndexedShape& geom = indS_hyps->first;
2225 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2226 int oldID = geom._index;
2227 int newID = meshDS->ShapeToIndex( geom._shape );
2228 if ( oldID == 1 ) { // main shape
2230 geom._shape = newShape;
2234 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2235 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2236 // care of submeshes
2237 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2238 if ( newID != oldID ) {
2239 _mapSubMesh [ newID ] = newSubmesh;
2240 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2241 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2242 _mapSubMesh. erase(oldID);
2243 _mapSubMesh_i. erase(oldID);
2244 _mapSubMeshIor.erase(oldID);
2245 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2249 TShapeTypeList::iterator geomType = groupData.begin();
2250 for ( ; geomType != groupData.end(); ++geomType )
2252 const TIndexedShape& geom = geomType->first;
2253 int oldID = geom._index;
2254 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2257 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2258 CORBA::String_var name = groupSO->GetName();
2260 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2262 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2263 group_i->changeLocalId( newID );
2266 break; // everything has been updated
2269 } // loop on group data
2273 CORBA::Long newNbEntities = NbNodes() + NbElements();
2274 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2275 if ( newNbEntities != nbEntities )
2277 // Add all SObjects with icons to soToUpdateIcons
2278 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2280 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2281 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2282 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2284 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2285 i_gr != _mapGroups.end(); ++i_gr ) // groups
2286 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2289 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2290 for ( ; so != soToUpdateIcons.end(); ++so )
2291 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2294 //=============================================================================
2296 * \brief Create standalone group from a group on geometry or filter
2298 //=============================================================================
2300 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2301 throw (SALOME::SALOME_Exception)
2303 SMESH::SMESH_Group_var aGroup;
2308 _preMeshInfo->FullLoadFromFile();
2310 if ( theGroup->_is_nil() )
2311 return aGroup._retn();
2313 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2315 return aGroup._retn();
2317 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2319 const int anId = aGroupToRem->GetLocalID();
2320 if ( !_impl->ConvertToStandalone( anId ) )
2321 return aGroup._retn();
2322 removeGeomGroupData( theGroup );
2324 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2326 // remove old instance of group from own map
2327 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2328 _mapGroups.erase( anId );
2330 SALOMEDS::StudyBuilder_var builder;
2331 SALOMEDS::SObject_wrap aGroupSO;
2332 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2333 if ( !aStudy->_is_nil() ) {
2334 builder = aStudy->NewBuilder();
2335 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2336 if ( !aGroupSO->_is_nil() )
2338 // remove reference to geometry
2339 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2340 for ( ; chItr->More(); chItr->Next() )
2341 // Remove group's child SObject
2342 builder->RemoveObject( chItr->Value() );
2344 // Update Python script
2345 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2346 << ".ConvertToStandalone( " << aGroupSO << " )";
2348 // change icon of Group on Filter
2351 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2352 const int isEmpty = ( elemTypes->length() == 0 );
2355 SALOMEDS::GenericAttribute_wrap anAttr =
2356 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2357 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2358 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2364 // remember new group in own map
2365 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2366 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2368 // register CORBA object for persistence
2369 _gen_i->RegisterObject( aGroup );
2371 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2372 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2373 //aGroup->Register();
2374 aGroupToRem->UnRegister();
2376 SMESH_CATCH( SMESH::throwCorbaException );
2378 return aGroup._retn();
2381 //=============================================================================
2385 //=============================================================================
2387 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2389 if(MYDEBUG) MESSAGE( "createSubMesh" );
2390 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2391 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2392 const int subMeshId = mySubMesh->GetId();
2394 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2395 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2397 _mapSubMesh [subMeshId] = mySubMesh;
2398 _mapSubMesh_i [subMeshId] = subMeshServant;
2399 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2401 subMeshServant->Register();
2403 // register CORBA object for persistence
2404 int nextId = _gen_i->RegisterObject( subMesh );
2405 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2406 else { nextId = 0; } // avoid "unused variable" warning
2408 // to track changes of GEOM groups
2409 addGeomGroupData( theSubShapeObject, subMesh );
2411 return subMesh._retn();
2414 //=======================================================================
2415 //function : getSubMesh
2417 //=======================================================================
2419 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2421 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2422 if ( it == _mapSubMeshIor.end() )
2423 return SMESH::SMESH_subMesh::_nil();
2425 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2428 //=============================================================================
2432 //=============================================================================
2434 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2435 GEOM::GEOM_Object_ptr theSubShapeObject )
2437 bool isHypChanged = false;
2438 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2439 return isHypChanged;
2441 const int subMeshId = theSubMesh->GetId();
2443 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2445 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2447 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2450 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2451 isHypChanged = !hyps.empty();
2452 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2453 for ( ; hyp != hyps.end(); ++hyp )
2454 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2461 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2462 isHypChanged = ( aHypList->length() > 0 );
2463 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2464 removeHypothesis( theSubShapeObject, aHypList[i] );
2467 catch( const SALOME::SALOME_Exception& ) {
2468 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2470 removeGeomGroupData( theSubShapeObject );
2474 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2475 if ( id_smi != _mapSubMesh_i.end() )
2476 id_smi->second->UnRegister();
2478 // remove a CORBA object
2479 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2480 if ( id_smptr != _mapSubMeshIor.end() )
2481 SMESH::SMESH_subMesh_var( id_smptr->second );
2483 _mapSubMesh.erase(subMeshId);
2484 _mapSubMesh_i.erase(subMeshId);
2485 _mapSubMeshIor.erase(subMeshId);
2487 return isHypChanged;
2490 //=============================================================================
2494 //=============================================================================
2496 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2497 const char* theName,
2498 const TopoDS_Shape& theShape,
2499 const SMESH_PredicatePtr& thePredicate )
2501 std::string newName;
2502 if ( !theName || strlen( theName ) == 0 )
2504 std::set< std::string > presentNames;
2505 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2506 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2508 CORBA::String_var name = i_gr->second->GetName();
2509 presentNames.insert( name.in() );
2512 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2513 } while ( !presentNames.insert( newName ).second );
2514 theName = newName.c_str();
2517 SMESH::SMESH_GroupBase_var aGroup;
2518 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2520 SMESH_GroupBase_i* aGroupImpl;
2521 if ( !theShape.IsNull() )
2522 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2523 else if ( thePredicate )
2524 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2526 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2528 aGroup = aGroupImpl->_this();
2529 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2530 aGroupImpl->Register();
2532 // register CORBA object for persistence
2533 int nextId = _gen_i->RegisterObject( aGroup );
2534 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2535 else { nextId = 0; } // avoid "unused variable" warning in release mode
2537 // to track changes of GEOM groups
2538 if ( !theShape.IsNull() ) {
2539 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2540 addGeomGroupData( geom, aGroup );
2543 return aGroup._retn();
2546 //=============================================================================
2548 * SMESH_Mesh_i::removeGroup
2550 * Should be called by ~SMESH_Group_i()
2552 //=============================================================================
2554 void SMESH_Mesh_i::removeGroup( const int theId )
2556 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2557 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2558 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2559 _mapGroups.erase( theId );
2560 removeGeomGroupData( group );
2561 if ( !_impl->RemoveGroup( theId ))
2563 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2564 RemoveGroup( group );
2566 group->UnRegister();
2570 //=============================================================================
2574 //=============================================================================
2576 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2577 throw(SALOME::SALOME_Exception)
2579 SMESH::log_array_var aLog;
2583 _preMeshInfo->FullLoadFromFile();
2585 list < SMESHDS_Command * >logDS = _impl->GetLog();
2586 aLog = new SMESH::log_array;
2588 int lg = logDS.size();
2591 list < SMESHDS_Command * >::iterator its = logDS.begin();
2592 while(its != logDS.end()){
2593 SMESHDS_Command *com = *its;
2594 int comType = com->GetType();
2596 int lgcom = com->GetNumber();
2598 const list < int >&intList = com->GetIndexes();
2599 int inum = intList.size();
2601 list < int >::const_iterator ii = intList.begin();
2602 const list < double >&coordList = com->GetCoords();
2603 int rnum = coordList.size();
2605 list < double >::const_iterator ir = coordList.begin();
2606 aLog[indexLog].commandType = comType;
2607 aLog[indexLog].number = lgcom;
2608 aLog[indexLog].coords.length(rnum);
2609 aLog[indexLog].indexes.length(inum);
2610 for(int i = 0; i < rnum; i++){
2611 aLog[indexLog].coords[i] = *ir;
2612 //MESSAGE(" "<<i<<" "<<ir.Value());
2615 for(int i = 0; i < inum; i++){
2616 aLog[indexLog].indexes[i] = *ii;
2617 //MESSAGE(" "<<i<<" "<<ii.Value());
2626 SMESH_CATCH( SMESH::throwCorbaException );
2628 return aLog._retn();
2632 //=============================================================================
2636 //=============================================================================
2638 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2642 SMESH_CATCH( SMESH::throwCorbaException );
2645 //=============================================================================
2649 //=============================================================================
2651 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2656 //=============================================================================
2660 //=============================================================================
2662 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2667 //=============================================================================
2670 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2671 // issue 0020918: groups removal is caused by hyp modification
2672 // issue 0021208: to forget not loaded mesh data at hyp modification
2673 struct TCallUp_i : public SMESH_Mesh::TCallUp
2675 SMESH_Mesh_i* _mesh;
2676 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2677 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2678 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2679 virtual void Load () { _mesh->Load(); }
2683 //================================================================================
2685 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2687 //================================================================================
2689 void SMESH_Mesh_i::onHypothesisModified()
2692 _preMeshInfo->ForgetOrLoad();
2695 //=============================================================================
2699 //=============================================================================
2701 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2703 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2706 _impl->SetCallUp( new TCallUp_i(this));
2709 //=============================================================================
2713 //=============================================================================
2715 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2717 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2721 //=============================================================================
2723 * Return mesh editor
2725 //=============================================================================
2727 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2728 throw (SALOME::SALOME_Exception)
2730 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2734 _preMeshInfo->FullLoadFromFile();
2736 // Create MeshEditor
2738 _editor = new SMESH_MeshEditor_i( this, false );
2739 aMeshEdVar = _editor->_this();
2741 // Update Python script
2742 TPythonDump() << _editor << " = "
2743 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2745 SMESH_CATCH( SMESH::throwCorbaException );
2747 return aMeshEdVar._retn();
2750 //=============================================================================
2752 * Return mesh edition previewer
2754 //=============================================================================
2756 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2757 throw (SALOME::SALOME_Exception)
2759 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2763 _preMeshInfo->FullLoadFromFile();
2765 if ( !_previewEditor )
2766 _previewEditor = new SMESH_MeshEditor_i( this, true );
2767 aMeshEdVar = _previewEditor->_this();
2769 SMESH_CATCH( SMESH::throwCorbaException );
2771 return aMeshEdVar._retn();
2774 //================================================================================
2776 * \brief Return true if the mesh has been edited since a last total re-compute
2777 * and those modifications may prevent successful partial re-compute
2779 //================================================================================
2781 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2783 Unexpect aCatch(SALOME_SalomeException);
2784 return _impl->HasModificationsToDiscard();
2787 //================================================================================
2789 * \brief Returns a random unique color
2791 //================================================================================
2793 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2795 const int MAX_ATTEMPTS = 100;
2797 double tolerance = 0.5;
2798 SALOMEDS::Color col;
2802 // generate random color
2803 double red = (double)rand() / RAND_MAX;
2804 double green = (double)rand() / RAND_MAX;
2805 double blue = (double)rand() / RAND_MAX;
2806 // check existence in the list of the existing colors
2807 bool matched = false;
2808 std::list<SALOMEDS::Color>::const_iterator it;
2809 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2810 SALOMEDS::Color color = *it;
2811 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2812 matched = tol < tolerance;
2814 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2815 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2823 //=============================================================================
2825 * Sets auto-color mode. If it is on, groups get unique random colors
2827 //=============================================================================
2829 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2831 Unexpect aCatch(SALOME_SalomeException);
2832 _impl->SetAutoColor(theAutoColor);
2834 TPythonDump pyDump; // not to dump group->SetColor() from below code
2835 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2837 std::list<SALOMEDS::Color> aReservedColors;
2838 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2839 for ( ; it != _mapGroups.end(); it++ ) {
2840 if ( CORBA::is_nil( it->second )) continue;
2841 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2842 it->second->SetColor( aColor );
2843 aReservedColors.push_back( aColor );
2847 //=============================================================================
2849 * Returns true if auto-color mode is on
2851 //=============================================================================
2853 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2855 Unexpect aCatch(SALOME_SalomeException);
2856 return _impl->GetAutoColor();
2859 //=============================================================================
2861 * Checks if there are groups with equal names
2863 //=============================================================================
2865 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2867 return _impl->HasDuplicatedGroupNamesMED();
2870 //================================================================================
2872 * \brief Care of a file before exporting mesh into it
2874 //================================================================================
2876 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2878 SMESH_File aFile( file );
2880 if (aFile.exists()) {
2881 // existing filesystem node
2882 if ( !aFile.isDirectory() ) {
2883 if ( aFile.openForWriting() ) {
2884 if ( overwrite && ! aFile.remove()) {
2885 msg << "Can't replace " << aFile.getName();
2888 msg << "Can't write into " << aFile.getName();
2891 msg << "Location " << aFile.getName() << " is not a file";
2895 // nonexisting file; check if it can be created
2896 if ( !aFile.openForWriting() ) {
2897 msg << "You cannot create the file "
2899 << ". Check the directory existance and access rights";
2907 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2911 //================================================================================
2913 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2914 * \param file - file name
2915 * \param overwrite - to erase the file or not
2916 * \retval string - mesh name
2918 //================================================================================
2920 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2921 CORBA::Boolean overwrite)
2924 PrepareForWriting(file, overwrite);
2925 string aMeshName = "Mesh";
2926 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2927 if ( !aStudy->_is_nil() ) {
2928 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2929 if ( !aMeshSO->_is_nil() ) {
2930 CORBA::String_var name = aMeshSO->GetName();
2932 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2933 if ( !aStudy->GetProperties()->IsLocked() )
2935 SALOMEDS::GenericAttribute_wrap anAttr;
2936 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2937 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2938 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2939 ASSERT(!aFileName->_is_nil());
2940 aFileName->SetValue(file);
2941 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2942 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2943 ASSERT(!aFileType->_is_nil());
2944 aFileType->SetValue("FICHIERMED");
2948 // Update Python script
2949 // set name of mesh before export
2950 TPythonDump() << _gen_i << ".SetName("
2951 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2953 // check names of groups
2959 //================================================================================
2961 * \brief Export to med file
2963 //================================================================================
2965 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2966 CORBA::Boolean auto_groups,
2967 SMESH::MED_VERSION theVersion,
2968 CORBA::Boolean overwrite,
2969 CORBA::Boolean autoDimension)
2970 throw(SALOME::SALOME_Exception)
2974 _preMeshInfo->FullLoadFromFile();
2976 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2977 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2979 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2980 << file << "', " << auto_groups << ", "
2981 << theVersion << ", " << overwrite << ", "
2982 << autoDimension << " )";
2984 SMESH_CATCH( SMESH::throwCorbaException );
2987 //================================================================================
2989 * \brief Export a mesh to a med file
2991 //================================================================================
2993 void SMESH_Mesh_i::ExportToMED (const char* file,
2994 CORBA::Boolean auto_groups,
2995 SMESH::MED_VERSION theVersion)
2996 throw(SALOME::SALOME_Exception)
2998 ExportToMEDX(file,auto_groups,theVersion,true);
3001 //================================================================================
3003 * \brief Export a mesh to a med file
3005 //================================================================================
3007 void SMESH_Mesh_i::ExportMED (const char* file,
3008 CORBA::Boolean auto_groups)
3009 throw(SALOME::SALOME_Exception)
3011 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3014 //================================================================================
3016 * \brief Export a mesh to a SAUV file
3018 //================================================================================
3020 void SMESH_Mesh_i::ExportSAUV (const char* file,
3021 CORBA::Boolean auto_groups)
3022 throw(SALOME::SALOME_Exception)
3024 Unexpect aCatch(SALOME_SalomeException);
3026 _preMeshInfo->FullLoadFromFile();
3028 string aMeshName = prepareMeshNameAndGroups(file, true);
3029 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3030 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3031 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3035 //================================================================================
3037 * \brief Export a mesh to a DAT file
3039 //================================================================================
3041 void SMESH_Mesh_i::ExportDAT (const char *file)
3042 throw(SALOME::SALOME_Exception)
3044 Unexpect aCatch(SALOME_SalomeException);
3046 _preMeshInfo->FullLoadFromFile();
3048 // Update Python script
3049 // check names of groups
3051 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3054 PrepareForWriting(file);
3055 _impl->ExportDAT(file);
3058 //================================================================================
3060 * \brief Export a mesh to an UNV file
3062 //================================================================================
3064 void SMESH_Mesh_i::ExportUNV (const char *file)
3065 throw(SALOME::SALOME_Exception)
3067 Unexpect aCatch(SALOME_SalomeException);
3069 _preMeshInfo->FullLoadFromFile();
3071 // Update Python script
3072 // check names of groups
3074 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3077 PrepareForWriting(file);
3078 _impl->ExportUNV(file);
3081 //================================================================================
3083 * \brief Export a mesh to an STL file
3085 //================================================================================
3087 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3088 throw(SALOME::SALOME_Exception)
3090 Unexpect aCatch(SALOME_SalomeException);
3092 _preMeshInfo->FullLoadFromFile();
3094 // Update Python script
3095 // check names of groups
3097 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3098 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3101 PrepareForWriting(file);
3102 _impl->ExportSTL(file, isascii);
3105 //================================================================================
3107 * \brief Export a part of mesh to a med file
3109 //================================================================================
3111 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3113 CORBA::Boolean auto_groups,
3114 SMESH::MED_VERSION version,
3115 CORBA::Boolean overwrite,
3116 CORBA::Boolean autoDimension,
3117 const GEOM::ListOfFields& fields,
3118 const char* geomAssocFields)
3119 throw (SALOME::SALOME_Exception)
3123 _preMeshInfo->FullLoadFromFile();
3126 bool have0dField = false;
3127 if ( fields.length() > 0 )
3129 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3130 if ( shapeToMesh->_is_nil() )
3131 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3133 for ( size_t i = 0; i < fields.length(); ++i )
3135 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3136 THROW_SALOME_CORBA_EXCEPTION
3137 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3138 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3139 if ( fieldShape->_is_nil() )
3140 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3141 if ( !fieldShape->IsSame( shapeToMesh ) )
3142 THROW_SALOME_CORBA_EXCEPTION
3143 ( "Field defined not on shape", SALOME::BAD_PARAM);
3144 if ( fields[i]->GetDimension() == 0 )
3147 if ( geomAssocFields )
3148 for ( int i = 0; geomAssocFields[i]; ++i )
3149 switch ( geomAssocFields[i] ) {
3150 case 'v':case 'e':case 'f':case 's': break;
3151 case 'V':case 'E':case 'F':case 'S': break;
3152 default: THROW_SALOME_CORBA_EXCEPTION
3153 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3157 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3161 string aMeshName = "Mesh";
3162 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3163 if ( CORBA::is_nil( meshPart ) ||
3164 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3166 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3167 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3168 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3169 meshDS = _impl->GetMeshDS();
3174 _preMeshInfo->FullLoadFromFile();
3176 PrepareForWriting(file, overwrite);
3178 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3179 if ( !aStudy->_is_nil() ) {
3180 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3181 if ( !SO->_is_nil() ) {
3182 CORBA::String_var name = SO->GetName();
3186 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3187 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3188 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3189 meshDS = tmpDSDeleter._obj = partDS;
3194 if ( _impl->HasShapeToMesh() )
3196 DriverMED_W_Field fieldWriter;
3197 fieldWriter.SetFile( file );
3198 fieldWriter.SetMeshName( aMeshName );
3199 fieldWriter.AddODOnVertices( have0dField );
3201 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3205 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3206 goList->length( fields.length() );
3207 for ( size_t i = 0; i < fields.length(); ++i )
3209 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3212 TPythonDump() << _this() << ".ExportPartToMED( "
3213 << meshPart << ", r'" << file << "', "
3214 << auto_groups << ", " << version << ", " << overwrite << ", "
3215 << autoDimension << ", " << goList
3216 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3218 SMESH_CATCH( SMESH::throwCorbaException );
3221 //================================================================================
3223 * Write GEOM fields to MED file
3225 //================================================================================
3227 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3228 SMESHDS_Mesh* meshDS,
3229 const GEOM::ListOfFields& fields,
3230 const char* geomAssocFields)
3232 #define METH "SMESH_Mesh_i::exportMEDFields() "
3234 if (( fields.length() < 1 ) &&
3235 ( !geomAssocFields || !geomAssocFields[0] ))
3238 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3239 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3240 std::vector< int > subIdsByDim[ 4 ];
3241 const double noneDblValue = 0.;
3242 const double noneIntValue = 0;
3244 for ( size_t iF = 0; iF < fields.length(); ++iF )
3248 int dim = fields[ iF ]->GetDimension();
3249 SMDSAbs_ElementType elemType;
3250 TopAbs_ShapeEnum shapeType;
3252 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3253 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3254 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3255 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3257 continue; // skip fields on whole shape
3259 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3260 if ( dataType == GEOM::FDT_String )
3262 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3263 if ( stepIDs->length() < 1 )
3265 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3266 if ( comps->length() < 1 )
3268 CORBA::String_var name = fields[ iF ]->GetName();
3270 if ( !fieldWriter.Set( meshDS,
3274 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3277 for ( size_t iC = 0; iC < comps->length(); ++iC )
3278 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3280 // find sub-shape IDs
3282 std::vector< int >& subIds = subIdsByDim[ dim ];
3283 if ( subIds.empty() )
3284 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3285 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3286 subIds.push_back( id );
3290 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3294 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3296 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3297 if ( step->_is_nil() )
3300 CORBA::Long stamp = step->GetStamp();
3301 CORBA::Long id = step->GetID();
3302 fieldWriter.SetDtIt( int( stamp ), int( id ));
3304 // fill dblVals or intVals
3307 case GEOM::FDT_Double:
3309 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3310 if ( dblStep->_is_nil() ) continue;
3311 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3312 if ( vv->length() != subIds.size() )
3313 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3314 for ( size_t i = 0; i < vv->length(); ++i )
3315 dblVals[ subIds[ i ]] = vv[ i ];
3320 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3321 if ( intStep->_is_nil() ) continue;
3322 GEOM::ListOfLong_var vv = intStep->GetValues();
3323 if ( vv->length() != subIds.size() )
3324 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3325 for ( size_t i = 0; i < vv->length(); ++i )
3326 intVals[ subIds[ i ]] = (int) vv[ i ];
3329 case GEOM::FDT_Bool:
3331 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3332 if ( boolStep->_is_nil() ) continue;
3333 GEOM::short_array_var vv = boolStep->GetValues();
3334 if ( vv->length() != subIds.size() )
3335 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3336 for ( size_t i = 0; i < vv->length(); ++i )
3337 intVals[ subIds[ i ]] = (int) vv[ i ];
3343 // pass values to fieldWriter
3344 elemIt = fieldWriter.GetOrderedElems();
3345 if ( dataType == GEOM::FDT_Double )
3346 while ( elemIt->more() )
3348 const SMDS_MeshElement* e = elemIt->next();
3349 const int shapeID = e->getshapeId();
3350 if ( shapeID < 1 || shapeID >= dblVals.size() )
3351 fieldWriter.AddValue( noneDblValue );
3353 fieldWriter.AddValue( dblVals[ shapeID ]);
3356 while ( elemIt->more() )
3358 const SMDS_MeshElement* e = elemIt->next();
3359 const int shapeID = e->getshapeId();
3360 if ( shapeID < 1 || shapeID >= intVals.size() )
3361 fieldWriter.AddValue( (double) noneIntValue );
3363 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3367 fieldWriter.Perform();
3368 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3369 if ( res && res->IsKO() )
3371 if ( res->myComment.empty() )
3372 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3374 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3380 if ( !geomAssocFields || !geomAssocFields[0] )
3383 // write geomAssocFields
3385 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3386 shapeDim[ TopAbs_COMPOUND ] = 3;
3387 shapeDim[ TopAbs_COMPSOLID ] = 3;
3388 shapeDim[ TopAbs_SOLID ] = 3;
3389 shapeDim[ TopAbs_SHELL ] = 2;
3390 shapeDim[ TopAbs_FACE ] = 2;
3391 shapeDim[ TopAbs_WIRE ] = 1;
3392 shapeDim[ TopAbs_EDGE ] = 1;
3393 shapeDim[ TopAbs_VERTEX ] = 0;
3394 shapeDim[ TopAbs_SHAPE ] = 3;
3396 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3398 std::vector< std::string > compNames;
3399 switch ( geomAssocFields[ iF ]) {
3401 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3402 compNames.push_back( "dim" );
3405 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3408 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3411 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3415 compNames.push_back( "id" );
3416 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3417 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3419 fieldWriter.SetDtIt( -1, -1 );
3421 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3425 if ( compNames.size() == 2 ) // _vertices_
3426 while ( elemIt->more() )
3428 const SMDS_MeshElement* e = elemIt->next();
3429 const int shapeID = e->getshapeId();
3432 fieldWriter.AddValue( (double) -1 );
3433 fieldWriter.AddValue( (double) -1 );
3437 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3438 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3439 fieldWriter.AddValue( (double) shapeID );
3443 while ( elemIt->more() )
3445 const SMDS_MeshElement* e = elemIt->next();
3446 const int shapeID = e->getshapeId();
3448 fieldWriter.AddValue( (double) -1 );
3450 fieldWriter.AddValue( (double) shapeID );
3454 fieldWriter.Perform();
3455 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3456 if ( res && res->IsKO() )
3458 if ( res->myComment.empty() )
3459 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3461 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3464 } // loop on geomAssocFields
3469 //================================================================================
3471 * \brief Export a part of mesh to a DAT file
3473 //================================================================================
3475 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3477 throw (SALOME::SALOME_Exception)
3479 Unexpect aCatch(SALOME_SalomeException);
3481 _preMeshInfo->FullLoadFromFile();
3483 PrepareForWriting(file);
3485 SMESH_MeshPartDS partDS( meshPart );
3486 _impl->ExportDAT(file,&partDS);
3488 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3489 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3491 //================================================================================
3493 * \brief Export a part of mesh to an UNV file
3495 //================================================================================
3497 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3499 throw (SALOME::SALOME_Exception)
3501 Unexpect aCatch(SALOME_SalomeException);
3503 _preMeshInfo->FullLoadFromFile();
3505 PrepareForWriting(file);
3507 SMESH_MeshPartDS partDS( meshPart );
3508 _impl->ExportUNV(file, &partDS);
3510 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3511 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3513 //================================================================================
3515 * \brief Export a part of mesh to an STL file
3517 //================================================================================
3519 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3521 ::CORBA::Boolean isascii)
3522 throw (SALOME::SALOME_Exception)
3524 Unexpect aCatch(SALOME_SalomeException);
3526 _preMeshInfo->FullLoadFromFile();
3528 PrepareForWriting(file);
3530 SMESH_MeshPartDS partDS( meshPart );
3531 _impl->ExportSTL(file, isascii, &partDS);
3533 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3534 << meshPart<< ", r'" << file << "', " << isascii << ")";
3537 //================================================================================
3539 * \brief Export a part of mesh to an STL file
3541 //================================================================================
3543 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3545 CORBA::Boolean overwrite)
3546 throw (SALOME::SALOME_Exception)
3549 Unexpect aCatch(SALOME_SalomeException);
3551 _preMeshInfo->FullLoadFromFile();
3553 PrepareForWriting(file,overwrite);
3555 SMESH_MeshPartDS partDS( meshPart );
3556 _impl->ExportCGNS(file, &partDS);
3558 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3559 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3561 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3565 //================================================================================
3567 * \brief Export a part of mesh to a GMF file
3569 //================================================================================
3571 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3573 bool withRequiredGroups)
3574 throw (SALOME::SALOME_Exception)
3576 Unexpect aCatch(SALOME_SalomeException);
3578 _preMeshInfo->FullLoadFromFile();
3580 PrepareForWriting(file,/*overwrite=*/true);
3582 SMESH_MeshPartDS partDS( meshPart );
3583 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3585 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3586 << meshPart<< ", r'"
3588 << withRequiredGroups << ")";
3591 //=============================================================================
3593 * Return computation progress [0.,1]
3595 //=============================================================================
3597 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3601 return _impl->GetComputeProgress();
3603 SMESH_CATCH( SMESH::doNothing );
3607 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3609 Unexpect aCatch(SALOME_SalomeException);
3611 return _preMeshInfo->NbNodes();
3613 return _impl->NbNodes();
3616 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3618 Unexpect aCatch(SALOME_SalomeException);
3620 return _preMeshInfo->NbElements();
3622 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3625 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3627 Unexpect aCatch(SALOME_SalomeException);
3629 return _preMeshInfo->Nb0DElements();
3631 return _impl->Nb0DElements();
3634 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3636 Unexpect aCatch(SALOME_SalomeException);
3638 return _preMeshInfo->NbBalls();
3640 return _impl->NbBalls();
3643 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3645 Unexpect aCatch(SALOME_SalomeException);
3647 return _preMeshInfo->NbEdges();
3649 return _impl->NbEdges();
3652 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3653 throw(SALOME::SALOME_Exception)
3655 Unexpect aCatch(SALOME_SalomeException);
3657 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3659 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3662 //=============================================================================
3664 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3666 Unexpect aCatch(SALOME_SalomeException);
3668 return _preMeshInfo->NbFaces();
3670 return _impl->NbFaces();
3673 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3675 Unexpect aCatch(SALOME_SalomeException);
3677 return _preMeshInfo->NbTriangles();
3679 return _impl->NbTriangles();
3682 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3684 Unexpect aCatch(SALOME_SalomeException);
3686 return _preMeshInfo->NbBiQuadTriangles();
3688 return _impl->NbBiQuadTriangles();
3691 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3693 Unexpect aCatch(SALOME_SalomeException);
3695 return _preMeshInfo->NbQuadrangles();
3697 return _impl->NbQuadrangles();
3700 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3702 Unexpect aCatch(SALOME_SalomeException);
3704 return _preMeshInfo->NbBiQuadQuadrangles();
3706 return _impl->NbBiQuadQuadrangles();
3709 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3711 Unexpect aCatch(SALOME_SalomeException);
3713 return _preMeshInfo->NbPolygons();
3715 return _impl->NbPolygons();
3718 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3719 throw(SALOME::SALOME_Exception)
3721 Unexpect aCatch(SALOME_SalomeException);
3723 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3725 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3728 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3729 throw(SALOME::SALOME_Exception)
3731 Unexpect aCatch(SALOME_SalomeException);
3733 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3735 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3738 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3739 throw(SALOME::SALOME_Exception)
3741 Unexpect aCatch(SALOME_SalomeException);
3743 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3745 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3748 //=============================================================================
3750 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3752 Unexpect aCatch(SALOME_SalomeException);
3754 return _preMeshInfo->NbVolumes();
3756 return _impl->NbVolumes();
3759 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3761 Unexpect aCatch(SALOME_SalomeException);
3763 return _preMeshInfo->NbTetras();
3765 return _impl->NbTetras();
3768 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3770 Unexpect aCatch(SALOME_SalomeException);
3772 return _preMeshInfo->NbHexas();
3774 return _impl->NbHexas();
3777 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3779 Unexpect aCatch(SALOME_SalomeException);
3781 return _preMeshInfo->NbTriQuadHexas();
3783 return _impl->NbTriQuadraticHexas();
3786 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3788 Unexpect aCatch(SALOME_SalomeException);
3790 return _preMeshInfo->NbPyramids();
3792 return _impl->NbPyramids();
3795 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3797 Unexpect aCatch(SALOME_SalomeException);
3799 return _preMeshInfo->NbPrisms();
3801 return _impl->NbPrisms();
3804 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3806 Unexpect aCatch(SALOME_SalomeException);
3808 return _preMeshInfo->NbHexPrisms();
3810 return _impl->NbHexagonalPrisms();
3813 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3815 Unexpect aCatch(SALOME_SalomeException);
3817 return _preMeshInfo->NbPolyhedrons();
3819 return _impl->NbPolyhedrons();
3822 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3823 throw(SALOME::SALOME_Exception)
3825 Unexpect aCatch(SALOME_SalomeException);
3827 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3829 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3832 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3833 throw(SALOME::SALOME_Exception)
3835 Unexpect aCatch(SALOME_SalomeException);
3837 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3839 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3842 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3843 throw(SALOME::SALOME_Exception)
3845 Unexpect aCatch(SALOME_SalomeException);
3847 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3849 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3852 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3853 throw(SALOME::SALOME_Exception)
3855 Unexpect aCatch(SALOME_SalomeException);
3857 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3859 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3862 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3863 throw(SALOME::SALOME_Exception)
3865 Unexpect aCatch(SALOME_SalomeException);
3867 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3869 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3872 //=============================================================================
3874 * Returns nb of published sub-meshes
3876 //=============================================================================
3878 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3880 Unexpect aCatch(SALOME_SalomeException);
3881 return _mapSubMesh_i.size();
3884 //=============================================================================
3886 * Dumps mesh into a string
3888 //=============================================================================
3890 char* SMESH_Mesh_i::Dump()
3894 return CORBA::string_dup( os.str().c_str() );
3897 //=============================================================================
3899 * Method of SMESH_IDSource interface
3901 //=============================================================================
3903 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3905 return GetElementsId();
3908 //=============================================================================
3910 * Returns ids of all elements
3912 //=============================================================================
3914 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3915 throw (SALOME::SALOME_Exception)
3917 Unexpect aCatch(SALOME_SalomeException);
3919 _preMeshInfo->FullLoadFromFile();
3921 SMESH::long_array_var aResult = new SMESH::long_array();
3922 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3924 if ( aSMESHDS_Mesh == NULL )
3925 return aResult._retn();
3927 long nbElements = NbElements();
3928 aResult->length( nbElements );
3929 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3930 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3931 aResult[i] = anIt->next()->GetID();
3933 return aResult._retn();
3937 //=============================================================================
3939 * Returns ids of all elements of given type
3941 //=============================================================================
3943 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3944 throw (SALOME::SALOME_Exception)
3946 Unexpect aCatch(SALOME_SalomeException);
3948 _preMeshInfo->FullLoadFromFile();
3950 SMESH::long_array_var aResult = new SMESH::long_array();
3951 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3953 if ( aSMESHDS_Mesh == NULL )
3954 return aResult._retn();
3956 long nbElements = NbElements();
3958 // No sense in returning ids of elements along with ids of nodes:
3959 // when theElemType == SMESH::ALL, return node ids only if
3960 // there are no elements
3961 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3962 return GetNodesId();
3964 aResult->length( nbElements );
3968 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3969 while ( i < nbElements && anIt->more() )
3970 aResult[i++] = anIt->next()->GetID();
3972 aResult->length( i );
3974 return aResult._retn();
3977 //=============================================================================
3979 * Returns ids of all nodes
3981 //=============================================================================
3983 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3984 throw (SALOME::SALOME_Exception)
3986 Unexpect aCatch(SALOME_SalomeException);
3988 _preMeshInfo->FullLoadFromFile();
3990 SMESH::long_array_var aResult = new SMESH::long_array();
3991 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3993 if ( aSMESHDS_Mesh == NULL )
3994 return aResult._retn();
3996 long nbNodes = NbNodes();
3997 aResult->length( nbNodes );
3998 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3999 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4000 aResult[i] = anIt->next()->GetID();
4002 return aResult._retn();
4005 //=============================================================================
4009 //=============================================================================
4011 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4012 throw (SALOME::SALOME_Exception)
4014 SMESH::ElementType type;
4018 _preMeshInfo->FullLoadFromFile();
4020 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4022 SMESH_CATCH( SMESH::throwCorbaException );
4027 //=============================================================================
4031 //=============================================================================
4033 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4034 throw (SALOME::SALOME_Exception)
4037 _preMeshInfo->FullLoadFromFile();
4039 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4041 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4043 return ( SMESH::EntityType ) e->GetEntityType();
4046 //=============================================================================
4050 //=============================================================================
4052 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4053 throw (SALOME::SALOME_Exception)
4056 _preMeshInfo->FullLoadFromFile();
4058 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4060 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4062 return ( SMESH::GeometryType ) e->GetGeomType();
4065 //=============================================================================
4067 * Returns ID of elements for given submesh
4069 //=============================================================================
4070 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4071 throw (SALOME::SALOME_Exception)
4073 SMESH::long_array_var aResult = new SMESH::long_array();
4077 _preMeshInfo->FullLoadFromFile();
4079 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4080 if(!SM) return aResult._retn();
4082 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4083 if(!SDSM) return aResult._retn();
4085 aResult->length(SDSM->NbElements());
4087 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4089 while ( eIt->more() ) {
4090 aResult[i++] = eIt->next()->GetID();
4093 SMESH_CATCH( SMESH::throwCorbaException );
4095 return aResult._retn();
4098 //=============================================================================
4100 * Returns ID of nodes for given submesh
4101 * If param all==true - returns all nodes, else -
4102 * returns only nodes on shapes.
4104 //=============================================================================
4106 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4108 throw (SALOME::SALOME_Exception)
4110 SMESH::long_array_var aResult = new SMESH::long_array();
4114 _preMeshInfo->FullLoadFromFile();
4116 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4117 if(!SM) return aResult._retn();
4119 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4120 if(!SDSM) return aResult._retn();
4123 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4124 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4125 while ( nIt->more() ) {
4126 const SMDS_MeshNode* elem = nIt->next();
4127 theElems.insert( elem->GetID() );
4130 else { // all nodes of submesh elements
4131 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4132 while ( eIt->more() ) {
4133 const SMDS_MeshElement* anElem = eIt->next();
4134 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4135 while ( nIt->more() ) {
4136 const SMDS_MeshElement* elem = nIt->next();
4137 theElems.insert( elem->GetID() );
4142 aResult->length(theElems.size());
4143 set<int>::iterator itElem;
4145 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4146 aResult[i++] = *itElem;
4148 SMESH_CATCH( SMESH::throwCorbaException );
4150 return aResult._retn();
4153 //=============================================================================
4155 * Returns type of elements for given submesh
4157 //=============================================================================
4159 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4160 throw (SALOME::SALOME_Exception)
4162 SMESH::ElementType type;
4166 _preMeshInfo->FullLoadFromFile();
4168 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4169 if(!SM) return SMESH::ALL;
4171 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4172 if(!SDSM) return SMESH::ALL;
4174 if(SDSM->NbElements()==0)
4175 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4177 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4178 const SMDS_MeshElement* anElem = eIt->next();
4180 type = ( SMESH::ElementType ) anElem->GetType();
4182 SMESH_CATCH( SMESH::throwCorbaException );
4188 //=============================================================================
4190 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4192 //=============================================================================
4194 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4197 _preMeshInfo->FullLoadFromFile();
4199 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4201 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4206 //=============================================================================
4208 * Get XYZ coordinates of node as list of double
4209 * If there is not node for given ID - returns empty list
4211 //=============================================================================
4213 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4216 _preMeshInfo->FullLoadFromFile();
4218 SMESH::double_array_var aResult = new SMESH::double_array();
4219 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4220 if ( aSMESHDS_Mesh == NULL )
4221 return aResult._retn();
4224 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4226 return aResult._retn();
4230 aResult[0] = aNode->X();
4231 aResult[1] = aNode->Y();
4232 aResult[2] = aNode->Z();
4233 return aResult._retn();
4237 //=============================================================================
4239 * For given node returns list of IDs of inverse elements
4240 * If there is not node for given ID - returns empty list
4242 //=============================================================================
4244 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4247 _preMeshInfo->FullLoadFromFile();
4249 SMESH::long_array_var aResult = new SMESH::long_array();
4250 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4251 if ( aSMESHDS_Mesh == NULL )
4252 return aResult._retn();
4255 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4257 return aResult._retn();
4259 // find inverse elements
4260 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4261 aResult->length( aNode->NbInverseElements() );
4262 for( int i = 0; eIt->more(); ++i )
4264 const SMDS_MeshElement* elem = eIt->next();
4265 aResult[ i ] = elem->GetID();
4267 return aResult._retn();
4270 //=============================================================================
4272 * \brief Return position of a node on shape
4274 //=============================================================================
4276 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4279 _preMeshInfo->FullLoadFromFile();
4281 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4282 aNodePosition->shapeID = 0;
4283 aNodePosition->shapeType = GEOM::SHAPE;
4285 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4286 if ( !mesh ) return aNodePosition;
4288 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4290 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4292 aNodePosition->shapeID = aNode->getshapeId();
4293 switch ( pos->GetTypeOfPosition() ) {
4295 aNodePosition->shapeType = GEOM::EDGE;
4296 aNodePosition->params.length(1);
4297 aNodePosition->params[0] =
4298 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4301 aNodePosition->shapeType = GEOM::FACE;
4302 aNodePosition->params.length(2);
4303 aNodePosition->params[0] =
4304 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4305 aNodePosition->params[1] =
4306 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4308 case SMDS_TOP_VERTEX:
4309 aNodePosition->shapeType = GEOM::VERTEX;
4311 case SMDS_TOP_3DSPACE:
4312 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4313 aNodePosition->shapeType = GEOM::SOLID;
4314 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4315 aNodePosition->shapeType = GEOM::SHELL;
4321 return aNodePosition;
4324 //=============================================================================
4326 * \brief Return position of an element on shape
4328 //=============================================================================
4330 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4333 _preMeshInfo->FullLoadFromFile();
4335 SMESH::ElementPosition anElementPosition;
4336 anElementPosition.shapeID = 0;
4337 anElementPosition.shapeType = GEOM::SHAPE;
4339 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4340 if ( !mesh ) return anElementPosition;
4342 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4344 anElementPosition.shapeID = anElem->getshapeId();
4345 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4346 if ( !aSp.IsNull() ) {
4347 switch ( aSp.ShapeType() ) {
4349 anElementPosition.shapeType = GEOM::EDGE;
4352 anElementPosition.shapeType = GEOM::FACE;
4355 anElementPosition.shapeType = GEOM::VERTEX;
4358 anElementPosition.shapeType = GEOM::SOLID;
4361 anElementPosition.shapeType = GEOM::SHELL;
4367 return anElementPosition;
4370 //=============================================================================
4372 * If given element is node returns IDs of shape from position
4373 * If there is not node for given ID - returns -1
4375 //=============================================================================
4377 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4380 _preMeshInfo->FullLoadFromFile();
4382 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4383 if ( aSMESHDS_Mesh == NULL )
4387 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4389 return aNode->getshapeId();
4396 //=============================================================================
4398 * For given element returns ID of result shape after
4399 * ::FindShape() from SMESH_MeshEditor
4400 * If there is not element for given ID - returns -1
4402 //=============================================================================
4404 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4407 _preMeshInfo->FullLoadFromFile();
4409 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4410 if ( aSMESHDS_Mesh == NULL )
4413 // try to find element
4414 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4418 ::SMESH_MeshEditor aMeshEditor(_impl);
4419 int index = aMeshEditor.FindShape( elem );
4427 //=============================================================================
4429 * Returns number of nodes for given element
4430 * If there is not element for given ID - returns -1
4432 //=============================================================================
4434 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4437 _preMeshInfo->FullLoadFromFile();
4439 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4440 if ( aSMESHDS_Mesh == NULL ) return -1;
4441 // try to find element
4442 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4443 if(!elem) return -1;
4444 return elem->NbNodes();
4448 //=============================================================================
4450 * Returns ID of node by given index for given element
4451 * If there is not element for given ID - returns -1
4452 * If there is not node for given index - returns -2
4454 //=============================================================================
4456 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4459 _preMeshInfo->FullLoadFromFile();
4461 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4462 if ( aSMESHDS_Mesh == NULL ) return -1;
4463 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4464 if(!elem) return -1;
4465 if( index>=elem->NbNodes() || index<0 ) return -1;
4466 return elem->GetNode(index)->GetID();
4469 //=============================================================================
4471 * Returns IDs of nodes of given element
4473 //=============================================================================
4475 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4478 _preMeshInfo->FullLoadFromFile();
4480 SMESH::long_array_var aResult = new SMESH::long_array();
4481 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4483 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4485 aResult->length( elem->NbNodes() );
4486 for ( int i = 0; i < elem->NbNodes(); ++i )
4487 aResult[ i ] = elem->GetNode( i )->GetID();
4490 return aResult._retn();
4493 //=============================================================================
4495 * Returns true if given node is medium node
4496 * in given quadratic element
4498 //=============================================================================
4500 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4503 _preMeshInfo->FullLoadFromFile();
4505 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4506 if ( aSMESHDS_Mesh == NULL ) return false;
4508 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4509 if(!aNode) return false;
4510 // try to find element
4511 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4512 if(!elem) return false;
4514 return elem->IsMediumNode(aNode);
4518 //=============================================================================
4520 * Returns true if given node is medium node
4521 * in one of quadratic elements
4523 //=============================================================================
4525 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4526 SMESH::ElementType theElemType)
4529 _preMeshInfo->FullLoadFromFile();
4531 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4532 if ( aSMESHDS_Mesh == NULL ) return false;
4535 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4536 if(!aNode) return false;
4538 SMESH_MesherHelper aHelper( *(_impl) );
4540 SMDSAbs_ElementType aType;
4541 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4542 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4543 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4544 else aType = SMDSAbs_All;
4546 return aHelper.IsMedium(aNode,aType);
4550 //=============================================================================
4552 * Returns number of edges for given element
4554 //=============================================================================
4556 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4559 _preMeshInfo->FullLoadFromFile();
4561 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4562 if ( aSMESHDS_Mesh == NULL ) return -1;
4563 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4564 if(!elem) return -1;
4565 return elem->NbEdges();
4569 //=============================================================================
4571 * Returns number of faces for given element
4573 //=============================================================================
4575 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4578 _preMeshInfo->FullLoadFromFile();
4580 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4581 if ( aSMESHDS_Mesh == NULL ) return -1;
4582 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4583 if(!elem) return -1;
4584 return elem->NbFaces();
4587 //=======================================================================
4588 //function : GetElemFaceNodes
4589 //purpose : Returns nodes of given face (counted from zero) for given element.
4590 //=======================================================================
4592 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4593 CORBA::Short faceIndex)
4596 _preMeshInfo->FullLoadFromFile();
4598 SMESH::long_array_var aResult = new SMESH::long_array();
4599 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4601 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4603 SMDS_VolumeTool vtool( elem );
4604 if ( faceIndex < vtool.NbFaces() )
4606 aResult->length( vtool.NbFaceNodes( faceIndex ));
4607 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4608 for ( int i = 0; i < aResult->length(); ++i )
4609 aResult[ i ] = nn[ i ]->GetID();
4613 return aResult._retn();
4616 //=======================================================================
4617 //function : GetElemFaceNodes
4618 //purpose : Returns three components of normal of given mesh face.
4619 //=======================================================================
4621 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4622 CORBA::Boolean normalized)
4625 _preMeshInfo->FullLoadFromFile();
4627 SMESH::double_array_var aResult = new SMESH::double_array();
4629 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4632 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4634 aResult->length( 3 );
4635 aResult[ 0 ] = normal.X();
4636 aResult[ 1 ] = normal.Y();
4637 aResult[ 2 ] = normal.Z();
4640 return aResult._retn();
4643 //=======================================================================
4644 //function : FindElementByNodes
4645 //purpose : Returns an element based on all given nodes.
4646 //=======================================================================
4648 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4651 _preMeshInfo->FullLoadFromFile();
4653 CORBA::Long elemID(0);
4654 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4656 vector< const SMDS_MeshNode * > nn( nodes.length() );
4657 for ( int i = 0; i < nodes.length(); ++i )
4658 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4661 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4662 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4663 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4664 _impl->NbVolumes( ORDER_QUADRATIC )))
4665 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4667 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4672 //=============================================================================
4674 * Returns true if given element is polygon
4676 //=============================================================================
4678 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4681 _preMeshInfo->FullLoadFromFile();
4683 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4684 if ( aSMESHDS_Mesh == NULL ) return false;
4685 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4686 if(!elem) return false;
4687 return elem->IsPoly();
4691 //=============================================================================
4693 * Returns true if given element is quadratic
4695 //=============================================================================
4697 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4700 _preMeshInfo->FullLoadFromFile();
4702 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4703 if ( aSMESHDS_Mesh == NULL ) return false;
4704 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4705 if(!elem) return false;
4706 return elem->IsQuadratic();
4709 //=============================================================================
4711 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4713 //=============================================================================
4715 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4718 _preMeshInfo->FullLoadFromFile();
4720 if ( const SMDS_BallElement* ball =
4721 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4722 return ball->GetDiameter();
4727 //=============================================================================
4729 * Returns bary center for given element
4731 //=============================================================================
4733 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4736 _preMeshInfo->FullLoadFromFile();
4738 SMESH::double_array_var aResult = new SMESH::double_array();
4739 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4740 if ( aSMESHDS_Mesh == NULL )
4741 return aResult._retn();
4743 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4745 return aResult._retn();
4747 if(elem->GetType()==SMDSAbs_Volume) {
4748 SMDS_VolumeTool aTool;
4749 if(aTool.Set(elem)) {
4751 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4756 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4758 double x=0., y=0., z=0.;
4759 for(; anIt->more(); ) {
4761 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4775 return aResult._retn();
4778 //================================================================================
4780 * \brief Create a group of elements preventing computation of a sub-shape
4782 //================================================================================
4784 SMESH::ListOfGroups*
4785 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4786 const char* theGroupName )
4787 throw ( SALOME::SALOME_Exception )
4789 Unexpect aCatch(SALOME_SalomeException);
4791 if ( !theGroupName || strlen( theGroupName) == 0 )
4792 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4794 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4796 // submesh by subshape id
4797 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4798 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4801 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4802 if ( error && !error->myBadElements.empty())
4804 // sort bad elements by type
4805 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4806 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4807 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4808 for ( ; elemIt != elemEnd; ++elemIt )
4810 const SMDS_MeshElement* elem = *elemIt;
4811 if ( !elem ) continue;
4813 if ( elem->GetID() < 1 )
4815 // elem is a temporary element, make a real element
4816 vector< const SMDS_MeshNode* > nodes;
4817 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4818 while ( nIt->more() && elem )
4820 nodes.push_back( nIt->next() );
4821 if ( nodes.back()->GetID() < 1 )
4822 elem = 0; // a temporary element on temporary nodes
4826 ::SMESH_MeshEditor editor( _impl );
4827 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4831 elemsByType[ elem->GetType() ].push_back( elem );
4834 // how many groups to create?
4836 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4837 nbTypes += int( !elemsByType[ i ].empty() );
4838 groups->length( nbTypes );
4841 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4843 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4844 if ( elems.empty() ) continue;
4846 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4847 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4849 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4850 SMESH::SMESH_Mesh_var mesh = _this();
4851 SALOMEDS::SObject_wrap aSO =
4852 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4853 GEOM::GEOM_Object::_nil(), theGroupName);
4855 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4856 if ( !grp_i ) continue;
4858 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4859 for ( size_t iE = 0; iE < elems.size(); ++iE )
4860 grpDS->SMDSGroup().Add( elems[ iE ]);
4865 return groups._retn();
4868 //=============================================================================
4870 * Create and publish group servants if any groups were imported or created anyhow
4872 //=============================================================================
4874 void SMESH_Mesh_i::CreateGroupServants()
4876 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4877 SMESH::SMESH_Mesh_var aMesh = _this();
4880 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4881 while ( groupIt->more() )
4883 ::SMESH_Group* group = groupIt->next();
4884 int anId = group->GetGroupDS()->GetID();
4886 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4887 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4889 addedIDs.insert( anId );
4891 SMESH_GroupBase_i* aGroupImpl;
4893 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4894 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4896 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4897 shape = groupOnGeom->GetShape();
4900 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4903 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4904 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4905 aGroupImpl->Register();
4907 // register CORBA object for persistence
4908 int nextId = _gen_i->RegisterObject( groupVar );
4909 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4910 else { nextId = 0; } // avoid "unused variable" warning in release mode
4912 // publishing the groups in the study
4913 if ( !aStudy->_is_nil() ) {
4914 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4915 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4918 if ( !addedIDs.empty() )
4921 set<int>::iterator id = addedIDs.begin();
4922 for ( ; id != addedIDs.end(); ++id )
4924 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4925 int i = std::distance( _mapGroups.begin(), it );
4926 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4931 //=============================================================================
4933 * \brief Return groups cantained in _mapGroups by their IDs
4935 //=============================================================================
4937 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4939 int nbGroups = groupIDs.size();
4940 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4941 aList->length( nbGroups );
4943 list<int>::const_iterator ids = groupIDs.begin();
4944 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4946 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4947 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4948 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4950 aList->length( nbGroups );
4951 return aList._retn();
4954 //=============================================================================
4956 * \brief Return information about imported file
4958 //=============================================================================
4960 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4962 SMESH::MedFileInfo_var res( _medFileInfo );
4963 if ( !res.operator->() ) {
4964 res = new SMESH::MedFileInfo;
4966 res->fileSize = res->major = res->minor = res->release = -1;
4971 //=============================================================================
4973 * \brief Pass names of mesh groups from study to mesh DS
4975 //=============================================================================
4977 void SMESH_Mesh_i::checkGroupNames()
4979 int nbGrp = NbGroups();
4983 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4984 if ( aStudy->_is_nil() )
4985 return; // nothing to do
4987 SMESH::ListOfGroups* grpList = 0;
4988 // avoid dump of "GetGroups"
4990 // store python dump into a local variable inside local scope
4991 SMESH::TPythonDump pDump; // do not delete this line of code
4992 grpList = GetGroups();
4995 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4996 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4999 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5000 if ( aGrpSO->_is_nil() )
5002 // correct name of the mesh group if necessary
5003 const char* guiName = aGrpSO->GetName();
5004 if ( strcmp(guiName, aGrp->GetName()) )
5005 aGrp->SetName( guiName );
5009 //=============================================================================
5011 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5013 //=============================================================================
5014 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5016 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5020 //=============================================================================
5022 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5024 //=============================================================================
5026 char* SMESH_Mesh_i::GetParameters()
5028 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5031 //=============================================================================
5033 * \brief Returns list of notebook variables used for last Mesh operation
5035 //=============================================================================
5036 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5038 SMESH::string_array_var aResult = new SMESH::string_array();
5039 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5041 CORBA::String_var aParameters = GetParameters();
5042 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5043 if ( !aStudy->_is_nil()) {
5044 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5045 if(aSections->length() > 0) {
5046 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5047 aResult->length(aVars.length());
5048 for(int i = 0;i < aVars.length();i++)
5049 aResult[i] = CORBA::string_dup( aVars[i]);
5053 return aResult._retn();
5056 //=======================================================================
5057 //function : GetTypes
5058 //purpose : Returns types of elements it contains
5059 //=======================================================================
5061 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5064 return _preMeshInfo->GetTypes();
5066 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5070 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5071 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5072 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5073 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5074 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5075 types->length( nbTypes );
5077 return types._retn();
5080 //=======================================================================
5081 //function : GetMesh
5082 //purpose : Returns self
5083 //=======================================================================
5085 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5087 return SMESH::SMESH_Mesh::_duplicate( _this() );
5090 //=======================================================================
5091 //function : IsMeshInfoCorrect
5092 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5093 // * happen if mesh data is not yet fully loaded from the file of study.
5094 //=======================================================================
5096 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5098 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5101 //=============================================================================
5103 * \brief Returns number of mesh elements per each \a EntityType
5105 //=============================================================================
5107 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5110 return _preMeshInfo->GetMeshInfo();
5112 SMESH::long_array_var aRes = new SMESH::long_array();
5113 aRes->length(SMESH::Entity_Last);
5114 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5116 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5118 return aRes._retn();
5119 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5120 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5121 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5122 return aRes._retn();
5125 //=============================================================================
5127 * \brief Returns number of mesh elements per each \a ElementType
5129 //=============================================================================
5131 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5133 SMESH::long_array_var aRes = new SMESH::long_array();
5134 aRes->length(SMESH::NB_ELEMENT_TYPES);
5135 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5138 const SMDS_MeshInfo* meshInfo = 0;
5140 meshInfo = _preMeshInfo;
5141 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5142 meshInfo = & meshDS->GetMeshInfo();
5145 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5146 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5148 return aRes._retn();
5151 //=============================================================================
5153 * Collect statistic of mesh elements given by iterator
5155 //=============================================================================
5157 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5158 SMESH::long_array& theInfo)
5160 if (!theItr) return;
5161 while (theItr->more())
5162 theInfo[ theItr->next()->GetEntityType() ]++;
5164 //=============================================================================
5166 * Returns mesh unstructed grid information.
5168 //=============================================================================
5170 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5172 SALOMEDS::TMPFile_var SeqFile;
5173 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5174 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5176 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5177 aWriter->WriteToOutputStringOn();
5178 aWriter->SetInputData(aGrid);
5179 aWriter->SetFileTypeToBinary();
5181 char* str = aWriter->GetOutputString();
5182 int size = aWriter->GetOutputStringLength();
5184 //Allocate octect buffer of required size
5185 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5186 //Copy ostrstream content to the octect buffer
5187 memcpy(OctetBuf, str, size);
5188 //Create and return TMPFile
5189 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5193 return SeqFile._retn();
5196 //=============================================================================
5197 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5198 * SMESH::ElementType type) */
5200 using namespace SMESH::Controls;
5201 //-----------------------------------------------------------------------------
5202 struct PredicateIterator : public SMDS_ElemIterator
5204 SMDS_ElemIteratorPtr _elemIter;
5205 PredicatePtr _predicate;
5206 const SMDS_MeshElement* _elem;
5208 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5209 PredicatePtr predicate):
5210 _elemIter(iterator), _predicate(predicate)
5218 virtual const SMDS_MeshElement* next()
5220 const SMDS_MeshElement* res = _elem;
5222 while ( _elemIter->more() && !_elem )
5224 _elem = _elemIter->next();
5225 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5232 //-----------------------------------------------------------------------------
5233 struct IDSourceIterator : public SMDS_ElemIterator
5235 const CORBA::Long* _idPtr;
5236 const CORBA::Long* _idEndPtr;
5237 SMESH::long_array_var _idArray;
5238 const SMDS_Mesh* _mesh;
5239 const SMDSAbs_ElementType _type;
5240 const SMDS_MeshElement* _elem;
5242 IDSourceIterator( const SMDS_Mesh* mesh,
5243 const CORBA::Long* ids,
5245 SMDSAbs_ElementType type):
5246 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5248 if ( _idPtr && nbIds && _mesh )
5251 IDSourceIterator( const SMDS_Mesh* mesh,
5252 SMESH::long_array* idArray,
5253 SMDSAbs_ElementType type):
5254 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5256 if ( idArray && _mesh )
5258 _idPtr = &_idArray[0];
5259 _idEndPtr = _idPtr + _idArray->length();
5267 virtual const SMDS_MeshElement* next()
5269 const SMDS_MeshElement* res = _elem;
5271 while ( _idPtr < _idEndPtr && !_elem )
5273 if ( _type == SMDSAbs_Node )
5275 _elem = _mesh->FindNode( *_idPtr++ );
5277 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5278 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5286 //-----------------------------------------------------------------------------
5288 struct NodeOfElemIterator : public SMDS_ElemIterator
5290 TColStd_MapOfInteger _checkedNodeIDs;
5291 SMDS_ElemIteratorPtr _elemIter;
5292 SMDS_ElemIteratorPtr _nodeIter;
5293 const SMDS_MeshElement* _node;
5295 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5297 if ( _elemIter && _elemIter->more() )
5299 _nodeIter = _elemIter->next()->nodesIterator();
5307 virtual const SMDS_MeshElement* next()
5309 const SMDS_MeshElement* res = _node;
5311 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5313 if ( _nodeIter->more() )
5315 _node = _nodeIter->next();
5316 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5321 _nodeIter = _elemIter->next()->nodesIterator();
5329 //=============================================================================
5331 * Return iterator on elements of given type in given object
5333 //=============================================================================
5335 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5336 SMESH::ElementType theType)
5338 SMDS_ElemIteratorPtr elemIt;
5339 bool typeOK = false;
5340 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5342 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5343 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5344 if ( !mesh_i ) return elemIt;
5345 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5347 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5349 elemIt = meshDS->elementsIterator( elemType );
5352 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5354 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5357 elemIt = sm->GetElements();
5358 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5360 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5361 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5365 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5367 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5368 if ( groupDS && ( elemType == groupDS->GetType() ||
5369 elemType == SMDSAbs_Node ||
5370 elemType == SMDSAbs_All ))
5372 elemIt = groupDS->GetElements();
5373 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5376 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5378 if ( filter_i->GetElementType() == theType ||
5379 elemType == SMDSAbs_Node ||
5380 elemType == SMDSAbs_All)
5382 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5383 if ( pred_i && pred_i->GetPredicate() )
5385 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5386 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5387 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5388 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5394 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5395 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5396 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5398 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5401 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5402 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5406 SMESH::long_array_var ids = theObject->GetIDs();
5407 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5409 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5412 if ( elemIt && elemIt->more() && !typeOK )
5414 if ( elemType == SMDSAbs_Node )
5416 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5420 elemIt = SMDS_ElemIteratorPtr();
5426 //=============================================================================
5427 namespace // Finding concurrent hypotheses
5428 //=============================================================================
5432 * \brief mapping of mesh dimension into shape type
5434 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5436 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5438 case 0: aType = TopAbs_VERTEX; break;
5439 case 1: aType = TopAbs_EDGE; break;
5440 case 2: aType = TopAbs_FACE; break;
5442 default:aType = TopAbs_SOLID; break;
5447 //-----------------------------------------------------------------------------
5449 * \brief Internal structure used to find concurent submeshes
5451 * It represents a pair < submesh, concurent dimension >, where
5452 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5453 * with another submesh. In other words, it is dimension of a hypothesis assigned
5460 int _dim; //!< a dimension the algo can build (concurrent dimension)
5461 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5462 TopTools_MapOfShape _shapeMap;
5463 SMESH_subMesh* _subMesh;
5464 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5466 //-----------------------------------------------------------------------------
5467 // Return the algorithm
5468 const SMESH_Algo* GetAlgo() const
5469 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5471 //-----------------------------------------------------------------------------
5473 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5475 const TopoDS_Shape& theShape)
5477 _subMesh = (SMESH_subMesh*)theSubMesh;
5478 SetShape( theDim, theShape );
5481 //-----------------------------------------------------------------------------
5483 void SetShape(const int theDim,
5484 const TopoDS_Shape& theShape)
5487 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5488 if (_dim >= _ownDim)
5489 _shapeMap.Add( theShape );
5491 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5492 for( ; anExp.More(); anExp.Next() )
5493 _shapeMap.Add( anExp.Current() );
5497 //-----------------------------------------------------------------------------
5498 //! Check sharing of sub-shapes
5499 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5500 const TopTools_MapOfShape& theToFind,
5501 const TopAbs_ShapeEnum theType)
5503 bool isShared = false;
5504 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5505 for (; !isShared && anItr.More(); anItr.Next() )
5507 const TopoDS_Shape aSubSh = anItr.Key();
5508 // check for case when concurrent dimensions are same
5509 isShared = theToFind.Contains( aSubSh );
5510 // check for sub-shape with concurrent dimension
5511 TopExp_Explorer anExp( aSubSh, theType );
5512 for ( ; !isShared && anExp.More(); anExp.Next() )
5513 isShared = theToFind.Contains( anExp.Current() );
5518 //-----------------------------------------------------------------------------
5519 //! check algorithms
5520 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5521 const SMESHDS_Hypothesis* theA2)
5523 if ( !theA1 || !theA2 ||
5524 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5525 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5526 return false; // one of the hypothesis is not algorithm
5527 // check algorithm names (should be equal)
5528 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5532 //-----------------------------------------------------------------------------
5533 //! Check if sub-shape hypotheses are concurrent
5534 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5536 if ( _subMesh == theOther->_subMesh )
5537 return false; // same sub-shape - should not be
5539 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5540 // any of the two submeshes is not on COMPOUND shape )
5541 // -> no concurrency
5542 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5543 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5544 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5545 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5546 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5549 // bool checkSubShape = ( _dim >= theOther->_dim )
5550 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5551 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5552 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5553 if ( !checkSubShape )
5556 // check algorithms to be same
5557 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5558 return true; // different algorithms -> concurrency !
5560 // check hypothesises for concurrence (skip first as algorithm)
5562 // pointers should be same, because it is referened from mesh hypothesis partition
5563 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5564 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5565 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5566 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5568 // the submeshes are concurrent if their algorithms has different parameters
5569 return nbSame != theOther->_hypotheses.size() - 1;
5572 // Return true if algorithm of this SMESH_DimHyp is used if no
5573 // sub-mesh order is imposed by the user
5574 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5576 // NeedDiscreteBoundary() algo has a higher priority
5577 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5578 theOther->GetAlgo()->NeedDiscreteBoundary() )
5579 return !this->GetAlgo()->NeedDiscreteBoundary();
5581 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5584 }; // end of SMESH_DimHyp
5585 //-----------------------------------------------------------------------------
5587 typedef list<const SMESH_DimHyp*> TDimHypList;
5589 //-----------------------------------------------------------------------------
5591 void addDimHypInstance(const int theDim,
5592 const TopoDS_Shape& theShape,
5593 const SMESH_Algo* theAlgo,
5594 const SMESH_subMesh* theSubMesh,
5595 const list <const SMESHDS_Hypothesis*>& theHypList,
5596 TDimHypList* theDimHypListArr )
5598 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5599 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5600 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5601 dimHyp->_hypotheses.push_front(theAlgo);
5602 listOfdimHyp.push_back( dimHyp );
5605 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5606 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5607 theHypList.begin(), theHypList.end() );
5610 //-----------------------------------------------------------------------------
5611 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5612 TDimHypList& theListOfConcurr)
5614 if ( theListOfConcurr.empty() )
5616 theListOfConcurr.push_back( theDimHyp );
5620 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5621 while ( hypIt != theListOfConcurr.end() &&
5622 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5624 theListOfConcurr.insert( hypIt, theDimHyp );
5628 //-----------------------------------------------------------------------------
5629 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5630 const TDimHypList& theListOfDimHyp,
5631 TDimHypList& theListOfConcurrHyp,
5632 set<int>& theSetOfConcurrId )
5634 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5635 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5637 const SMESH_DimHyp* curDimHyp = *rIt;
5638 if ( curDimHyp == theDimHyp )
5639 break; // meet own dimHyp pointer in same dimension
5641 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5642 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5644 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5649 //-----------------------------------------------------------------------------
5650 void unionLists(TListOfInt& theListOfId,
5651 TListOfListOfInt& theListOfListOfId,
5654 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5655 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5657 continue; //skip already treated lists
5658 // check if other list has any same submesh object
5659 TListOfInt& otherListOfId = *it;
5660 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5661 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5664 // union two lists (from source into target)
5665 TListOfInt::iterator it2 = otherListOfId.begin();
5666 for ( ; it2 != otherListOfId.end(); it2++ ) {
5667 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5668 theListOfId.push_back(*it2);
5670 // clear source list
5671 otherListOfId.clear();
5674 //-----------------------------------------------------------------------------
5676 //! free memory allocated for dimension-hypothesis objects
5677 void removeDimHyps( TDimHypList* theArrOfList )
5679 for (int i = 0; i < 4; i++ ) {
5680 TDimHypList& listOfdimHyp = theArrOfList[i];
5681 TDimHypList::const_iterator it = listOfdimHyp.begin();
5682 for ( ; it != listOfdimHyp.end(); it++ )
5687 //-----------------------------------------------------------------------------
5689 * \brief find common submeshes with given submesh
5690 * \param theSubMeshList list of already collected submesh to check
5691 * \param theSubMesh given submesh to intersect with other
5692 * \param theCommonSubMeshes collected common submeshes
5694 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5695 const SMESH_subMesh* theSubMesh,
5696 set<const SMESH_subMesh*>& theCommon )
5700 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5701 for ( ; it != theSubMeshList.end(); it++ )
5702 theSubMesh->FindIntersection( *it, theCommon );
5703 theSubMeshList.push_back( theSubMesh );
5704 //theCommon.insert( theSubMesh );
5707 //-----------------------------------------------------------------------------
5708 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5710 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5711 for ( ; listsIt != smLists.end(); ++listsIt )
5713 const TListOfInt& smIDs = *listsIt;
5714 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5722 //=============================================================================
5724 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5726 //=============================================================================
5728 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5730 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5731 if ( isSubMeshInList( submeshID, anOrder ))
5734 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5735 return isSubMeshInList( submeshID, allConurrent );
5738 //=============================================================================
5740 * \brief Return submesh objects list in meshing order
5742 //=============================================================================
5744 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5746 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5748 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5750 return aResult._retn();
5752 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5753 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5754 anOrder.splice( anOrder.end(), allConurrent );
5757 TListOfListOfInt::iterator listIt = anOrder.begin();
5758 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5759 unionLists( *listIt, anOrder, listIndx + 1 );
5761 // convert submesh ids into interface instances
5762 // and dump command into python
5763 convertMeshOrder( anOrder, aResult, false );
5765 return aResult._retn();
5768 //=============================================================================
5770 * \brief Finds concurrent sub-meshes
5772 //=============================================================================
5774 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5776 TListOfListOfInt anOrder;
5777 ::SMESH_Mesh& mesh = GetImpl();
5779 // collect submeshes and detect concurrent algorithms and hypothesises
5780 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5782 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5783 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5784 ::SMESH_subMesh* sm = (*i_sm).second;
5786 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5788 // list of assigned hypothesises
5789 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5790 // Find out dimensions where the submesh can be concurrent.
5791 // We define the dimensions by algo of each of hypotheses in hypList
5792 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5793 for( ; hypIt != hypList.end(); hypIt++ ) {
5794 SMESH_Algo* anAlgo = 0;
5795 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5796 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5797 // hyp it-self is algo
5798 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5800 // try to find algorithm with help of sub-shapes
5801 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5802 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5803 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5806 continue; // no algorithm assigned to a current submesh
5808 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5809 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5811 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5812 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5813 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5815 } // end iterations on submesh
5817 // iterate on created dimension-hypotheses and check for concurrents
5818 for ( int i = 0; i < 4; i++ ) {
5819 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5820 // check for concurrents in own and other dimensions (step-by-step)
5821 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5822 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5823 const SMESH_DimHyp* dimHyp = *dhIt;
5824 TDimHypList listOfConcurr;
5825 set<int> setOfConcurrIds;
5826 // looking for concurrents and collect into own list
5827 for ( int j = i; j < 4; j++ )
5828 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5829 // check if any concurrents found
5830 if ( listOfConcurr.size() > 0 ) {
5831 // add own submesh to list of concurrent
5832 addInOrderOfPriority( dimHyp, listOfConcurr );
5833 list<int> listOfConcurrIds;
5834 TDimHypList::iterator hypIt = listOfConcurr.begin();
5835 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5836 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5837 anOrder.push_back( listOfConcurrIds );
5842 removeDimHyps(dimHypListArr);
5844 // now, minimise the number of concurrent groups
5845 // Here we assume that lists of submeshes can have same submesh
5846 // in case of multi-dimension algorithms, as result
5847 // list with common submesh has to be united into one list
5849 TListOfListOfInt::iterator listIt = anOrder.begin();
5850 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5851 unionLists( *listIt, anOrder, listIndx + 1 );
5857 //=============================================================================
5859 * \brief Set submesh object order
5860 * \param theSubMeshArray submesh array order
5862 //=============================================================================
5864 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5867 _preMeshInfo->ForgetOrLoad();
5870 ::SMESH_Mesh& mesh = GetImpl();
5872 TPythonDump aPythonDump; // prevent dump of called methods
5873 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5875 TListOfListOfInt subMeshOrder;
5876 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5878 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5879 TListOfInt subMeshIds;
5881 aPythonDump << ", ";
5882 aPythonDump << "[ ";
5883 // Collect subMeshes which should be clear
5884 // do it list-by-list, because modification of submesh order
5885 // take effect between concurrent submeshes only
5886 set<const SMESH_subMesh*> subMeshToClear;
5887 list<const SMESH_subMesh*> subMeshList;
5888 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5890 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5892 aPythonDump << ", ";
5893 aPythonDump << subMesh;
5894 subMeshIds.push_back( subMesh->GetId() );
5895 // detect common parts of submeshes
5896 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5897 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5899 aPythonDump << " ]";
5900 subMeshOrder.push_back( subMeshIds );
5902 // clear collected submeshes
5903 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5904 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5905 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5906 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5908 aPythonDump << " ])";
5910 mesh.SetMeshOrder( subMeshOrder );
5916 //=============================================================================
5918 * \brief Convert submesh ids into submesh interfaces
5920 //=============================================================================
5922 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5923 SMESH::submesh_array_array& theResOrder,
5924 const bool theIsDump)
5926 int nbSet = theIdsOrder.size();
5927 TPythonDump aPythonDump; // prevent dump of called methods
5929 aPythonDump << "[ ";
5930 theResOrder.length(nbSet);
5931 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5933 for( ; it != theIdsOrder.end(); it++ ) {
5934 // translate submesh identificators into submesh objects
5935 // takeing into account real number of concurrent lists
5936 const TListOfInt& aSubOrder = (*it);
5937 if (!aSubOrder.size())
5940 aPythonDump << "[ ";
5941 // convert shape indeces into interfaces
5942 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5943 aResSubSet->length(aSubOrder.size());
5944 TListOfInt::const_iterator subIt = aSubOrder.begin();
5946 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5947 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5949 SMESH::SMESH_subMesh_var subMesh =
5950 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5953 aPythonDump << ", ";
5954 aPythonDump << subMesh;
5956 aResSubSet[ j++ ] = subMesh;
5959 aPythonDump << " ]";
5961 theResOrder[ listIndx++ ] = aResSubSet;
5963 // correct number of lists
5964 theResOrder.length( listIndx );
5967 // finilise python dump
5968 aPythonDump << " ]";
5969 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5973 //================================================================================
5975 // Implementation of SMESH_MeshPartDS
5977 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5978 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5980 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5981 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5983 _meshDS = mesh_i->GetImpl().GetMeshDS();
5985 SetPersistentId( _meshDS->GetPersistentId() );
5987 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5989 // <meshPart> is the whole mesh
5990 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5992 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5993 myGroupSet = _meshDS->GetGroups();
5998 SMESH::long_array_var anIDs = meshPart->GetIDs();
5999 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6000 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6002 for (int i=0; i < anIDs->length(); i++)
6003 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6004 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6009 for (int i=0; i < anIDs->length(); i++)
6010 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6011 if ( _elements[ e->GetType() ].insert( e ).second )
6014 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6015 while ( nIt->more() )
6017 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6018 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6025 _meshDS = 0; // to enforce iteration on _elements and _nodes
6028 // -------------------------------------------------------------------------------------
6029 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6030 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6033 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6034 for ( ; partIt != meshPart.end(); ++partIt )
6035 if ( const SMDS_MeshElement * e = *partIt )
6036 if ( _elements[ e->GetType() ].insert( e ).second )
6039 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6040 while ( nIt->more() )
6042 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6043 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6049 // -------------------------------------------------------------------------------------
6050 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6052 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6054 typedef SMDS_SetIterator
6055 <const SMDS_MeshElement*,
6056 TIDSortedElemSet::const_iterator,
6057 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6058 SMDS_MeshElement::GeomFilter
6061 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6063 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6064 _elements[type].end(),
6065 SMDS_MeshElement::GeomFilter( geomType )));
6067 // -------------------------------------------------------------------------------------
6068 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6070 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6072 typedef SMDS_SetIterator
6073 <const SMDS_MeshElement*,
6074 TIDSortedElemSet::const_iterator,
6075 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6076 SMDS_MeshElement::EntityFilter
6079 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6081 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6082 _elements[type].end(),
6083 SMDS_MeshElement::EntityFilter( entity )));
6085 // -------------------------------------------------------------------------------------
6086 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6088 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6089 if ( type == SMDSAbs_All && !_meshDS )
6091 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6093 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6094 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6096 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6098 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6099 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6101 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6102 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6104 // -------------------------------------------------------------------------------------
6105 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6106 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6108 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6109 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6110 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6112 // -------------------------------------------------------------------------------------
6113 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6114 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6115 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6116 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6117 #undef _GET_ITER_DEFINE
6119 // END Implementation of SMESH_MeshPartDS
6121 //================================================================================