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 //=============================================================================
1573 \brief Create groups of entities from existing groups of superior dimensions
1575 1) extract all nodes from each group,
1576 2) combine all elements of specified dimension laying on these nodes.
1577 \param theGroups list of source groups
1578 \param theElemType dimension of elements
1579 \param theName name of new group
1580 \return pointer on new group
1584 //=============================================================================
1586 SMESH::SMESH_Group_ptr
1587 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfGroups& theGroups,
1588 SMESH::ElementType theElemType,
1589 const char* theName )
1590 throw (SALOME::SALOME_Exception)
1592 SMESH::SMESH_Group_var aResGrp;
1596 _preMeshInfo->FullLoadFromFile();
1598 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1600 if ( !theName || !aMeshDS )
1601 return SMESH::SMESH_Group::_nil();
1603 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1609 aResGrp = CreateGroup( theElemType, theName );
1610 if ( aResGrp->_is_nil() )
1611 return SMESH::SMESH_Group::_nil();
1613 SMESHDS_GroupBase* groupBaseDS =
1614 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1615 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1617 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1619 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1620 if ( CORBA::is_nil( aGrp ) )
1623 groupBaseDS = SMESH::DownCast<SMESH_GroupBase_i*>( aGrp )->GetGroupDS();
1624 SMDS_ElemIteratorPtr elIt = groupBaseDS->GetElements();
1626 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1628 while ( elIt->more() ) {
1629 const SMDS_MeshElement* el = elIt->next();
1630 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1631 while ( nIt->more() )
1632 resGroupCore.Add( nIt->next() );
1635 else // get elements of theElemType based on nodes of every element of group
1637 while ( elIt->more() )
1639 const SMDS_MeshElement* el = elIt->next(); // an element of group
1640 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1641 TIDSortedElemSet checkedElems;
1642 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1643 while ( nIt->more() )
1645 const SMDS_MeshNode* n = static_cast<const SMDS_MeshNode*>( nIt->next() );
1646 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1647 // check nodes of elements of theElemType around el
1648 while ( elOfTypeIt->more() )
1650 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1651 if ( !checkedElems.insert( elOfType ).second ) continue;
1653 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1654 bool allNodesOK = true;
1655 while ( nIt2->more() && allNodesOK )
1656 allNodesOK = elNodes.count( nIt2->next() );
1658 resGroupCore.Add( elOfType );
1665 // Update Python script
1666 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1667 << ".CreateDimGroup( "
1668 << theGroups << ", " << theElemType << ", '" << theName << "' )";
1670 SMESH_CATCH( SMESH::throwCorbaException );
1672 return aResGrp._retn();
1675 //================================================================================
1677 * \brief Remember GEOM group data
1679 //================================================================================
1681 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1682 CORBA::Object_ptr theSmeshObj)
1684 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1687 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1688 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1689 if ( groupSO->_is_nil() )
1692 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1693 GEOM::GEOM_IGroupOperations_wrap groupOp =
1694 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1695 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1698 _geomGroupData.push_back( TGeomGroupData() );
1699 TGeomGroupData & groupData = _geomGroupData.back();
1701 CORBA::String_var entry = groupSO->GetID();
1702 groupData._groupEntry = entry.in();
1704 for ( int i = 0; i < ids->length(); ++i )
1705 groupData._indices.insert( ids[i] );
1707 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1708 // shape index in SMESHDS
1709 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1710 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1713 //================================================================================
1715 * Remove GEOM group data relating to removed smesh object
1717 //================================================================================
1719 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1721 list<TGeomGroupData>::iterator
1722 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1723 for ( ; data != dataEnd; ++data ) {
1724 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1725 _geomGroupData.erase( data );
1731 //================================================================================
1733 * \brief Return new group contents if it has been changed and update group data
1735 //================================================================================
1737 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1739 TopoDS_Shape newShape;
1742 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1743 if ( study->_is_nil() ) return newShape; // means "not changed"
1744 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1745 if ( !groupSO->_is_nil() )
1747 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1748 if ( CORBA::is_nil( groupObj )) return newShape;
1749 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1751 // get indices of group items
1752 set<int> curIndices;
1753 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1754 GEOM::GEOM_IGroupOperations_wrap groupOp =
1755 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1756 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1757 for ( int i = 0; i < ids->length(); ++i )
1758 curIndices.insert( ids[i] );
1760 if ( groupData._indices == curIndices )
1761 return newShape; // group not changed
1764 groupData._indices = curIndices;
1766 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1767 if ( !geomClient ) return newShape;
1768 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1769 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1770 newShape = _gen_i->GeomObjectToShape( geomGroup );
1773 if ( newShape.IsNull() ) {
1774 // geom group becomes empty - return empty compound
1775 TopoDS_Compound compound;
1776 BRep_Builder().MakeCompound(compound);
1777 newShape = compound;
1784 //-----------------------------------------------------------------------------
1786 * \brief Storage of shape and index used in CheckGeomGroupModif()
1788 struct TIndexedShape
1791 TopoDS_Shape _shape;
1792 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1794 //-----------------------------------------------------------------------------
1796 * \brief Data to re-create a group on geometry
1798 struct TGroupOnGeomData
1802 SMDSAbs_ElementType _type;
1804 Quantity_Color _color;
1808 //=============================================================================
1810 * \brief Update data if geometry changes
1814 //=============================================================================
1816 void SMESH_Mesh_i::CheckGeomModif()
1818 if ( !_impl->HasShapeToMesh() ) return;
1820 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1821 if ( study->_is_nil() ) return;
1823 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1824 if ( mainGO->_is_nil() ) return;
1826 if ( mainGO->GetType() == GEOM_GROUP ||
1827 mainGO->GetTick() == _mainShapeTick )
1829 CheckGeomGroupModif();
1833 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1834 if ( !geomClient ) return;
1835 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1836 if ( geomGen->_is_nil() ) return;
1838 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1839 geomClient->RemoveShapeFromBuffer( ior.in() );
1841 // Update data taking into account that
1842 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1845 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1846 if ( newShape.IsNull() )
1849 _mainShapeTick = mainGO->GetTick();
1851 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1853 // store data of groups on geometry
1854 vector< TGroupOnGeomData > groupsData;
1855 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1856 groupsData.reserve( groups.size() );
1857 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1858 for ( ; g != groups.end(); ++g )
1859 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1861 TGroupOnGeomData data;
1862 data._oldID = group->GetID();
1863 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1864 data._type = group->GetType();
1865 data._name = group->GetStoreName();
1866 data._color = group->GetColor();
1867 groupsData.push_back( data );
1869 // store assigned hypotheses
1870 vector< pair< int, THypList > > ids2Hyps;
1871 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
1872 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
1874 const TopoDS_Shape& s = s2hyps.Key();
1875 const THypList& hyps = s2hyps.ChangeValue();
1876 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
1879 // change shape to mesh
1880 int oldNbSubShapes = meshDS->MaxShapeIndex();
1881 _impl->ShapeToMesh( TopoDS_Shape() );
1882 _impl->ShapeToMesh( newShape );
1884 // re-add shapes of geom groups
1885 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
1886 for ( ; data != _geomGroupData.end(); ++data )
1888 TopoDS_Shape newShape = newGroupShape( *data );
1889 if ( !newShape.IsNull() )
1891 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
1893 TopoDS_Compound compound;
1894 BRep_Builder().MakeCompound( compound );
1895 BRep_Builder().Add( compound, newShape );
1896 newShape = compound;
1898 _impl->GetSubMesh( newShape );
1901 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
1902 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
1903 SALOME::INTERNAL_ERROR );
1905 // re-assign hypotheses
1906 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
1908 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
1909 const THypList& hyps = ids2Hyps[i].second;
1910 THypList::const_iterator h = hyps.begin();
1911 for ( ; h != hyps.end(); ++h )
1912 _impl->AddHypothesis( s, (*h)->GetID() );
1916 for ( size_t i = 0; i < groupsData.size(); ++i )
1918 const TGroupOnGeomData& data = groupsData[i];
1920 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
1921 if ( i2g == _mapGroups.end() ) continue;
1923 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
1924 if ( !gr_i ) continue;
1927 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
1928 meshDS->IndexToShape( data._shapeID ));
1931 _mapGroups.erase( i2g );
1935 g->GetGroupDS()->SetColor( data._color );
1936 gr_i->changeLocalId( id );
1937 _mapGroups[ id ] = i2g->second;
1938 if ( data._oldID != id )
1939 _mapGroups.erase( i2g );
1943 // update _mapSubMesh
1944 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
1945 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
1946 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
1950 //=============================================================================
1952 * \brief Update objects depending on changed geom groups
1954 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
1955 * issue 0020210: Update of a smesh group after modification of the associated geom group
1957 //=============================================================================
1959 void SMESH_Mesh_i::CheckGeomGroupModif()
1961 if ( !_impl->HasShapeToMesh() ) return;
1963 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1964 if ( study->_is_nil() ) return;
1966 CORBA::Long nbEntities = NbNodes() + NbElements();
1968 // Check if group contents changed
1970 typedef map< string, TopoDS_Shape > TEntry2Geom;
1971 TEntry2Geom newGroupContents;
1973 list<TGeomGroupData>::iterator
1974 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1975 for ( ; data != dataEnd; ++data )
1977 pair< TEntry2Geom::iterator, bool > it_new =
1978 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
1979 bool processedGroup = !it_new.second;
1980 TopoDS_Shape& newShape = it_new.first->second;
1981 if ( !processedGroup )
1982 newShape = newGroupShape( *data );
1983 if ( newShape.IsNull() )
1984 continue; // no changes
1987 _preMeshInfo->ForgetOrLoad();
1989 if ( processedGroup ) { // update group indices
1990 list<TGeomGroupData>::iterator data2 = data;
1991 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
1992 data->_indices = data2->_indices;
1995 // Update SMESH objects according to new GEOM group contents
1997 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
1998 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2000 int oldID = submesh->GetId();
2001 if ( !_mapSubMeshIor.count( oldID ))
2003 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2005 // update hypotheses
2006 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2007 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2008 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2010 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2011 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2013 // care of submeshes
2014 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2015 int newID = newSubmesh->GetId();
2016 if ( newID != oldID ) {
2017 _mapSubMesh [ newID ] = newSubmesh;
2018 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2019 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2020 _mapSubMesh. erase(oldID);
2021 _mapSubMesh_i. erase(oldID);
2022 _mapSubMeshIor.erase(oldID);
2023 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2028 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2029 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2030 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2032 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2034 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2035 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2036 ds->SetShape( newShape );
2041 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2042 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2044 // Remove groups and submeshes basing on removed sub-shapes
2046 TopTools_MapOfShape newShapeMap;
2047 TopoDS_Iterator shapeIt( newShape );
2048 for ( ; shapeIt.More(); shapeIt.Next() )
2049 newShapeMap.Add( shapeIt.Value() );
2051 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2052 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2054 if ( newShapeMap.Contains( shapeIt.Value() ))
2056 TopTools_IndexedMapOfShape oldShapeMap;
2057 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2058 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2060 const TopoDS_Shape& oldShape = oldShapeMap(i);
2061 int oldInd = meshDS->ShapeToIndex( oldShape );
2063 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2064 if ( i_smIor != _mapSubMeshIor.end() ) {
2065 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2068 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2069 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2071 // check if a group bases on oldInd shape
2072 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2073 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2074 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2075 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2077 RemoveGroup( i_grp->second ); // several groups can base on same shape
2078 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2083 // Reassign hypotheses and update groups after setting the new shape to mesh
2085 // collect anassigned hypotheses
2086 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2087 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2088 TShapeHypList assignedHyps;
2089 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2091 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2092 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2093 if ( !hyps.empty() ) {
2094 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2095 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2096 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2099 // collect shapes supporting groups
2100 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2101 TShapeTypeList groupData;
2102 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2103 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2104 for ( ; grIt != groups.end(); ++grIt )
2106 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2108 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2110 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2111 _impl->ShapeToMesh( newShape );
2113 // reassign hypotheses
2114 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2115 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2117 TIndexedShape& geom = indS_hyps->first;
2118 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2119 int oldID = geom._index;
2120 int newID = meshDS->ShapeToIndex( geom._shape );
2121 if ( oldID == 1 ) { // main shape
2123 geom._shape = newShape;
2127 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2128 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2129 // care of submeshes
2130 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2131 if ( newID != oldID ) {
2132 _mapSubMesh [ newID ] = newSubmesh;
2133 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2134 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2135 _mapSubMesh. erase(oldID);
2136 _mapSubMesh_i. erase(oldID);
2137 _mapSubMeshIor.erase(oldID);
2138 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2142 TShapeTypeList::iterator geomType = groupData.begin();
2143 for ( ; geomType != groupData.end(); ++geomType )
2145 const TIndexedShape& geom = geomType->first;
2146 int oldID = geom._index;
2147 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2150 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2151 CORBA::String_var name = groupSO->GetName();
2153 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2155 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2156 group_i->changeLocalId( newID );
2159 break; // everything has been updated
2162 } // loop on group data
2166 CORBA::Long newNbEntities = NbNodes() + NbElements();
2167 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2168 if ( newNbEntities != nbEntities )
2170 // Add all SObjects with icons to soToUpdateIcons
2171 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2173 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2174 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2175 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2177 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2178 i_gr != _mapGroups.end(); ++i_gr ) // groups
2179 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2182 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2183 for ( ; so != soToUpdateIcons.end(); ++so )
2184 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2187 //=============================================================================
2189 * \brief Create standalone group from a group on geometry or filter
2191 //=============================================================================
2193 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2194 throw (SALOME::SALOME_Exception)
2196 SMESH::SMESH_Group_var aGroup;
2201 _preMeshInfo->FullLoadFromFile();
2203 if ( theGroup->_is_nil() )
2204 return aGroup._retn();
2206 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2208 return aGroup._retn();
2210 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2212 const int anId = aGroupToRem->GetLocalID();
2213 if ( !_impl->ConvertToStandalone( anId ) )
2214 return aGroup._retn();
2215 removeGeomGroupData( theGroup );
2217 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2219 // remove old instance of group from own map
2220 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2221 _mapGroups.erase( anId );
2223 SALOMEDS::StudyBuilder_var builder;
2224 SALOMEDS::SObject_wrap aGroupSO;
2225 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2226 if ( !aStudy->_is_nil() ) {
2227 builder = aStudy->NewBuilder();
2228 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2229 if ( !aGroupSO->_is_nil() )
2231 // remove reference to geometry
2232 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2233 for ( ; chItr->More(); chItr->Next() )
2234 // Remove group's child SObject
2235 builder->RemoveObject( chItr->Value() );
2237 // Update Python script
2238 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2239 << ".ConvertToStandalone( " << aGroupSO << " )";
2241 // change icon of Group on Filter
2244 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2245 const int isEmpty = ( elemTypes->length() == 0 );
2248 SALOMEDS::GenericAttribute_wrap anAttr =
2249 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2250 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2251 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2257 // remember new group in own map
2258 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2259 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2261 // register CORBA object for persistence
2262 _gen_i->RegisterObject( aGroup );
2264 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2265 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2266 //aGroup->Register();
2267 aGroupToRem->UnRegister();
2269 SMESH_CATCH( SMESH::throwCorbaException );
2271 return aGroup._retn();
2274 //=============================================================================
2278 //=============================================================================
2280 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2282 if(MYDEBUG) MESSAGE( "createSubMesh" );
2283 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2284 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2285 const int subMeshId = mySubMesh->GetId();
2287 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2288 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2290 _mapSubMesh [subMeshId] = mySubMesh;
2291 _mapSubMesh_i [subMeshId] = subMeshServant;
2292 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2294 subMeshServant->Register();
2296 // register CORBA object for persistence
2297 int nextId = _gen_i->RegisterObject( subMesh );
2298 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2299 else { nextId = 0; } // avoid "unused variable" warning
2301 // to track changes of GEOM groups
2302 addGeomGroupData( theSubShapeObject, subMesh );
2304 return subMesh._retn();
2307 //=======================================================================
2308 //function : getSubMesh
2310 //=======================================================================
2312 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2314 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2315 if ( it == _mapSubMeshIor.end() )
2316 return SMESH::SMESH_subMesh::_nil();
2318 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2321 //=============================================================================
2325 //=============================================================================
2327 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2328 GEOM::GEOM_Object_ptr theSubShapeObject )
2330 bool isHypChanged = false;
2331 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2332 return isHypChanged;
2334 const int subMeshId = theSubMesh->GetId();
2336 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2338 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2340 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2343 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2344 isHypChanged = !hyps.empty();
2345 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2346 for ( ; hyp != hyps.end(); ++hyp )
2347 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2354 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2355 isHypChanged = ( aHypList->length() > 0 );
2356 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2357 removeHypothesis( theSubShapeObject, aHypList[i] );
2360 catch( const SALOME::SALOME_Exception& ) {
2361 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2363 removeGeomGroupData( theSubShapeObject );
2367 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2368 if ( id_smi != _mapSubMesh_i.end() )
2369 id_smi->second->UnRegister();
2371 // remove a CORBA object
2372 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2373 if ( id_smptr != _mapSubMeshIor.end() )
2374 SMESH::SMESH_subMesh_var( id_smptr->second );
2376 _mapSubMesh.erase(subMeshId);
2377 _mapSubMesh_i.erase(subMeshId);
2378 _mapSubMeshIor.erase(subMeshId);
2380 return isHypChanged;
2383 //=============================================================================
2387 //=============================================================================
2389 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2390 const char* theName,
2391 const TopoDS_Shape& theShape,
2392 const SMESH_PredicatePtr& thePredicate )
2394 std::string newName;
2395 if ( !theName || strlen( theName ) == 0 )
2397 std::set< std::string > presentNames;
2398 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2399 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2401 CORBA::String_var name = i_gr->second->GetName();
2402 presentNames.insert( name.in() );
2405 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2406 } while ( !presentNames.insert( newName ).second );
2407 theName = newName.c_str();
2410 SMESH::SMESH_GroupBase_var aGroup;
2411 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2413 SMESH_GroupBase_i* aGroupImpl;
2414 if ( !theShape.IsNull() )
2415 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2416 else if ( thePredicate )
2417 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2419 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2421 aGroup = aGroupImpl->_this();
2422 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2423 aGroupImpl->Register();
2425 // register CORBA object for persistence
2426 int nextId = _gen_i->RegisterObject( aGroup );
2427 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2428 else { nextId = 0; } // avoid "unused variable" warning in release mode
2430 // to track changes of GEOM groups
2431 if ( !theShape.IsNull() ) {
2432 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2433 addGeomGroupData( geom, aGroup );
2436 return aGroup._retn();
2439 //=============================================================================
2441 * SMESH_Mesh_i::removeGroup
2443 * Should be called by ~SMESH_Group_i()
2445 //=============================================================================
2447 void SMESH_Mesh_i::removeGroup( const int theId )
2449 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2450 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2451 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2452 _mapGroups.erase( theId );
2453 removeGeomGroupData( group );
2454 if ( !_impl->RemoveGroup( theId ))
2456 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2457 RemoveGroup( group );
2459 group->UnRegister();
2463 //=============================================================================
2467 //=============================================================================
2469 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2470 throw(SALOME::SALOME_Exception)
2472 SMESH::log_array_var aLog;
2476 _preMeshInfo->FullLoadFromFile();
2478 list < SMESHDS_Command * >logDS = _impl->GetLog();
2479 aLog = new SMESH::log_array;
2481 int lg = logDS.size();
2484 list < SMESHDS_Command * >::iterator its = logDS.begin();
2485 while(its != logDS.end()){
2486 SMESHDS_Command *com = *its;
2487 int comType = com->GetType();
2489 int lgcom = com->GetNumber();
2491 const list < int >&intList = com->GetIndexes();
2492 int inum = intList.size();
2494 list < int >::const_iterator ii = intList.begin();
2495 const list < double >&coordList = com->GetCoords();
2496 int rnum = coordList.size();
2498 list < double >::const_iterator ir = coordList.begin();
2499 aLog[indexLog].commandType = comType;
2500 aLog[indexLog].number = lgcom;
2501 aLog[indexLog].coords.length(rnum);
2502 aLog[indexLog].indexes.length(inum);
2503 for(int i = 0; i < rnum; i++){
2504 aLog[indexLog].coords[i] = *ir;
2505 //MESSAGE(" "<<i<<" "<<ir.Value());
2508 for(int i = 0; i < inum; i++){
2509 aLog[indexLog].indexes[i] = *ii;
2510 //MESSAGE(" "<<i<<" "<<ii.Value());
2519 SMESH_CATCH( SMESH::throwCorbaException );
2521 return aLog._retn();
2525 //=============================================================================
2529 //=============================================================================
2531 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2535 SMESH_CATCH( SMESH::throwCorbaException );
2538 //=============================================================================
2542 //=============================================================================
2544 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2549 //=============================================================================
2553 //=============================================================================
2555 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2560 //=============================================================================
2563 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2564 // issue 0020918: groups removal is caused by hyp modification
2565 // issue 0021208: to forget not loaded mesh data at hyp modification
2566 struct TCallUp_i : public SMESH_Mesh::TCallUp
2568 SMESH_Mesh_i* _mesh;
2569 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2570 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2571 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2572 virtual void Load () { _mesh->Load(); }
2576 //================================================================================
2578 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2580 //================================================================================
2582 void SMESH_Mesh_i::onHypothesisModified()
2585 _preMeshInfo->ForgetOrLoad();
2588 //=============================================================================
2592 //=============================================================================
2594 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2596 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2599 _impl->SetCallUp( new TCallUp_i(this));
2602 //=============================================================================
2606 //=============================================================================
2608 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2610 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2614 //=============================================================================
2616 * Return mesh editor
2618 //=============================================================================
2620 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2621 throw (SALOME::SALOME_Exception)
2623 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2627 _preMeshInfo->FullLoadFromFile();
2629 // Create MeshEditor
2631 _editor = new SMESH_MeshEditor_i( this, false );
2632 aMeshEdVar = _editor->_this();
2634 // Update Python script
2635 TPythonDump() << _editor << " = "
2636 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2638 SMESH_CATCH( SMESH::throwCorbaException );
2640 return aMeshEdVar._retn();
2643 //=============================================================================
2645 * Return mesh edition previewer
2647 //=============================================================================
2649 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2650 throw (SALOME::SALOME_Exception)
2652 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2656 _preMeshInfo->FullLoadFromFile();
2658 if ( !_previewEditor )
2659 _previewEditor = new SMESH_MeshEditor_i( this, true );
2660 aMeshEdVar = _previewEditor->_this();
2662 SMESH_CATCH( SMESH::throwCorbaException );
2664 return aMeshEdVar._retn();
2667 //================================================================================
2669 * \brief Return true if the mesh has been edited since a last total re-compute
2670 * and those modifications may prevent successful partial re-compute
2672 //================================================================================
2674 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2676 Unexpect aCatch(SALOME_SalomeException);
2677 return _impl->HasModificationsToDiscard();
2680 //================================================================================
2682 * \brief Returns a random unique color
2684 //================================================================================
2686 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2688 const int MAX_ATTEMPTS = 100;
2690 double tolerance = 0.5;
2691 SALOMEDS::Color col;
2695 // generate random color
2696 double red = (double)rand() / RAND_MAX;
2697 double green = (double)rand() / RAND_MAX;
2698 double blue = (double)rand() / RAND_MAX;
2699 // check existence in the list of the existing colors
2700 bool matched = false;
2701 std::list<SALOMEDS::Color>::const_iterator it;
2702 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2703 SALOMEDS::Color color = *it;
2704 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2705 matched = tol < tolerance;
2707 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2708 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2716 //=============================================================================
2718 * Sets auto-color mode. If it is on, groups get unique random colors
2720 //=============================================================================
2722 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2724 Unexpect aCatch(SALOME_SalomeException);
2725 _impl->SetAutoColor(theAutoColor);
2727 TPythonDump pyDump; // not to dump group->SetColor() from below code
2728 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2730 std::list<SALOMEDS::Color> aReservedColors;
2731 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2732 for ( ; it != _mapGroups.end(); it++ ) {
2733 if ( CORBA::is_nil( it->second )) continue;
2734 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2735 it->second->SetColor( aColor );
2736 aReservedColors.push_back( aColor );
2740 //=============================================================================
2742 * Returns true if auto-color mode is on
2744 //=============================================================================
2746 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2748 Unexpect aCatch(SALOME_SalomeException);
2749 return _impl->GetAutoColor();
2752 //=============================================================================
2754 * Checks if there are groups with equal names
2756 //=============================================================================
2758 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2760 return _impl->HasDuplicatedGroupNamesMED();
2763 //================================================================================
2765 * \brief Care of a file before exporting mesh into it
2767 //================================================================================
2769 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2771 SMESH_File aFile( file );
2773 if (aFile.exists()) {
2774 // existing filesystem node
2775 if ( !aFile.isDirectory() ) {
2776 if ( aFile.openForWriting() ) {
2777 if ( overwrite && ! aFile.remove()) {
2778 msg << "Can't replace " << aFile.getName();
2781 msg << "Can't write into " << aFile.getName();
2784 msg << "Location " << aFile.getName() << " is not a file";
2788 // nonexisting file; check if it can be created
2789 if ( !aFile.openForWriting() ) {
2790 msg << "You cannot create the file "
2792 << ". Check the directory existance and access rights";
2800 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2804 //================================================================================
2806 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2807 * \param file - file name
2808 * \param overwrite - to erase the file or not
2809 * \retval string - mesh name
2811 //================================================================================
2813 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2814 CORBA::Boolean overwrite)
2817 PrepareForWriting(file, overwrite);
2818 string aMeshName = "Mesh";
2819 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2820 if ( !aStudy->_is_nil() ) {
2821 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2822 if ( !aMeshSO->_is_nil() ) {
2823 CORBA::String_var name = aMeshSO->GetName();
2825 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2826 if ( !aStudy->GetProperties()->IsLocked() )
2828 SALOMEDS::GenericAttribute_wrap anAttr;
2829 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2830 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2831 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2832 ASSERT(!aFileName->_is_nil());
2833 aFileName->SetValue(file);
2834 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2835 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2836 ASSERT(!aFileType->_is_nil());
2837 aFileType->SetValue("FICHIERMED");
2841 // Update Python script
2842 // set name of mesh before export
2843 TPythonDump() << _gen_i << ".SetName("
2844 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2846 // check names of groups
2852 //================================================================================
2854 * \brief Export to med file
2856 //================================================================================
2858 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2859 CORBA::Boolean auto_groups,
2860 SMESH::MED_VERSION theVersion,
2861 CORBA::Boolean overwrite,
2862 CORBA::Boolean autoDimension)
2863 throw(SALOME::SALOME_Exception)
2867 _preMeshInfo->FullLoadFromFile();
2869 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
2870 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
2872 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
2873 << file << "', " << auto_groups << ", "
2874 << theVersion << ", " << overwrite << ", "
2875 << autoDimension << " )";
2877 SMESH_CATCH( SMESH::throwCorbaException );
2880 //================================================================================
2882 * \brief Export a mesh to a med file
2884 //================================================================================
2886 void SMESH_Mesh_i::ExportToMED (const char* file,
2887 CORBA::Boolean auto_groups,
2888 SMESH::MED_VERSION theVersion)
2889 throw(SALOME::SALOME_Exception)
2891 ExportToMEDX(file,auto_groups,theVersion,true);
2894 //================================================================================
2896 * \brief Export a mesh to a med file
2898 //================================================================================
2900 void SMESH_Mesh_i::ExportMED (const char* file,
2901 CORBA::Boolean auto_groups)
2902 throw(SALOME::SALOME_Exception)
2904 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
2907 //================================================================================
2909 * \brief Export a mesh to a SAUV file
2911 //================================================================================
2913 void SMESH_Mesh_i::ExportSAUV (const char* file,
2914 CORBA::Boolean auto_groups)
2915 throw(SALOME::SALOME_Exception)
2917 Unexpect aCatch(SALOME_SalomeException);
2919 _preMeshInfo->FullLoadFromFile();
2921 string aMeshName = prepareMeshNameAndGroups(file, true);
2922 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
2923 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
2924 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
2928 //================================================================================
2930 * \brief Export a mesh to a DAT file
2932 //================================================================================
2934 void SMESH_Mesh_i::ExportDAT (const char *file)
2935 throw(SALOME::SALOME_Exception)
2937 Unexpect aCatch(SALOME_SalomeException);
2939 _preMeshInfo->FullLoadFromFile();
2941 // Update Python script
2942 // check names of groups
2944 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
2947 PrepareForWriting(file);
2948 _impl->ExportDAT(file);
2951 //================================================================================
2953 * \brief Export a mesh to an UNV file
2955 //================================================================================
2957 void SMESH_Mesh_i::ExportUNV (const char *file)
2958 throw(SALOME::SALOME_Exception)
2960 Unexpect aCatch(SALOME_SalomeException);
2962 _preMeshInfo->FullLoadFromFile();
2964 // Update Python script
2965 // check names of groups
2967 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
2970 PrepareForWriting(file);
2971 _impl->ExportUNV(file);
2974 //================================================================================
2976 * \brief Export a mesh to an STL file
2978 //================================================================================
2980 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
2981 throw(SALOME::SALOME_Exception)
2983 Unexpect aCatch(SALOME_SalomeException);
2985 _preMeshInfo->FullLoadFromFile();
2987 // Update Python script
2988 // check names of groups
2990 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
2991 << ".ExportSTL( r'" << file << "', " << isascii << " )";
2994 PrepareForWriting(file);
2995 _impl->ExportSTL(file, isascii);
2998 //================================================================================
3000 * \brief Export a part of mesh to a med file
3002 //================================================================================
3004 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3006 CORBA::Boolean auto_groups,
3007 SMESH::MED_VERSION version,
3008 CORBA::Boolean overwrite,
3009 CORBA::Boolean autoDimension,
3010 const GEOM::ListOfFields& fields,
3011 const char* geomAssocFields)
3012 throw (SALOME::SALOME_Exception)
3016 _preMeshInfo->FullLoadFromFile();
3019 bool have0dField = false;
3020 if ( fields.length() > 0 )
3022 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3023 if ( shapeToMesh->_is_nil() )
3024 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3026 for ( size_t i = 0; i < fields.length(); ++i )
3028 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3029 THROW_SALOME_CORBA_EXCEPTION
3030 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3031 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3032 if ( fieldShape->_is_nil() )
3033 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3034 if ( !fieldShape->IsSame( shapeToMesh ) )
3035 THROW_SALOME_CORBA_EXCEPTION
3036 ( "Field defined not on shape", SALOME::BAD_PARAM);
3037 if ( fields[i]->GetDimension() == 0 )
3040 if ( geomAssocFields )
3041 for ( int i = 0; geomAssocFields[i]; ++i )
3042 switch ( geomAssocFields[i] ) {
3043 case 'v':case 'e':case 'f':case 's': break;
3044 case 'V':case 'E':case 'F':case 'S': break;
3045 default: THROW_SALOME_CORBA_EXCEPTION
3046 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3050 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3054 string aMeshName = "Mesh";
3055 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3056 if ( CORBA::is_nil( meshPart ) ||
3057 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3059 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3060 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3061 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3062 meshDS = _impl->GetMeshDS();
3067 _preMeshInfo->FullLoadFromFile();
3069 PrepareForWriting(file, overwrite);
3071 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3072 if ( !aStudy->_is_nil() ) {
3073 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3074 if ( !SO->_is_nil() ) {
3075 CORBA::String_var name = SO->GetName();
3079 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3080 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3081 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3082 meshDS = tmpDSDeleter._obj = partDS;
3087 if ( _impl->HasShapeToMesh() )
3089 DriverMED_W_Field fieldWriter;
3090 fieldWriter.SetFile( file );
3091 fieldWriter.SetMeshName( aMeshName );
3092 fieldWriter.AddODOnVertices( have0dField );
3094 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3098 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3099 goList->length( fields.length() );
3100 for ( size_t i = 0; i < fields.length(); ++i )
3102 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3105 TPythonDump() << _this() << ".ExportPartToMED( "
3106 << meshPart << ", r'" << file << "', "
3107 << auto_groups << ", " << version << ", " << overwrite << ", "
3108 << autoDimension << ", " << goList
3109 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3111 SMESH_CATCH( SMESH::throwCorbaException );
3114 //================================================================================
3116 * Write GEOM fields to MED file
3118 //================================================================================
3120 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3121 SMESHDS_Mesh* meshDS,
3122 const GEOM::ListOfFields& fields,
3123 const char* geomAssocFields)
3125 #define METH "SMESH_Mesh_i::exportMEDFields() "
3127 if (( fields.length() < 1 ) &&
3128 ( !geomAssocFields || !geomAssocFields[0] ))
3131 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3132 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3133 std::vector< int > subIdsByDim[ 4 ];
3134 const double noneDblValue = 0.;
3135 const double noneIntValue = 0;
3137 for ( size_t iF = 0; iF < fields.length(); ++iF )
3141 int dim = fields[ iF ]->GetDimension();
3142 SMDSAbs_ElementType elemType;
3143 TopAbs_ShapeEnum shapeType;
3145 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3146 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3147 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3148 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3150 continue; // skip fields on whole shape
3152 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3153 if ( dataType == GEOM::FDT_String )
3155 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3156 if ( stepIDs->length() < 1 )
3158 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3159 if ( comps->length() < 1 )
3161 CORBA::String_var name = fields[ iF ]->GetName();
3163 if ( !fieldWriter.Set( meshDS,
3167 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3170 for ( size_t iC = 0; iC < comps->length(); ++iC )
3171 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3173 // find sub-shape IDs
3175 std::vector< int >& subIds = subIdsByDim[ dim ];
3176 if ( subIds.empty() )
3177 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3178 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3179 subIds.push_back( id );
3183 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3187 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3189 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3190 if ( step->_is_nil() )
3193 CORBA::Long stamp = step->GetStamp();
3194 CORBA::Long id = step->GetID();
3195 fieldWriter.SetDtIt( int( stamp ), int( id ));
3197 // fill dblVals or intVals
3200 case GEOM::FDT_Double:
3202 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3203 if ( dblStep->_is_nil() ) continue;
3204 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3205 if ( vv->length() != subIds.size() )
3206 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3207 for ( size_t i = 0; i < vv->length(); ++i )
3208 dblVals[ subIds[ i ]] = vv[ i ];
3213 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3214 if ( intStep->_is_nil() ) continue;
3215 GEOM::ListOfLong_var vv = intStep->GetValues();
3216 if ( vv->length() != subIds.size() )
3217 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3218 for ( size_t i = 0; i < vv->length(); ++i )
3219 intVals[ subIds[ i ]] = (int) vv[ i ];
3222 case GEOM::FDT_Bool:
3224 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3225 if ( boolStep->_is_nil() ) continue;
3226 GEOM::short_array_var vv = boolStep->GetValues();
3227 if ( vv->length() != subIds.size() )
3228 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3229 for ( size_t i = 0; i < vv->length(); ++i )
3230 intVals[ subIds[ i ]] = (int) vv[ i ];
3236 // pass values to fieldWriter
3237 elemIt = fieldWriter.GetOrderedElems();
3238 if ( dataType == GEOM::FDT_Double )
3239 while ( elemIt->more() )
3241 const SMDS_MeshElement* e = elemIt->next();
3242 const int shapeID = e->getshapeId();
3243 if ( shapeID < 1 || shapeID >= dblVals.size() )
3244 fieldWriter.AddValue( noneDblValue );
3246 fieldWriter.AddValue( dblVals[ shapeID ]);
3249 while ( elemIt->more() )
3251 const SMDS_MeshElement* e = elemIt->next();
3252 const int shapeID = e->getshapeId();
3253 if ( shapeID < 1 || shapeID >= intVals.size() )
3254 fieldWriter.AddValue( (double) noneIntValue );
3256 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3260 fieldWriter.Perform();
3261 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3262 if ( res && res->IsKO() )
3264 if ( res->myComment.empty() )
3265 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3267 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3273 if ( !geomAssocFields || !geomAssocFields[0] )
3276 // write geomAssocFields
3278 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3279 shapeDim[ TopAbs_COMPOUND ] = 3;
3280 shapeDim[ TopAbs_COMPSOLID ] = 3;
3281 shapeDim[ TopAbs_SOLID ] = 3;
3282 shapeDim[ TopAbs_SHELL ] = 2;
3283 shapeDim[ TopAbs_FACE ] = 2;
3284 shapeDim[ TopAbs_WIRE ] = 1;
3285 shapeDim[ TopAbs_EDGE ] = 1;
3286 shapeDim[ TopAbs_VERTEX ] = 0;
3287 shapeDim[ TopAbs_SHAPE ] = 3;
3289 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3291 std::vector< std::string > compNames;
3292 switch ( geomAssocFields[ iF ]) {
3294 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3295 compNames.push_back( "dim" );
3298 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3301 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3304 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3308 compNames.push_back( "id" );
3309 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3310 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3312 fieldWriter.SetDtIt( -1, -1 );
3314 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3318 if ( compNames.size() == 2 ) // _vertices_
3319 while ( elemIt->more() )
3321 const SMDS_MeshElement* e = elemIt->next();
3322 const int shapeID = e->getshapeId();
3325 fieldWriter.AddValue( (double) -1 );
3326 fieldWriter.AddValue( (double) -1 );
3330 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3331 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3332 fieldWriter.AddValue( (double) shapeID );
3336 while ( elemIt->more() )
3338 const SMDS_MeshElement* e = elemIt->next();
3339 const int shapeID = e->getshapeId();
3341 fieldWriter.AddValue( (double) -1 );
3343 fieldWriter.AddValue( (double) shapeID );
3347 fieldWriter.Perform();
3348 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3349 if ( res && res->IsKO() )
3351 if ( res->myComment.empty() )
3352 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3354 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3357 } // loop on geomAssocFields
3362 //================================================================================
3364 * \brief Export a part of mesh to a DAT file
3366 //================================================================================
3368 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3370 throw (SALOME::SALOME_Exception)
3372 Unexpect aCatch(SALOME_SalomeException);
3374 _preMeshInfo->FullLoadFromFile();
3376 PrepareForWriting(file);
3378 SMESH_MeshPartDS partDS( meshPart );
3379 _impl->ExportDAT(file,&partDS);
3381 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3382 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3384 //================================================================================
3386 * \brief Export a part of mesh to an UNV file
3388 //================================================================================
3390 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3392 throw (SALOME::SALOME_Exception)
3394 Unexpect aCatch(SALOME_SalomeException);
3396 _preMeshInfo->FullLoadFromFile();
3398 PrepareForWriting(file);
3400 SMESH_MeshPartDS partDS( meshPart );
3401 _impl->ExportUNV(file, &partDS);
3403 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3404 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3406 //================================================================================
3408 * \brief Export a part of mesh to an STL file
3410 //================================================================================
3412 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3414 ::CORBA::Boolean isascii)
3415 throw (SALOME::SALOME_Exception)
3417 Unexpect aCatch(SALOME_SalomeException);
3419 _preMeshInfo->FullLoadFromFile();
3421 PrepareForWriting(file);
3423 SMESH_MeshPartDS partDS( meshPart );
3424 _impl->ExportSTL(file, isascii, &partDS);
3426 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3427 << meshPart<< ", r'" << file << "', " << isascii << ")";
3430 //================================================================================
3432 * \brief Export a part of mesh to an STL file
3434 //================================================================================
3436 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3438 CORBA::Boolean overwrite)
3439 throw (SALOME::SALOME_Exception)
3442 Unexpect aCatch(SALOME_SalomeException);
3444 _preMeshInfo->FullLoadFromFile();
3446 PrepareForWriting(file,overwrite);
3448 SMESH_MeshPartDS partDS( meshPart );
3449 _impl->ExportCGNS(file, &partDS);
3451 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3452 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3454 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3458 //================================================================================
3460 * \brief Export a part of mesh to a GMF file
3462 //================================================================================
3464 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3466 bool withRequiredGroups)
3467 throw (SALOME::SALOME_Exception)
3469 Unexpect aCatch(SALOME_SalomeException);
3471 _preMeshInfo->FullLoadFromFile();
3473 PrepareForWriting(file,/*overwrite=*/true);
3475 SMESH_MeshPartDS partDS( meshPart );
3476 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3478 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3479 << meshPart<< ", r'"
3481 << withRequiredGroups << ")";
3484 //=============================================================================
3486 * Return computation progress [0.,1]
3488 //=============================================================================
3490 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3494 return _impl->GetComputeProgress();
3496 SMESH_CATCH( SMESH::doNothing );
3500 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3502 Unexpect aCatch(SALOME_SalomeException);
3504 return _preMeshInfo->NbNodes();
3506 return _impl->NbNodes();
3509 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3511 Unexpect aCatch(SALOME_SalomeException);
3513 return _preMeshInfo->NbElements();
3515 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3518 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3520 Unexpect aCatch(SALOME_SalomeException);
3522 return _preMeshInfo->Nb0DElements();
3524 return _impl->Nb0DElements();
3527 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3529 Unexpect aCatch(SALOME_SalomeException);
3531 return _preMeshInfo->NbBalls();
3533 return _impl->NbBalls();
3536 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3538 Unexpect aCatch(SALOME_SalomeException);
3540 return _preMeshInfo->NbEdges();
3542 return _impl->NbEdges();
3545 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3546 throw(SALOME::SALOME_Exception)
3548 Unexpect aCatch(SALOME_SalomeException);
3550 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3552 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3555 //=============================================================================
3557 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3559 Unexpect aCatch(SALOME_SalomeException);
3561 return _preMeshInfo->NbFaces();
3563 return _impl->NbFaces();
3566 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3568 Unexpect aCatch(SALOME_SalomeException);
3570 return _preMeshInfo->NbTriangles();
3572 return _impl->NbTriangles();
3575 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3577 Unexpect aCatch(SALOME_SalomeException);
3579 return _preMeshInfo->NbBiQuadTriangles();
3581 return _impl->NbBiQuadTriangles();
3584 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3586 Unexpect aCatch(SALOME_SalomeException);
3588 return _preMeshInfo->NbQuadrangles();
3590 return _impl->NbQuadrangles();
3593 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3595 Unexpect aCatch(SALOME_SalomeException);
3597 return _preMeshInfo->NbBiQuadQuadrangles();
3599 return _impl->NbBiQuadQuadrangles();
3602 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3604 Unexpect aCatch(SALOME_SalomeException);
3606 return _preMeshInfo->NbPolygons();
3608 return _impl->NbPolygons();
3611 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3612 throw(SALOME::SALOME_Exception)
3614 Unexpect aCatch(SALOME_SalomeException);
3616 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3618 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3621 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3622 throw(SALOME::SALOME_Exception)
3624 Unexpect aCatch(SALOME_SalomeException);
3626 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3628 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3631 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3632 throw(SALOME::SALOME_Exception)
3634 Unexpect aCatch(SALOME_SalomeException);
3636 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3638 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3641 //=============================================================================
3643 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3645 Unexpect aCatch(SALOME_SalomeException);
3647 return _preMeshInfo->NbVolumes();
3649 return _impl->NbVolumes();
3652 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3654 Unexpect aCatch(SALOME_SalomeException);
3656 return _preMeshInfo->NbTetras();
3658 return _impl->NbTetras();
3661 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3663 Unexpect aCatch(SALOME_SalomeException);
3665 return _preMeshInfo->NbHexas();
3667 return _impl->NbHexas();
3670 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3672 Unexpect aCatch(SALOME_SalomeException);
3674 return _preMeshInfo->NbTriQuadHexas();
3676 return _impl->NbTriQuadraticHexas();
3679 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3681 Unexpect aCatch(SALOME_SalomeException);
3683 return _preMeshInfo->NbPyramids();
3685 return _impl->NbPyramids();
3688 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3690 Unexpect aCatch(SALOME_SalomeException);
3692 return _preMeshInfo->NbPrisms();
3694 return _impl->NbPrisms();
3697 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3699 Unexpect aCatch(SALOME_SalomeException);
3701 return _preMeshInfo->NbHexPrisms();
3703 return _impl->NbHexagonalPrisms();
3706 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3708 Unexpect aCatch(SALOME_SalomeException);
3710 return _preMeshInfo->NbPolyhedrons();
3712 return _impl->NbPolyhedrons();
3715 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3716 throw(SALOME::SALOME_Exception)
3718 Unexpect aCatch(SALOME_SalomeException);
3720 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3722 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3725 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3726 throw(SALOME::SALOME_Exception)
3728 Unexpect aCatch(SALOME_SalomeException);
3730 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3732 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3735 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3736 throw(SALOME::SALOME_Exception)
3738 Unexpect aCatch(SALOME_SalomeException);
3740 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3742 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3745 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3746 throw(SALOME::SALOME_Exception)
3748 Unexpect aCatch(SALOME_SalomeException);
3750 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3752 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3755 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3756 throw(SALOME::SALOME_Exception)
3758 Unexpect aCatch(SALOME_SalomeException);
3760 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3762 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3765 //=============================================================================
3767 * Returns nb of published sub-meshes
3769 //=============================================================================
3771 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3773 Unexpect aCatch(SALOME_SalomeException);
3774 return _mapSubMesh_i.size();
3777 //=============================================================================
3779 * Dumps mesh into a string
3781 //=============================================================================
3783 char* SMESH_Mesh_i::Dump()
3787 return CORBA::string_dup( os.str().c_str() );
3790 //=============================================================================
3792 * Method of SMESH_IDSource interface
3794 //=============================================================================
3796 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3798 return GetElementsId();
3801 //=============================================================================
3803 * Returns ids of all elements
3805 //=============================================================================
3807 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3808 throw (SALOME::SALOME_Exception)
3810 Unexpect aCatch(SALOME_SalomeException);
3812 _preMeshInfo->FullLoadFromFile();
3814 SMESH::long_array_var aResult = new SMESH::long_array();
3815 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3817 if ( aSMESHDS_Mesh == NULL )
3818 return aResult._retn();
3820 long nbElements = NbElements();
3821 aResult->length( nbElements );
3822 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3823 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3824 aResult[i] = anIt->next()->GetID();
3826 return aResult._retn();
3830 //=============================================================================
3832 * Returns ids of all elements of given type
3834 //=============================================================================
3836 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3837 throw (SALOME::SALOME_Exception)
3839 Unexpect aCatch(SALOME_SalomeException);
3841 _preMeshInfo->FullLoadFromFile();
3843 SMESH::long_array_var aResult = new SMESH::long_array();
3844 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3846 if ( aSMESHDS_Mesh == NULL )
3847 return aResult._retn();
3849 long nbElements = NbElements();
3851 // No sense in returning ids of elements along with ids of nodes:
3852 // when theElemType == SMESH::ALL, return node ids only if
3853 // there are no elements
3854 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3855 return GetNodesId();
3857 aResult->length( nbElements );
3861 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3862 while ( i < nbElements && anIt->more() )
3863 aResult[i++] = anIt->next()->GetID();
3865 aResult->length( i );
3867 return aResult._retn();
3870 //=============================================================================
3872 * Returns ids of all nodes
3874 //=============================================================================
3876 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
3877 throw (SALOME::SALOME_Exception)
3879 Unexpect aCatch(SALOME_SalomeException);
3881 _preMeshInfo->FullLoadFromFile();
3883 SMESH::long_array_var aResult = new SMESH::long_array();
3884 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3886 if ( aSMESHDS_Mesh == NULL )
3887 return aResult._retn();
3889 long nbNodes = NbNodes();
3890 aResult->length( nbNodes );
3891 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
3892 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
3893 aResult[i] = anIt->next()->GetID();
3895 return aResult._retn();
3898 //=============================================================================
3902 //=============================================================================
3904 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
3905 throw (SALOME::SALOME_Exception)
3907 SMESH::ElementType type;
3911 _preMeshInfo->FullLoadFromFile();
3913 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
3915 SMESH_CATCH( SMESH::throwCorbaException );
3920 //=============================================================================
3924 //=============================================================================
3926 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
3927 throw (SALOME::SALOME_Exception)
3930 _preMeshInfo->FullLoadFromFile();
3932 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3934 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3936 return ( SMESH::EntityType ) e->GetEntityType();
3939 //=============================================================================
3943 //=============================================================================
3945 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
3946 throw (SALOME::SALOME_Exception)
3949 _preMeshInfo->FullLoadFromFile();
3951 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
3953 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
3955 return ( SMESH::GeometryType ) e->GetGeomType();
3958 //=============================================================================
3960 * Returns ID of elements for given submesh
3962 //=============================================================================
3963 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
3964 throw (SALOME::SALOME_Exception)
3966 SMESH::long_array_var aResult = new SMESH::long_array();
3970 _preMeshInfo->FullLoadFromFile();
3972 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
3973 if(!SM) return aResult._retn();
3975 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
3976 if(!SDSM) return aResult._retn();
3978 aResult->length(SDSM->NbElements());
3980 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
3982 while ( eIt->more() ) {
3983 aResult[i++] = eIt->next()->GetID();
3986 SMESH_CATCH( SMESH::throwCorbaException );
3988 return aResult._retn();
3991 //=============================================================================
3993 * Returns ID of nodes for given submesh
3994 * If param all==true - returns all nodes, else -
3995 * returns only nodes on shapes.
3997 //=============================================================================
3999 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4001 throw (SALOME::SALOME_Exception)
4003 SMESH::long_array_var aResult = new SMESH::long_array();
4007 _preMeshInfo->FullLoadFromFile();
4009 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4010 if(!SM) return aResult._retn();
4012 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4013 if(!SDSM) return aResult._retn();
4016 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4017 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4018 while ( nIt->more() ) {
4019 const SMDS_MeshNode* elem = nIt->next();
4020 theElems.insert( elem->GetID() );
4023 else { // all nodes of submesh elements
4024 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4025 while ( eIt->more() ) {
4026 const SMDS_MeshElement* anElem = eIt->next();
4027 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4028 while ( nIt->more() ) {
4029 const SMDS_MeshElement* elem = nIt->next();
4030 theElems.insert( elem->GetID() );
4035 aResult->length(theElems.size());
4036 set<int>::iterator itElem;
4038 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4039 aResult[i++] = *itElem;
4041 SMESH_CATCH( SMESH::throwCorbaException );
4043 return aResult._retn();
4046 //=============================================================================
4048 * Returns type of elements for given submesh
4050 //=============================================================================
4052 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4053 throw (SALOME::SALOME_Exception)
4055 SMESH::ElementType type;
4059 _preMeshInfo->FullLoadFromFile();
4061 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4062 if(!SM) return SMESH::ALL;
4064 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4065 if(!SDSM) return SMESH::ALL;
4067 if(SDSM->NbElements()==0)
4068 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4070 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4071 const SMDS_MeshElement* anElem = eIt->next();
4073 type = ( SMESH::ElementType ) anElem->GetType();
4075 SMESH_CATCH( SMESH::throwCorbaException );
4081 //=============================================================================
4083 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4085 //=============================================================================
4087 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4090 _preMeshInfo->FullLoadFromFile();
4092 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4094 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4099 //=============================================================================
4101 * Get XYZ coordinates of node as list of double
4102 * If there is not node for given ID - returns empty list
4104 //=============================================================================
4106 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4109 _preMeshInfo->FullLoadFromFile();
4111 SMESH::double_array_var aResult = new SMESH::double_array();
4112 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4113 if ( aSMESHDS_Mesh == NULL )
4114 return aResult._retn();
4117 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4119 return aResult._retn();
4123 aResult[0] = aNode->X();
4124 aResult[1] = aNode->Y();
4125 aResult[2] = aNode->Z();
4126 return aResult._retn();
4130 //=============================================================================
4132 * For given node returns list of IDs of inverse elements
4133 * If there is not node for given ID - returns empty list
4135 //=============================================================================
4137 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4140 _preMeshInfo->FullLoadFromFile();
4142 SMESH::long_array_var aResult = new SMESH::long_array();
4143 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4144 if ( aSMESHDS_Mesh == NULL )
4145 return aResult._retn();
4148 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4150 return aResult._retn();
4152 // find inverse elements
4153 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4154 aResult->length( aNode->NbInverseElements() );
4155 for( int i = 0; eIt->more(); ++i )
4157 const SMDS_MeshElement* elem = eIt->next();
4158 aResult[ i ] = elem->GetID();
4160 return aResult._retn();
4163 //=============================================================================
4165 * \brief Return position of a node on shape
4167 //=============================================================================
4169 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4172 _preMeshInfo->FullLoadFromFile();
4174 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4175 aNodePosition->shapeID = 0;
4176 aNodePosition->shapeType = GEOM::SHAPE;
4178 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4179 if ( !mesh ) return aNodePosition;
4181 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4183 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4185 aNodePosition->shapeID = aNode->getshapeId();
4186 switch ( pos->GetTypeOfPosition() ) {
4188 aNodePosition->shapeType = GEOM::EDGE;
4189 aNodePosition->params.length(1);
4190 aNodePosition->params[0] =
4191 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4194 aNodePosition->shapeType = GEOM::FACE;
4195 aNodePosition->params.length(2);
4196 aNodePosition->params[0] =
4197 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4198 aNodePosition->params[1] =
4199 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4201 case SMDS_TOP_VERTEX:
4202 aNodePosition->shapeType = GEOM::VERTEX;
4204 case SMDS_TOP_3DSPACE:
4205 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4206 aNodePosition->shapeType = GEOM::SOLID;
4207 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4208 aNodePosition->shapeType = GEOM::SHELL;
4214 return aNodePosition;
4217 //=============================================================================
4219 * \brief Return position of an element on shape
4221 //=============================================================================
4223 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4226 _preMeshInfo->FullLoadFromFile();
4228 SMESH::ElementPosition anElementPosition;
4229 anElementPosition.shapeID = 0;
4230 anElementPosition.shapeType = GEOM::SHAPE;
4232 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4233 if ( !mesh ) return anElementPosition;
4235 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4237 anElementPosition.shapeID = anElem->getshapeId();
4238 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4239 if ( !aSp.IsNull() ) {
4240 switch ( aSp.ShapeType() ) {
4242 anElementPosition.shapeType = GEOM::EDGE;
4245 anElementPosition.shapeType = GEOM::FACE;
4248 anElementPosition.shapeType = GEOM::VERTEX;
4251 anElementPosition.shapeType = GEOM::SOLID;
4254 anElementPosition.shapeType = GEOM::SHELL;
4260 return anElementPosition;
4263 //=============================================================================
4265 * If given element is node returns IDs of shape from position
4266 * If there is not node for given ID - returns -1
4268 //=============================================================================
4270 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4273 _preMeshInfo->FullLoadFromFile();
4275 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4276 if ( aSMESHDS_Mesh == NULL )
4280 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4282 return aNode->getshapeId();
4289 //=============================================================================
4291 * For given element returns ID of result shape after
4292 * ::FindShape() from SMESH_MeshEditor
4293 * If there is not element for given ID - returns -1
4295 //=============================================================================
4297 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4300 _preMeshInfo->FullLoadFromFile();
4302 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4303 if ( aSMESHDS_Mesh == NULL )
4306 // try to find element
4307 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4311 ::SMESH_MeshEditor aMeshEditor(_impl);
4312 int index = aMeshEditor.FindShape( elem );
4320 //=============================================================================
4322 * Returns number of nodes for given element
4323 * If there is not element for given ID - returns -1
4325 //=============================================================================
4327 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4330 _preMeshInfo->FullLoadFromFile();
4332 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4333 if ( aSMESHDS_Mesh == NULL ) return -1;
4334 // try to find element
4335 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4336 if(!elem) return -1;
4337 return elem->NbNodes();
4341 //=============================================================================
4343 * Returns ID of node by given index for given element
4344 * If there is not element for given ID - returns -1
4345 * If there is not node for given index - returns -2
4347 //=============================================================================
4349 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4352 _preMeshInfo->FullLoadFromFile();
4354 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4355 if ( aSMESHDS_Mesh == NULL ) return -1;
4356 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4357 if(!elem) return -1;
4358 if( index>=elem->NbNodes() || index<0 ) return -1;
4359 return elem->GetNode(index)->GetID();
4362 //=============================================================================
4364 * Returns IDs of nodes of given element
4366 //=============================================================================
4368 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4371 _preMeshInfo->FullLoadFromFile();
4373 SMESH::long_array_var aResult = new SMESH::long_array();
4374 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4376 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4378 aResult->length( elem->NbNodes() );
4379 for ( int i = 0; i < elem->NbNodes(); ++i )
4380 aResult[ i ] = elem->GetNode( i )->GetID();
4383 return aResult._retn();
4386 //=============================================================================
4388 * Returns true if given node is medium node
4389 * in given quadratic element
4391 //=============================================================================
4393 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4396 _preMeshInfo->FullLoadFromFile();
4398 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4399 if ( aSMESHDS_Mesh == NULL ) return false;
4401 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4402 if(!aNode) return false;
4403 // try to find element
4404 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4405 if(!elem) return false;
4407 return elem->IsMediumNode(aNode);
4411 //=============================================================================
4413 * Returns true if given node is medium node
4414 * in one of quadratic elements
4416 //=============================================================================
4418 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4419 SMESH::ElementType theElemType)
4422 _preMeshInfo->FullLoadFromFile();
4424 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4425 if ( aSMESHDS_Mesh == NULL ) return false;
4428 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4429 if(!aNode) return false;
4431 SMESH_MesherHelper aHelper( *(_impl) );
4433 SMDSAbs_ElementType aType;
4434 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4435 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4436 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4437 else aType = SMDSAbs_All;
4439 return aHelper.IsMedium(aNode,aType);
4443 //=============================================================================
4445 * Returns number of edges for given element
4447 //=============================================================================
4449 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4452 _preMeshInfo->FullLoadFromFile();
4454 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4455 if ( aSMESHDS_Mesh == NULL ) return -1;
4456 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4457 if(!elem) return -1;
4458 return elem->NbEdges();
4462 //=============================================================================
4464 * Returns number of faces for given element
4466 //=============================================================================
4468 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4471 _preMeshInfo->FullLoadFromFile();
4473 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4474 if ( aSMESHDS_Mesh == NULL ) return -1;
4475 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4476 if(!elem) return -1;
4477 return elem->NbFaces();
4480 //=======================================================================
4481 //function : GetElemFaceNodes
4482 //purpose : Returns nodes of given face (counted from zero) for given element.
4483 //=======================================================================
4485 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4486 CORBA::Short faceIndex)
4489 _preMeshInfo->FullLoadFromFile();
4491 SMESH::long_array_var aResult = new SMESH::long_array();
4492 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4494 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4496 SMDS_VolumeTool vtool( elem );
4497 if ( faceIndex < vtool.NbFaces() )
4499 aResult->length( vtool.NbFaceNodes( faceIndex ));
4500 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4501 for ( int i = 0; i < aResult->length(); ++i )
4502 aResult[ i ] = nn[ i ]->GetID();
4506 return aResult._retn();
4509 //=======================================================================
4510 //function : GetElemFaceNodes
4511 //purpose : Returns three components of normal of given mesh face.
4512 //=======================================================================
4514 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4515 CORBA::Boolean normalized)
4518 _preMeshInfo->FullLoadFromFile();
4520 SMESH::double_array_var aResult = new SMESH::double_array();
4522 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4525 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4527 aResult->length( 3 );
4528 aResult[ 0 ] = normal.X();
4529 aResult[ 1 ] = normal.Y();
4530 aResult[ 2 ] = normal.Z();
4533 return aResult._retn();
4536 //=======================================================================
4537 //function : FindElementByNodes
4538 //purpose : Returns an element based on all given nodes.
4539 //=======================================================================
4541 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4544 _preMeshInfo->FullLoadFromFile();
4546 CORBA::Long elemID(0);
4547 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4549 vector< const SMDS_MeshNode * > nn( nodes.length() );
4550 for ( int i = 0; i < nodes.length(); ++i )
4551 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4554 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4555 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4556 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4557 _impl->NbVolumes( ORDER_QUADRATIC )))
4558 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4560 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4565 //=============================================================================
4567 * Returns true if given element is polygon
4569 //=============================================================================
4571 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4574 _preMeshInfo->FullLoadFromFile();
4576 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4577 if ( aSMESHDS_Mesh == NULL ) return false;
4578 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4579 if(!elem) return false;
4580 return elem->IsPoly();
4584 //=============================================================================
4586 * Returns true if given element is quadratic
4588 //=============================================================================
4590 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4593 _preMeshInfo->FullLoadFromFile();
4595 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4596 if ( aSMESHDS_Mesh == NULL ) return false;
4597 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4598 if(!elem) return false;
4599 return elem->IsQuadratic();
4602 //=============================================================================
4604 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4606 //=============================================================================
4608 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4611 _preMeshInfo->FullLoadFromFile();
4613 if ( const SMDS_BallElement* ball =
4614 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4615 return ball->GetDiameter();
4620 //=============================================================================
4622 * Returns bary center for given element
4624 //=============================================================================
4626 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4629 _preMeshInfo->FullLoadFromFile();
4631 SMESH::double_array_var aResult = new SMESH::double_array();
4632 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4633 if ( aSMESHDS_Mesh == NULL )
4634 return aResult._retn();
4636 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4638 return aResult._retn();
4640 if(elem->GetType()==SMDSAbs_Volume) {
4641 SMDS_VolumeTool aTool;
4642 if(aTool.Set(elem)) {
4644 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4649 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4651 double x=0., y=0., z=0.;
4652 for(; anIt->more(); ) {
4654 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4668 return aResult._retn();
4671 //================================================================================
4673 * \brief Create a group of elements preventing computation of a sub-shape
4675 //================================================================================
4677 SMESH::ListOfGroups*
4678 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4679 const char* theGroupName )
4680 throw ( SALOME::SALOME_Exception )
4682 Unexpect aCatch(SALOME_SalomeException);
4684 if ( !theGroupName || strlen( theGroupName) == 0 )
4685 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4687 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4689 // submesh by subshape id
4690 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4691 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4694 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4695 if ( error && !error->myBadElements.empty())
4697 // sort bad elements by type
4698 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4699 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4700 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4701 for ( ; elemIt != elemEnd; ++elemIt )
4703 const SMDS_MeshElement* elem = *elemIt;
4704 if ( !elem ) continue;
4706 if ( elem->GetID() < 1 )
4708 // elem is a temporary element, make a real element
4709 vector< const SMDS_MeshNode* > nodes;
4710 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4711 while ( nIt->more() && elem )
4713 nodes.push_back( nIt->next() );
4714 if ( nodes.back()->GetID() < 1 )
4715 elem = 0; // a temporary element on temporary nodes
4719 ::SMESH_MeshEditor editor( _impl );
4720 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4724 elemsByType[ elem->GetType() ].push_back( elem );
4727 // how many groups to create?
4729 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4730 nbTypes += int( !elemsByType[ i ].empty() );
4731 groups->length( nbTypes );
4734 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4736 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4737 if ( elems.empty() ) continue;
4739 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4740 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4742 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4743 SMESH::SMESH_Mesh_var mesh = _this();
4744 SALOMEDS::SObject_wrap aSO =
4745 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4746 GEOM::GEOM_Object::_nil(), theGroupName);
4748 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4749 if ( !grp_i ) continue;
4751 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4752 for ( size_t iE = 0; iE < elems.size(); ++iE )
4753 grpDS->SMDSGroup().Add( elems[ iE ]);
4758 return groups._retn();
4761 //=============================================================================
4763 * Create and publish group servants if any groups were imported or created anyhow
4765 //=============================================================================
4767 void SMESH_Mesh_i::CreateGroupServants()
4769 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4770 SMESH::SMESH_Mesh_var aMesh = _this();
4773 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4774 while ( groupIt->more() )
4776 ::SMESH_Group* group = groupIt->next();
4777 int anId = group->GetGroupDS()->GetID();
4779 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4780 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4782 addedIDs.insert( anId );
4784 SMESH_GroupBase_i* aGroupImpl;
4786 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4787 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4789 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4790 shape = groupOnGeom->GetShape();
4793 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4796 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4797 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4798 aGroupImpl->Register();
4800 // register CORBA object for persistence
4801 int nextId = _gen_i->RegisterObject( groupVar );
4802 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4803 else { nextId = 0; } // avoid "unused variable" warning in release mode
4805 // publishing the groups in the study
4806 if ( !aStudy->_is_nil() ) {
4807 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4808 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4811 if ( !addedIDs.empty() )
4814 set<int>::iterator id = addedIDs.begin();
4815 for ( ; id != addedIDs.end(); ++id )
4817 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4818 int i = std::distance( _mapGroups.begin(), it );
4819 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4824 //=============================================================================
4826 * \brief Return groups cantained in _mapGroups by their IDs
4828 //=============================================================================
4830 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4832 int nbGroups = groupIDs.size();
4833 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4834 aList->length( nbGroups );
4836 list<int>::const_iterator ids = groupIDs.begin();
4837 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4839 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4840 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4841 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4843 aList->length( nbGroups );
4844 return aList._retn();
4847 //=============================================================================
4849 * \brief Return information about imported file
4851 //=============================================================================
4853 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4855 SMESH::MedFileInfo_var res( _medFileInfo );
4856 if ( !res.operator->() ) {
4857 res = new SMESH::MedFileInfo;
4859 res->fileSize = res->major = res->minor = res->release = -1;
4864 //=============================================================================
4866 * \brief Pass names of mesh groups from study to mesh DS
4868 //=============================================================================
4870 void SMESH_Mesh_i::checkGroupNames()
4872 int nbGrp = NbGroups();
4876 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4877 if ( aStudy->_is_nil() )
4878 return; // nothing to do
4880 SMESH::ListOfGroups* grpList = 0;
4881 // avoid dump of "GetGroups"
4883 // store python dump into a local variable inside local scope
4884 SMESH::TPythonDump pDump; // do not delete this line of code
4885 grpList = GetGroups();
4888 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
4889 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
4892 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
4893 if ( aGrpSO->_is_nil() )
4895 // correct name of the mesh group if necessary
4896 const char* guiName = aGrpSO->GetName();
4897 if ( strcmp(guiName, aGrp->GetName()) )
4898 aGrp->SetName( guiName );
4902 //=============================================================================
4904 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
4906 //=============================================================================
4907 void SMESH_Mesh_i::SetParameters(const char* theParameters)
4909 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
4913 //=============================================================================
4915 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
4917 //=============================================================================
4919 char* SMESH_Mesh_i::GetParameters()
4921 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
4924 //=============================================================================
4926 * \brief Returns list of notebook variables used for last Mesh operation
4928 //=============================================================================
4929 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
4931 SMESH::string_array_var aResult = new SMESH::string_array();
4932 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
4934 CORBA::String_var aParameters = GetParameters();
4935 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
4936 if ( !aStudy->_is_nil()) {
4937 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
4938 if(aSections->length() > 0) {
4939 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
4940 aResult->length(aVars.length());
4941 for(int i = 0;i < aVars.length();i++)
4942 aResult[i] = CORBA::string_dup( aVars[i]);
4946 return aResult._retn();
4949 //=======================================================================
4950 //function : GetTypes
4951 //purpose : Returns types of elements it contains
4952 //=======================================================================
4954 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
4957 return _preMeshInfo->GetTypes();
4959 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
4963 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
4964 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
4965 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
4966 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
4967 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
4968 types->length( nbTypes );
4970 return types._retn();
4973 //=======================================================================
4974 //function : GetMesh
4975 //purpose : Returns self
4976 //=======================================================================
4978 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
4980 return SMESH::SMESH_Mesh::_duplicate( _this() );
4983 //=======================================================================
4984 //function : IsMeshInfoCorrect
4985 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
4986 // * happen if mesh data is not yet fully loaded from the file of study.
4987 //=======================================================================
4989 bool SMESH_Mesh_i::IsMeshInfoCorrect()
4991 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
4994 //=============================================================================
4996 * \brief Returns number of mesh elements per each \a EntityType
4998 //=============================================================================
5000 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5003 return _preMeshInfo->GetMeshInfo();
5005 SMESH::long_array_var aRes = new SMESH::long_array();
5006 aRes->length(SMESH::Entity_Last);
5007 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5009 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5011 return aRes._retn();
5012 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5013 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5014 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5015 return aRes._retn();
5018 //=============================================================================
5020 * \brief Returns number of mesh elements per each \a ElementType
5022 //=============================================================================
5024 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5026 SMESH::long_array_var aRes = new SMESH::long_array();
5027 aRes->length(SMESH::NB_ELEMENT_TYPES);
5028 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5031 const SMDS_MeshInfo* meshInfo = 0;
5033 meshInfo = _preMeshInfo;
5034 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5035 meshInfo = & meshDS->GetMeshInfo();
5038 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5039 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5041 return aRes._retn();
5044 //=============================================================================
5046 * Collect statistic of mesh elements given by iterator
5048 //=============================================================================
5050 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5051 SMESH::long_array& theInfo)
5053 if (!theItr) return;
5054 while (theItr->more())
5055 theInfo[ theItr->next()->GetEntityType() ]++;
5057 //=============================================================================
5059 * Returns mesh unstructed grid information.
5061 //=============================================================================
5063 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5065 SALOMEDS::TMPFile_var SeqFile;
5066 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5067 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5069 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5070 aWriter->WriteToOutputStringOn();
5071 aWriter->SetInputData(aGrid);
5072 aWriter->SetFileTypeToBinary();
5074 char* str = aWriter->GetOutputString();
5075 int size = aWriter->GetOutputStringLength();
5077 //Allocate octect buffer of required size
5078 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5079 //Copy ostrstream content to the octect buffer
5080 memcpy(OctetBuf, str, size);
5081 //Create and return TMPFile
5082 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5086 return SeqFile._retn();
5089 //=============================================================================
5090 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5091 * SMESH::ElementType type) */
5093 using namespace SMESH::Controls;
5094 //-----------------------------------------------------------------------------
5095 struct PredicateIterator : public SMDS_ElemIterator
5097 SMDS_ElemIteratorPtr _elemIter;
5098 PredicatePtr _predicate;
5099 const SMDS_MeshElement* _elem;
5101 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5102 PredicatePtr predicate):
5103 _elemIter(iterator), _predicate(predicate)
5111 virtual const SMDS_MeshElement* next()
5113 const SMDS_MeshElement* res = _elem;
5115 while ( _elemIter->more() && !_elem )
5117 _elem = _elemIter->next();
5118 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5125 //-----------------------------------------------------------------------------
5126 struct IDSourceIterator : public SMDS_ElemIterator
5128 const CORBA::Long* _idPtr;
5129 const CORBA::Long* _idEndPtr;
5130 SMESH::long_array_var _idArray;
5131 const SMDS_Mesh* _mesh;
5132 const SMDSAbs_ElementType _type;
5133 const SMDS_MeshElement* _elem;
5135 IDSourceIterator( const SMDS_Mesh* mesh,
5136 const CORBA::Long* ids,
5138 SMDSAbs_ElementType type):
5139 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5141 if ( _idPtr && nbIds && _mesh )
5144 IDSourceIterator( const SMDS_Mesh* mesh,
5145 SMESH::long_array* idArray,
5146 SMDSAbs_ElementType type):
5147 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5149 if ( idArray && _mesh )
5151 _idPtr = &_idArray[0];
5152 _idEndPtr = _idPtr + _idArray->length();
5160 virtual const SMDS_MeshElement* next()
5162 const SMDS_MeshElement* res = _elem;
5164 while ( _idPtr < _idEndPtr && !_elem )
5166 if ( _type == SMDSAbs_Node )
5168 _elem = _mesh->FindNode( *_idPtr++ );
5170 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5171 _elem->GetType() != _type )
5179 //-----------------------------------------------------------------------------
5181 struct NodeOfElemIterator : public SMDS_ElemIterator
5183 TColStd_MapOfInteger _checkedNodeIDs;
5184 SMDS_ElemIteratorPtr _elemIter;
5185 SMDS_ElemIteratorPtr _nodeIter;
5186 const SMDS_MeshElement* _node;
5188 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5190 if ( _elemIter && _elemIter->more() )
5192 _nodeIter = _elemIter->next()->nodesIterator();
5200 virtual const SMDS_MeshElement* next()
5202 const SMDS_MeshElement* res = _node;
5204 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5206 if ( _nodeIter->more() )
5208 _node = _nodeIter->next();
5209 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5214 _nodeIter = _elemIter->next()->nodesIterator();
5222 //=============================================================================
5224 * Return iterator on elements of given type in given object
5226 //=============================================================================
5228 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5229 SMESH::ElementType theType)
5231 SMDS_ElemIteratorPtr elemIt;
5232 bool typeOK = false;
5233 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5235 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5236 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5237 if ( !mesh_i ) return elemIt;
5238 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5240 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5242 elemIt = meshDS->elementsIterator( elemType );
5245 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5247 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5250 elemIt = sm->GetElements();
5251 if ( elemType != SMDSAbs_Node )
5253 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5254 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5258 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5260 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5261 if ( groupDS && ( groupDS->GetType() == elemType || elemType == SMDSAbs_Node ))
5263 elemIt = groupDS->GetElements();
5264 typeOK = ( groupDS->GetType() == elemType );
5267 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5269 if ( filter_i->GetElementType() == theType || elemType == SMDSAbs_Node )
5271 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5272 if ( pred_i && pred_i->GetPredicate() )
5274 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5275 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5276 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5277 typeOK = ( filterType == elemType );
5283 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5284 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5285 if ( isNodes && elemType != SMDSAbs_Node )
5287 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5290 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5291 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5295 SMESH::long_array_var ids = theObject->GetIDs();
5296 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5298 typeOK = ( isNodes == ( elemType == SMDSAbs_Node ));
5301 if ( elemIt && elemIt->more() && !typeOK )
5303 if ( elemType == SMDSAbs_Node )
5305 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5309 elemIt = SMDS_ElemIteratorPtr();
5315 //=============================================================================
5316 namespace // Finding concurrent hypotheses
5317 //=============================================================================
5321 * \brief mapping of mesh dimension into shape type
5323 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5325 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5327 case 0: aType = TopAbs_VERTEX; break;
5328 case 1: aType = TopAbs_EDGE; break;
5329 case 2: aType = TopAbs_FACE; break;
5331 default:aType = TopAbs_SOLID; break;
5336 //-----------------------------------------------------------------------------
5338 * \brief Internal structure used to find concurent submeshes
5340 * It represents a pair < submesh, concurent dimension >, where
5341 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5342 * with another submesh. In other words, it is dimension of a hypothesis assigned
5349 int _dim; //!< a dimension the algo can build (concurrent dimension)
5350 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5351 TopTools_MapOfShape _shapeMap;
5352 SMESH_subMesh* _subMesh;
5353 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5355 //-----------------------------------------------------------------------------
5356 // Return the algorithm
5357 const SMESH_Algo* GetAlgo() const
5358 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5360 //-----------------------------------------------------------------------------
5362 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5364 const TopoDS_Shape& theShape)
5366 _subMesh = (SMESH_subMesh*)theSubMesh;
5367 SetShape( theDim, theShape );
5370 //-----------------------------------------------------------------------------
5372 void SetShape(const int theDim,
5373 const TopoDS_Shape& theShape)
5376 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5377 if (_dim >= _ownDim)
5378 _shapeMap.Add( theShape );
5380 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5381 for( ; anExp.More(); anExp.Next() )
5382 _shapeMap.Add( anExp.Current() );
5386 //-----------------------------------------------------------------------------
5387 //! Check sharing of sub-shapes
5388 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5389 const TopTools_MapOfShape& theToFind,
5390 const TopAbs_ShapeEnum theType)
5392 bool isShared = false;
5393 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5394 for (; !isShared && anItr.More(); anItr.Next() )
5396 const TopoDS_Shape aSubSh = anItr.Key();
5397 // check for case when concurrent dimensions are same
5398 isShared = theToFind.Contains( aSubSh );
5399 // check for sub-shape with concurrent dimension
5400 TopExp_Explorer anExp( aSubSh, theType );
5401 for ( ; !isShared && anExp.More(); anExp.Next() )
5402 isShared = theToFind.Contains( anExp.Current() );
5407 //-----------------------------------------------------------------------------
5408 //! check algorithms
5409 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5410 const SMESHDS_Hypothesis* theA2)
5412 if ( !theA1 || !theA2 ||
5413 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5414 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5415 return false; // one of the hypothesis is not algorithm
5416 // check algorithm names (should be equal)
5417 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5421 //-----------------------------------------------------------------------------
5422 //! Check if sub-shape hypotheses are concurrent
5423 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5425 if ( _subMesh == theOther->_subMesh )
5426 return false; // same sub-shape - should not be
5428 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5429 // any of the two submeshes is not on COMPOUND shape )
5430 // -> no concurrency
5431 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5432 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5433 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5434 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5435 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5438 // bool checkSubShape = ( _dim >= theOther->_dim )
5439 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5440 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5441 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5442 if ( !checkSubShape )
5445 // check algorithms to be same
5446 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5447 return true; // different algorithms -> concurrency !
5449 // check hypothesises for concurrence (skip first as algorithm)
5451 // pointers should be same, because it is referened from mesh hypothesis partition
5452 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5453 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5454 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5455 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5457 // the submeshes are concurrent if their algorithms has different parameters
5458 return nbSame != theOther->_hypotheses.size() - 1;
5461 // Return true if algorithm of this SMESH_DimHyp is used if no
5462 // sub-mesh order is imposed by the user
5463 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5465 // NeedDiscreteBoundary() algo has a higher priority
5466 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5467 theOther->GetAlgo()->NeedDiscreteBoundary() )
5468 return !this->GetAlgo()->NeedDiscreteBoundary();
5470 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5473 }; // end of SMESH_DimHyp
5474 //-----------------------------------------------------------------------------
5476 typedef list<const SMESH_DimHyp*> TDimHypList;
5478 //-----------------------------------------------------------------------------
5480 void addDimHypInstance(const int theDim,
5481 const TopoDS_Shape& theShape,
5482 const SMESH_Algo* theAlgo,
5483 const SMESH_subMesh* theSubMesh,
5484 const list <const SMESHDS_Hypothesis*>& theHypList,
5485 TDimHypList* theDimHypListArr )
5487 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5488 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5489 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5490 dimHyp->_hypotheses.push_front(theAlgo);
5491 listOfdimHyp.push_back( dimHyp );
5494 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5495 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5496 theHypList.begin(), theHypList.end() );
5499 //-----------------------------------------------------------------------------
5500 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5501 TDimHypList& theListOfConcurr)
5503 if ( theListOfConcurr.empty() )
5505 theListOfConcurr.push_back( theDimHyp );
5509 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5510 while ( hypIt != theListOfConcurr.end() &&
5511 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5513 theListOfConcurr.insert( hypIt, theDimHyp );
5517 //-----------------------------------------------------------------------------
5518 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5519 const TDimHypList& theListOfDimHyp,
5520 TDimHypList& theListOfConcurrHyp,
5521 set<int>& theSetOfConcurrId )
5523 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5524 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5526 const SMESH_DimHyp* curDimHyp = *rIt;
5527 if ( curDimHyp == theDimHyp )
5528 break; // meet own dimHyp pointer in same dimension
5530 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5531 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5533 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5538 //-----------------------------------------------------------------------------
5539 void unionLists(TListOfInt& theListOfId,
5540 TListOfListOfInt& theListOfListOfId,
5543 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5544 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5546 continue; //skip already treated lists
5547 // check if other list has any same submesh object
5548 TListOfInt& otherListOfId = *it;
5549 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5550 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5553 // union two lists (from source into target)
5554 TListOfInt::iterator it2 = otherListOfId.begin();
5555 for ( ; it2 != otherListOfId.end(); it2++ ) {
5556 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5557 theListOfId.push_back(*it2);
5559 // clear source list
5560 otherListOfId.clear();
5563 //-----------------------------------------------------------------------------
5565 //! free memory allocated for dimension-hypothesis objects
5566 void removeDimHyps( TDimHypList* theArrOfList )
5568 for (int i = 0; i < 4; i++ ) {
5569 TDimHypList& listOfdimHyp = theArrOfList[i];
5570 TDimHypList::const_iterator it = listOfdimHyp.begin();
5571 for ( ; it != listOfdimHyp.end(); it++ )
5576 //-----------------------------------------------------------------------------
5578 * \brief find common submeshes with given submesh
5579 * \param theSubMeshList list of already collected submesh to check
5580 * \param theSubMesh given submesh to intersect with other
5581 * \param theCommonSubMeshes collected common submeshes
5583 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5584 const SMESH_subMesh* theSubMesh,
5585 set<const SMESH_subMesh*>& theCommon )
5589 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5590 for ( ; it != theSubMeshList.end(); it++ )
5591 theSubMesh->FindIntersection( *it, theCommon );
5592 theSubMeshList.push_back( theSubMesh );
5593 //theCommon.insert( theSubMesh );
5596 //-----------------------------------------------------------------------------
5597 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5599 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5600 for ( ; listsIt != smLists.end(); ++listsIt )
5602 const TListOfInt& smIDs = *listsIt;
5603 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5611 //=============================================================================
5613 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5615 //=============================================================================
5617 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5619 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5620 if ( isSubMeshInList( submeshID, anOrder ))
5623 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5624 return isSubMeshInList( submeshID, allConurrent );
5627 //=============================================================================
5629 * \brief Return submesh objects list in meshing order
5631 //=============================================================================
5633 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5635 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5637 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5639 return aResult._retn();
5641 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5642 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5643 anOrder.splice( anOrder.end(), allConurrent );
5646 TListOfListOfInt::iterator listIt = anOrder.begin();
5647 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5648 unionLists( *listIt, anOrder, listIndx + 1 );
5650 // convert submesh ids into interface instances
5651 // and dump command into python
5652 convertMeshOrder( anOrder, aResult, false );
5654 return aResult._retn();
5657 //=============================================================================
5659 * \brief Finds concurrent sub-meshes
5661 //=============================================================================
5663 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5665 TListOfListOfInt anOrder;
5666 ::SMESH_Mesh& mesh = GetImpl();
5668 // collect submeshes and detect concurrent algorithms and hypothesises
5669 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5671 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5672 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5673 ::SMESH_subMesh* sm = (*i_sm).second;
5675 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5677 // list of assigned hypothesises
5678 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5679 // Find out dimensions where the submesh can be concurrent.
5680 // We define the dimensions by algo of each of hypotheses in hypList
5681 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5682 for( ; hypIt != hypList.end(); hypIt++ ) {
5683 SMESH_Algo* anAlgo = 0;
5684 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5685 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5686 // hyp it-self is algo
5687 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5689 // try to find algorithm with help of sub-shapes
5690 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5691 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5692 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5695 continue; // no algorithm assigned to a current submesh
5697 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5698 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5700 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5701 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5702 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5704 } // end iterations on submesh
5706 // iterate on created dimension-hypotheses and check for concurrents
5707 for ( int i = 0; i < 4; i++ ) {
5708 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5709 // check for concurrents in own and other dimensions (step-by-step)
5710 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5711 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5712 const SMESH_DimHyp* dimHyp = *dhIt;
5713 TDimHypList listOfConcurr;
5714 set<int> setOfConcurrIds;
5715 // looking for concurrents and collect into own list
5716 for ( int j = i; j < 4; j++ )
5717 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5718 // check if any concurrents found
5719 if ( listOfConcurr.size() > 0 ) {
5720 // add own submesh to list of concurrent
5721 addInOrderOfPriority( dimHyp, listOfConcurr );
5722 list<int> listOfConcurrIds;
5723 TDimHypList::iterator hypIt = listOfConcurr.begin();
5724 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5725 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5726 anOrder.push_back( listOfConcurrIds );
5731 removeDimHyps(dimHypListArr);
5733 // now, minimise the number of concurrent groups
5734 // Here we assume that lists of submeshes can have same submesh
5735 // in case of multi-dimension algorithms, as result
5736 // list with common submesh has to be united into one list
5738 TListOfListOfInt::iterator listIt = anOrder.begin();
5739 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5740 unionLists( *listIt, anOrder, listIndx + 1 );
5746 //=============================================================================
5748 * \brief Set submesh object order
5749 * \param theSubMeshArray submesh array order
5751 //=============================================================================
5753 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5756 _preMeshInfo->ForgetOrLoad();
5759 ::SMESH_Mesh& mesh = GetImpl();
5761 TPythonDump aPythonDump; // prevent dump of called methods
5762 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5764 TListOfListOfInt subMeshOrder;
5765 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5767 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5768 TListOfInt subMeshIds;
5770 aPythonDump << ", ";
5771 aPythonDump << "[ ";
5772 // Collect subMeshes which should be clear
5773 // do it list-by-list, because modification of submesh order
5774 // take effect between concurrent submeshes only
5775 set<const SMESH_subMesh*> subMeshToClear;
5776 list<const SMESH_subMesh*> subMeshList;
5777 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5779 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5781 aPythonDump << ", ";
5782 aPythonDump << subMesh;
5783 subMeshIds.push_back( subMesh->GetId() );
5784 // detect common parts of submeshes
5785 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5786 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5788 aPythonDump << " ]";
5789 subMeshOrder.push_back( subMeshIds );
5791 // clear collected submeshes
5792 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5793 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5794 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5795 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5797 aPythonDump << " ])";
5799 mesh.SetMeshOrder( subMeshOrder );
5805 //=============================================================================
5807 * \brief Convert submesh ids into submesh interfaces
5809 //=============================================================================
5811 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5812 SMESH::submesh_array_array& theResOrder,
5813 const bool theIsDump)
5815 int nbSet = theIdsOrder.size();
5816 TPythonDump aPythonDump; // prevent dump of called methods
5818 aPythonDump << "[ ";
5819 theResOrder.length(nbSet);
5820 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5822 for( ; it != theIdsOrder.end(); it++ ) {
5823 // translate submesh identificators into submesh objects
5824 // takeing into account real number of concurrent lists
5825 const TListOfInt& aSubOrder = (*it);
5826 if (!aSubOrder.size())
5829 aPythonDump << "[ ";
5830 // convert shape indeces into interfaces
5831 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5832 aResSubSet->length(aSubOrder.size());
5833 TListOfInt::const_iterator subIt = aSubOrder.begin();
5835 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5836 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5838 SMESH::SMESH_subMesh_var subMesh =
5839 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5842 aPythonDump << ", ";
5843 aPythonDump << subMesh;
5845 aResSubSet[ j++ ] = subMesh;
5848 aPythonDump << " ]";
5850 theResOrder[ listIndx++ ] = aResSubSet;
5852 // correct number of lists
5853 theResOrder.length( listIndx );
5856 // finilise python dump
5857 aPythonDump << " ]";
5858 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5862 //================================================================================
5864 // Implementation of SMESH_MeshPartDS
5866 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
5867 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
5869 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
5870 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
5872 _meshDS = mesh_i->GetImpl().GetMeshDS();
5874 SetPersistentId( _meshDS->GetPersistentId() );
5876 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
5878 // <meshPart> is the whole mesh
5879 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
5881 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
5882 myGroupSet = _meshDS->GetGroups();
5887 SMESH::long_array_var anIDs = meshPart->GetIDs();
5888 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
5889 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
5891 for (int i=0; i < anIDs->length(); i++)
5892 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
5893 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5898 for (int i=0; i < anIDs->length(); i++)
5899 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
5900 if ( _elements[ e->GetType() ].insert( e ).second )
5903 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5904 while ( nIt->more() )
5906 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5907 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5914 _meshDS = 0; // to enforce iteration on _elements and _nodes
5917 // -------------------------------------------------------------------------------------
5918 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
5919 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
5922 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
5923 for ( ; partIt != meshPart.end(); ++partIt )
5924 if ( const SMDS_MeshElement * e = *partIt )
5925 if ( _elements[ e->GetType() ].insert( e ).second )
5928 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
5929 while ( nIt->more() )
5931 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
5932 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
5938 // -------------------------------------------------------------------------------------
5939 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
5941 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
5943 typedef SMDS_SetIterator
5944 <const SMDS_MeshElement*,
5945 TIDSortedElemSet::const_iterator,
5946 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5947 SMDS_MeshElement::GeomFilter
5950 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
5952 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5953 _elements[type].end(),
5954 SMDS_MeshElement::GeomFilter( geomType )));
5956 // -------------------------------------------------------------------------------------
5957 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
5959 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
5961 typedef SMDS_SetIterator
5962 <const SMDS_MeshElement*,
5963 TIDSortedElemSet::const_iterator,
5964 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
5965 SMDS_MeshElement::EntityFilter
5968 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
5970 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
5971 _elements[type].end(),
5972 SMDS_MeshElement::EntityFilter( entity )));
5974 // -------------------------------------------------------------------------------------
5975 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
5977 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
5978 if ( type == SMDSAbs_All && !_meshDS )
5980 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
5982 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
5983 if ( !_elements[i].empty() && i != SMDSAbs_Node )
5985 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
5987 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
5988 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
5990 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
5991 ( new TIter( _elements[type].begin(), _elements[type].end() ));
5993 // -------------------------------------------------------------------------------------
5994 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
5995 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
5997 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
5998 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
5999 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6001 // -------------------------------------------------------------------------------------
6002 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6003 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6004 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6005 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6006 #undef _GET_ITER_DEFINE
6008 // END Implementation of SMESH_MeshPartDS
6010 //================================================================================