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 );
1060 aGroup->Modified(/*removed=*/true); // notify dependent Filter with FT_BelongToMeshGroup criterion
1062 // Remove the group from SMESH data structures
1063 removeGroup( aGroup->GetLocalID() );
1065 SMESH_CATCH( SMESH::throwCorbaException );
1068 //=============================================================================
1070 * Remove group with its contents
1072 //=============================================================================
1074 void SMESH_Mesh_i::RemoveGroupWithContents( SMESH::SMESH_GroupBase_ptr theGroup )
1075 throw (SALOME::SALOME_Exception)
1079 _preMeshInfo->FullLoadFromFile();
1081 if ( theGroup->_is_nil() )
1084 vector<int> nodeIds; // to remove nodes becoming free
1085 if ( !theGroup->IsEmpty() )
1087 CORBA::Long elemID = theGroup->GetID( 1 );
1088 int nbElemNodes = GetElemNbNodes( elemID );
1089 if ( nbElemNodes > 0 )
1090 nodeIds.reserve( theGroup->Size() * nbElemNodes );
1094 SMESH::SMESH_IDSource_var idSrc = SMESH::SMESH_IDSource::_narrow( theGroup );
1095 SMDS_ElemIteratorPtr elemIt = GetElements( idSrc, theGroup->GetType() );
1096 while ( elemIt->more() )
1098 const SMDS_MeshElement* e = elemIt->next();
1100 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
1101 while ( nIt->more() )
1102 nodeIds.push_back( nIt->next()->GetID() );
1104 _impl->GetMeshDS()->RemoveElement( e );
1107 // Remove free nodes
1108 if ( theGroup->GetType() != SMESH::NODE )
1109 for ( size_t i = 0 ; i < nodeIds.size(); ++i )
1110 if ( const SMDS_MeshNode* n = _impl->GetMeshDS()->FindNode( nodeIds[i] ))
1111 if ( n->NbInverseElements() == 0 )
1112 _impl->GetMeshDS()->RemoveFreeNode( n, /*sm=*/0 );
1114 TPythonDump pyDump; // Supress dump from RemoveGroup()
1116 // Update Python script (theGroup must be alive for this)
1117 pyDump << SMESH::SMESH_Mesh_var(_this())
1118 << ".RemoveGroupWithContents( " << theGroup << " )";
1121 RemoveGroup( theGroup );
1123 SMESH_CATCH( SMESH::throwCorbaException );
1126 //================================================================================
1128 * \brief Get the list of groups existing in the mesh
1129 * \retval SMESH::ListOfGroups * - list of groups
1131 //================================================================================
1133 SMESH::ListOfGroups * SMESH_Mesh_i::GetGroups() throw(SALOME::SALOME_Exception)
1135 Unexpect aCatch(SALOME_SalomeException);
1136 if (MYDEBUG) MESSAGE("GetGroups");
1138 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
1141 TPythonDump aPythonDump;
1142 if ( !_mapGroups.empty() )
1144 aPythonDump << "[ ";
1146 aList->length( _mapGroups.size() );
1148 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
1149 for ( ; it != _mapGroups.end(); it++ ) {
1150 if ( CORBA::is_nil( it->second )) continue;
1151 aList[i++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
1153 if (i > 1) aPythonDump << ", ";
1154 aPythonDump << it->second;
1158 catch(SALOME_Exception & S_ex) {
1159 THROW_SALOME_CORBA_EXCEPTION(S_ex.what(), SALOME::BAD_PARAM);
1161 aPythonDump << " ] = " << SMESH::SMESH_Mesh_var(_this()) << ".GetGroups()";
1163 return aList._retn();
1166 //=============================================================================
1168 * Get number of groups existing in the mesh
1170 //=============================================================================
1172 CORBA::Long SMESH_Mesh_i::NbGroups() throw (SALOME::SALOME_Exception)
1174 Unexpect aCatch(SALOME_SalomeException);
1175 return _mapGroups.size();
1178 //=============================================================================
1180 * New group including all mesh elements present in initial groups is created.
1182 //=============================================================================
1184 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1185 SMESH::SMESH_GroupBase_ptr theGroup2,
1186 const char* theName )
1187 throw (SALOME::SALOME_Exception)
1189 SMESH::SMESH_Group_var aResGrp;
1193 _preMeshInfo->FullLoadFromFile();
1195 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1196 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): NULL Group",
1198 if ( theGroup1->GetType() != theGroup2->GetType() )
1199 THROW_SALOME_CORBA_EXCEPTION("UnionGroups(): different group types",
1204 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1205 if ( aResGrp->_is_nil() )
1206 return SMESH::SMESH_Group::_nil();
1208 aResGrp->AddFrom( theGroup1 );
1209 aResGrp->AddFrom( theGroup2 );
1211 // Update Python script
1212 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this())
1213 << ".UnionGroups( " << theGroup1 << ", " << theGroup2 << ", '" << theName << "' )";
1215 SMESH_CATCH( SMESH::throwCorbaException );
1217 return aResGrp._retn();
1220 //=============================================================================
1222 * \brief New group including all mesh elements present in initial groups is created.
1223 * \param theGroups list of groups
1224 * \param theName name of group to be created
1225 * \return pointer to the new group
1227 //=============================================================================
1229 SMESH::SMESH_Group_ptr SMESH_Mesh_i::UnionListOfGroups(const SMESH::ListOfGroups& theGroups,
1230 const char* theName )
1231 throw (SALOME::SALOME_Exception)
1233 SMESH::SMESH_Group_var aResGrp;
1236 _preMeshInfo->FullLoadFromFile();
1239 return SMESH::SMESH_Group::_nil();
1244 SMESH::ElementType aType = SMESH::ALL;
1245 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1247 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1248 if ( CORBA::is_nil( aGrp ) )
1250 if ( aType == SMESH::ALL )
1251 aType = aGrp->GetType();
1252 else if ( aType != aGrp->GetType() )
1253 THROW_SALOME_CORBA_EXCEPTION("UnionListOfGroups(): different group types",
1256 if ( aType == SMESH::ALL )
1257 return SMESH::SMESH_Group::_nil();
1262 aResGrp = CreateGroup( aType, theName );
1263 if ( aResGrp->_is_nil() )
1264 return SMESH::SMESH_Group::_nil();
1266 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".UnionListOfGroups([ ";
1267 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1269 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1270 if ( !CORBA::is_nil( aGrp ) )
1272 aResGrp->AddFrom( aGrp );
1273 if ( g > 0 ) pyDump << ", ";
1277 pyDump << " ], '" << theName << "' )";
1279 SMESH_CATCH( SMESH::throwCorbaException );
1281 return aResGrp._retn();
1284 //=============================================================================
1286 * New group is created. All mesh elements that are
1287 * present in both initial groups are added to the new one.
1289 //=============================================================================
1291 SMESH::SMESH_Group_ptr SMESH_Mesh_i::IntersectGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1292 SMESH::SMESH_GroupBase_ptr theGroup2,
1293 const char* theName )
1294 throw (SALOME::SALOME_Exception)
1296 SMESH::SMESH_Group_var aResGrp;
1301 _preMeshInfo->FullLoadFromFile();
1303 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1304 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): NULL Group",
1306 if ( theGroup1->GetType() != theGroup2->GetType() )
1307 THROW_SALOME_CORBA_EXCEPTION("IntersectGroups(): different group types",
1311 // Create Intersection
1312 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1313 if ( aResGrp->_is_nil() )
1314 return aResGrp._retn();
1316 SMESHDS_GroupBase* groupDS1 = 0;
1317 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1318 groupDS1 = grp_i->GetGroupDS();
1320 SMESHDS_GroupBase* groupDS2 = 0;
1321 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1322 groupDS2 = grp_i->GetGroupDS();
1324 SMESHDS_Group* resGroupDS = 0;
1325 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1326 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1328 if ( groupDS1 && groupDS2 && resGroupDS && !groupDS2->IsEmpty() )
1330 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1331 while ( elemIt1->more() )
1333 const SMDS_MeshElement* e = elemIt1->next();
1334 if ( groupDS2->Contains( e ))
1335 resGroupDS->SMDSGroup().Add( e );
1338 // Update Python script
1339 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".IntersectGroups( "
1340 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1342 SMESH_CATCH( SMESH::throwCorbaException );
1344 return aResGrp._retn();
1347 //=============================================================================
1349 \brief Intersect list of groups. New group is created. All mesh elements that
1350 are present in all initial groups simultaneously are added to the new one.
1351 \param theGroups list of groups
1352 \param theName name of group to be created
1353 \return pointer on the group
1355 //=============================================================================
1356 SMESH::SMESH_Group_ptr
1357 SMESH_Mesh_i::IntersectListOfGroups(const SMESH::ListOfGroups& theGroups,
1358 const char* theName )
1359 throw (SALOME::SALOME_Exception)
1361 SMESH::SMESH_Group_var aResGrp;
1366 _preMeshInfo->FullLoadFromFile();
1369 return SMESH::SMESH_Group::_nil();
1371 // check types and get SMESHDS_GroupBase's
1372 SMESH::ElementType aType = SMESH::ALL;
1373 vector< SMESHDS_GroupBase* > groupVec;
1374 for ( int g = 0, n = theGroups.length(); g < n; g++ )
1376 SMESH::SMESH_GroupBase_var aGrp = theGroups[ g ];
1377 if ( CORBA::is_nil( aGrp ) )
1379 if ( aType == SMESH::ALL )
1380 aType = aGrp->GetType();
1381 else if ( aType != aGrp->GetType() )
1382 THROW_SALOME_CORBA_EXCEPTION("IntersectListOfGroups(): different group types",
1385 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1386 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1388 if ( grpDS->IsEmpty() )
1393 groupVec.push_back( grpDS );
1396 if ( aType == SMESH::ALL ) // all groups are nil
1397 return SMESH::SMESH_Group::_nil();
1402 aResGrp = CreateGroup( aType, theName );
1404 SMESHDS_Group* resGroupDS = 0;
1405 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1406 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1407 if ( !resGroupDS || groupVec.empty() )
1408 return aResGrp._retn();
1411 size_t i, nb = groupVec.size();
1412 SMDS_ElemIteratorPtr elemIt1 = groupVec[0]->GetElements();
1413 while ( elemIt1->more() )
1415 const SMDS_MeshElement* e = elemIt1->next();
1417 for ( i = 1; ( i < nb && inAll ); ++i )
1418 inAll = groupVec[i]->Contains( e );
1421 resGroupDS->SMDSGroup().Add( e );
1424 // Update Python script
1425 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1426 << ".IntersectListOfGroups( " << theGroups << ", '" << theName << "' )";
1428 SMESH_CATCH( SMESH::throwCorbaException );
1430 return aResGrp._retn();
1433 //=============================================================================
1435 * New group is created. All mesh elements that are present in
1436 * a main group but is not present in a tool group are added to the new one
1438 //=============================================================================
1440 SMESH::SMESH_Group_ptr SMESH_Mesh_i::CutGroups( SMESH::SMESH_GroupBase_ptr theGroup1,
1441 SMESH::SMESH_GroupBase_ptr theGroup2,
1442 const char* theName )
1443 throw (SALOME::SALOME_Exception)
1445 SMESH::SMESH_Group_var aResGrp;
1450 _preMeshInfo->FullLoadFromFile();
1452 if ( theGroup1->_is_nil() || theGroup2->_is_nil() )
1453 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): NULL Group",
1455 if ( theGroup1->GetType() != theGroup2->GetType() )
1456 THROW_SALOME_CORBA_EXCEPTION("CutGroups(): different group types",
1460 aResGrp = CreateGroup( theGroup1->GetType(), theName );
1461 if ( aResGrp->_is_nil() )
1462 return aResGrp._retn();
1464 SMESHDS_GroupBase* groupDS1 = 0;
1465 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup1 ))
1466 groupDS1 = grp_i->GetGroupDS();
1468 SMESHDS_GroupBase* groupDS2 = 0;
1469 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( theGroup2 ))
1470 groupDS2 = grp_i->GetGroupDS();
1472 SMESHDS_Group* resGroupDS = 0;
1473 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1474 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1476 if ( groupDS1 && groupDS2 && resGroupDS )
1478 SMDS_ElemIteratorPtr elemIt1 = groupDS1->GetElements();
1479 while ( elemIt1->more() )
1481 const SMDS_MeshElement* e = elemIt1->next();
1482 if ( !groupDS2->Contains( e ))
1483 resGroupDS->SMDSGroup().Add( e );
1486 // Update Python script
1487 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var(_this()) << ".CutGroups( "
1488 << theGroup1 << ", " << theGroup2 << ", '" << theName << "')";
1490 SMESH_CATCH( SMESH::throwCorbaException );
1492 return aResGrp._retn();
1495 //=============================================================================
1497 \brief Cut lists of groups. New group is created. All mesh elements that are
1498 present in main groups but do not present in tool groups are added to the new one
1499 \param theMainGroups list of main groups
1500 \param theToolGroups list of tool groups
1501 \param theName name of group to be created
1502 \return pointer on the group
1504 //=============================================================================
1505 SMESH::SMESH_Group_ptr
1506 SMESH_Mesh_i::CutListOfGroups(const SMESH::ListOfGroups& theMainGroups,
1507 const SMESH::ListOfGroups& theToolGroups,
1508 const char* theName )
1509 throw (SALOME::SALOME_Exception)
1511 SMESH::SMESH_Group_var aResGrp;
1516 _preMeshInfo->FullLoadFromFile();
1519 return SMESH::SMESH_Group::_nil();
1521 // check types and get SMESHDS_GroupBase's
1522 SMESH::ElementType aType = SMESH::ALL;
1523 vector< SMESHDS_GroupBase* > toolGroupVec;
1524 vector< SMDS_ElemIteratorPtr > mainIterVec;
1526 for ( int g = 0, n = theMainGroups.length(); g < n; g++ )
1528 SMESH::SMESH_GroupBase_var aGrp = theMainGroups[ g ];
1529 if ( CORBA::is_nil( aGrp ) )
1531 if ( aType == SMESH::ALL )
1532 aType = aGrp->GetType();
1533 else if ( aType != aGrp->GetType() )
1534 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1536 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1537 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1538 if ( !grpDS->IsEmpty() )
1539 mainIterVec.push_back( grpDS->GetElements() );
1541 if ( aType == SMESH::ALL ) // all main groups are nil
1542 return SMESH::SMESH_Group::_nil();
1543 if ( mainIterVec.empty() ) // all main groups are empty
1544 return aResGrp._retn();
1546 for ( int g = 0, n = theToolGroups.length(); g < n; g++ )
1548 SMESH::SMESH_GroupBase_var aGrp = theToolGroups[ g ];
1549 if ( CORBA::is_nil( aGrp ) )
1551 if ( aType != aGrp->GetType() )
1552 THROW_SALOME_CORBA_EXCEPTION("CutListOfGroups(): different group types",
1554 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aGrp ))
1555 if ( SMESHDS_GroupBase* grpDS = grp_i->GetGroupDS() )
1556 toolGroupVec.push_back( grpDS );
1562 aResGrp = CreateGroup( aType, theName );
1564 SMESHDS_Group* resGroupDS = 0;
1565 if ( SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( aResGrp ))
1566 resGroupDS = dynamic_cast<SMESHDS_Group*>( grp_i->GetGroupDS() );
1568 return aResGrp._retn();
1571 size_t i, nb = toolGroupVec.size();
1572 SMDS_ElemIteratorPtr mainElemIt
1573 ( new SMDS_IteratorOnIterators
1574 < const SMDS_MeshElement*, vector< SMDS_ElemIteratorPtr > >( mainIterVec ));
1575 while ( mainElemIt->more() )
1577 const SMDS_MeshElement* e = mainElemIt->next();
1579 for ( i = 0; ( i < nb && !isIn ); ++i )
1580 isIn = toolGroupVec[i]->Contains( e );
1583 resGroupDS->SMDSGroup().Add( e );
1586 // Update Python script
1587 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this() )
1588 << ".CutListOfGroups( " << theMainGroups << ", "
1589 << theToolGroups << ", '" << theName << "' )";
1591 SMESH_CATCH( SMESH::throwCorbaException );
1593 return aResGrp._retn();
1596 namespace // functions making checks according to SMESH::NB_COMMON_NODES_ENUM
1598 bool isAllNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1599 bool & toStopChecking )
1601 toStopChecking = ( nbCommon < nbChecked );
1602 return nbCommon == nbNodes;
1604 bool isMainNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1605 bool & toStopChecking )
1607 toStopChecking = ( nbCommon < nbChecked || nbChecked >= nbCorners );
1608 return nbCommon == nbCorners;
1610 bool isAtLeastOneNodeCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1611 bool & toStopChecking )
1613 return nbCommon > 0;
1615 bool isMajorityOfNodesCommon(int nbChecked, int nbCommon, int nbNodes, int nbCorners,
1616 bool & toStopChecking )
1618 return nbCommon >= nbNodes / 2;
1622 //=============================================================================
1624 * Create a group of entities basing on nodes of other groups.
1625 * \param [in] theGroups - list of either groups, sub-meshes or filters.
1626 * \param [in] anElemType - a type of elements to include to the new group.
1627 * \param [in] theName - a name of the new group.
1628 * \param [in] theNbCommonNodes - criterion of inclusion of an element to the new group.
1629 * \param [in] theUnderlyingOnly - if \c True, an element is included to the
1630 * new group provided that it is based on nodes of an element of \a aListOfGroups
1631 * \return SMESH_Group - the created group
1633 // IMP 19939, bug 22010, IMP 22635
1634 //=============================================================================
1636 SMESH::SMESH_Group_ptr
1637 SMESH_Mesh_i::CreateDimGroup(const SMESH::ListOfIDSources& theGroups,
1638 SMESH::ElementType theElemType,
1639 const char* theName,
1640 SMESH::NB_COMMON_NODES_ENUM theNbCommonNodes,
1641 CORBA::Boolean theUnderlyingOnly)
1642 throw (SALOME::SALOME_Exception)
1644 SMESH::SMESH_Group_var aResGrp;
1648 _preMeshInfo->FullLoadFromFile();
1650 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
1652 if ( !theName || !aMeshDS )
1653 return SMESH::SMESH_Group::_nil();
1655 SMDSAbs_ElementType anElemType = (SMDSAbs_ElementType)theElemType;
1657 bool (*isToInclude)(int nbChecked, int nbCommon, int nbNodes, int nbCorners, bool & toStop);
1658 SMESH_Comment nbCoNoStr( "SMESH.");
1659 switch ( theNbCommonNodes ) {
1660 case SMESH::ALL_NODES : isToInclude = isAllNodesCommon; nbCoNoStr<<"ALL_NODES" ;break;
1661 case SMESH::MAIN : isToInclude = isMainNodesCommon; nbCoNoStr<<"MAIN" ;break;
1662 case SMESH::AT_LEAST_ONE: isToInclude = isAtLeastOneNodeCommon; nbCoNoStr<<"AT_LEAST_ONE";break;
1663 case SMESH::MAJORITY : isToInclude = isMajorityOfNodesCommon; nbCoNoStr<<"MAJORITY" ;break;
1664 default: return aResGrp._retn();
1666 int nbChecked, nbCommon, nbNodes, nbCorners;
1672 aResGrp = CreateGroup( theElemType, theName );
1673 if ( aResGrp->_is_nil() )
1674 return SMESH::SMESH_Group::_nil();
1676 SMESHDS_GroupBase* groupBaseDS =
1677 SMESH::DownCast<SMESH_GroupBase_i*>( aResGrp )->GetGroupDS();
1678 SMDS_MeshGroup& resGroupCore = static_cast< SMESHDS_Group* >( groupBaseDS )->SMDSGroup();
1680 vector<bool> isNodeInGroups;
1682 for ( int g = 0, n = theGroups.length(); g < n; g++ ) // loop on theGroups
1684 SMESH::SMESH_IDSource_var aGrp = theGroups[ g ];
1685 if ( CORBA::is_nil( aGrp ) )
1687 SMESH::SMESH_Mesh_var mesh = aGrp->GetMesh();
1688 if ( mesh->_is_nil() || mesh->GetId() != this->GetId() )
1691 SMDS_ElemIteratorPtr elIt = GetElements( aGrp, SMESH::ALL );
1692 if ( !elIt ) continue;
1694 if ( theElemType == SMESH::NODE ) // get all nodes of elements
1696 while ( elIt->more() ) {
1697 const SMDS_MeshElement* el = elIt->next();
1698 SMDS_ElemIteratorPtr nIt = el->nodesIterator();
1699 while ( nIt->more() )
1700 resGroupCore.Add( nIt->next() );
1703 // get elements of theElemType based on nodes of every element of group
1704 else if ( theUnderlyingOnly )
1706 while ( elIt->more() )
1708 const SMDS_MeshElement* el = elIt->next(); // an element of ref group
1709 TIDSortedElemSet elNodes( el->begin_nodes(), el->end_nodes() );
1710 TIDSortedElemSet checkedElems;
1711 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1712 while ( nIt->more() )
1714 const SMDS_MeshNode* n = nIt->next();
1715 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1716 // check nodes of elements of theElemType around el
1717 while ( elOfTypeIt->more() )
1719 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1720 if ( !checkedElems.insert( elOfType ).second ) continue;
1721 nbNodes = elOfType->NbNodes();
1722 nbCorners = elOfType->NbCornerNodes();
1724 bool toStopChecking = false;
1725 SMDS_ElemIteratorPtr nIt2 = elOfType->nodesIterator();
1726 for ( nbChecked = 1; nIt2->more() && !toStopChecking; ++nbChecked )
1727 if ( elNodes.count( nIt2->next() ) &&
1728 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1730 resGroupCore.Add( elOfType );
1737 // get all nodes of elements of groups
1740 while ( elIt->more() )
1742 const SMDS_MeshElement* el = elIt->next(); // an element of group
1743 SMDS_NodeIteratorPtr nIt = el->nodeIterator();
1744 while ( nIt->more() )
1746 const SMDS_MeshNode* n = nIt->next();
1747 if ( n->GetID() >= isNodeInGroups.size() )
1748 isNodeInGroups.resize( n->GetID() + 1, false );
1749 isNodeInGroups[ n->GetID() ] = true;
1755 // Get elements of theElemType based on a certain number of nodes of elements of groups
1756 if ( !theUnderlyingOnly && !isNodeInGroups.empty() )
1758 const SMDS_MeshNode* n;
1759 vector<bool> isElemChecked( aMeshDS->MaxElementID() + 1 );
1760 const int isNodeInGroupsSize = isNodeInGroups.size();
1761 for ( int iN = 0; iN < isNodeInGroupsSize; ++iN )
1763 if ( !isNodeInGroups[ iN ] ||
1764 !( n = aMeshDS->FindNode( iN )))
1767 // check nodes of elements of theElemType around n
1768 SMDS_ElemIteratorPtr elOfTypeIt = n->GetInverseElementIterator( anElemType );
1769 while ( elOfTypeIt->more() )
1771 const SMDS_MeshElement* elOfType = elOfTypeIt->next();
1772 vector<bool>::reference isChecked = isElemChecked[ elOfType->GetID() ];
1777 nbNodes = elOfType->NbNodes();
1778 nbCorners = elOfType->NbCornerNodes();
1780 bool toStopChecking = false;
1781 SMDS_ElemIteratorPtr nIt = elOfType->nodesIterator();
1782 for ( nbChecked = 1; nIt->more() && !toStopChecking; ++nbChecked )
1784 const int nID = nIt->next()->GetID();
1785 if ( nID < isNodeInGroupsSize && isNodeInGroups[ nID ] &&
1786 isToInclude( nbChecked, ++nbCommon, nbNodes, nbCorners, toStopChecking ))
1788 resGroupCore.Add( elOfType );
1796 // Update Python script
1797 pyDump << aResGrp << " = " << SMESH::SMESH_Mesh_var( _this())
1798 << ".CreateDimGroup( "
1799 << theGroups << ", " << theElemType << ", '" << theName << "', "
1800 << nbCoNoStr << ", " << theUnderlyingOnly << ")";
1802 SMESH_CATCH( SMESH::throwCorbaException );
1804 return aResGrp._retn();
1807 //================================================================================
1809 * \brief Remember GEOM group data
1811 //================================================================================
1813 void SMESH_Mesh_i::addGeomGroupData(GEOM::GEOM_Object_ptr theGeomObj,
1814 CORBA::Object_ptr theSmeshObj)
1816 if ( CORBA::is_nil( theGeomObj ) || theGeomObj->GetType() != GEOM_GROUP )
1819 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1820 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study, theGeomObj );
1821 if ( groupSO->_is_nil() )
1824 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1825 GEOM::GEOM_IGroupOperations_wrap groupOp =
1826 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1827 GEOM::ListOfLong_var ids = groupOp->GetObjects( theGeomObj );
1830 _geomGroupData.push_back( TGeomGroupData() );
1831 TGeomGroupData & groupData = _geomGroupData.back();
1833 CORBA::String_var entry = groupSO->GetID();
1834 groupData._groupEntry = entry.in();
1836 for ( int i = 0; i < ids->length(); ++i )
1837 groupData._indices.insert( ids[i] );
1839 groupData._smeshObject = CORBA::Object::_duplicate( theSmeshObj );
1840 // shape index in SMESHDS
1841 // TopoDS_Shape shape = _gen_i->GeomObjectToShape( theGeomObj );
1842 // groupData._dsID = shape.IsNull() ? 0 : _impl->GetSubMesh( shape )->GetId();
1845 //================================================================================
1847 * Remove GEOM group data relating to removed smesh object
1849 //================================================================================
1851 void SMESH_Mesh_i::removeGeomGroupData(CORBA::Object_ptr theSmeshObj)
1853 list<TGeomGroupData>::iterator
1854 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
1855 for ( ; data != dataEnd; ++data ) {
1856 if ( theSmeshObj->_is_equivalent( data->_smeshObject )) {
1857 _geomGroupData.erase( data );
1863 //================================================================================
1865 * \brief Return new group contents if it has been changed and update group data
1867 //================================================================================
1869 TopoDS_Shape SMESH_Mesh_i::newGroupShape( TGeomGroupData & groupData)
1871 TopoDS_Shape newShape;
1874 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1875 if ( study->_is_nil() ) return newShape; // means "not changed"
1876 SALOMEDS::SObject_wrap groupSO = study->FindObjectID( groupData._groupEntry.c_str() );
1877 if ( !groupSO->_is_nil() )
1879 CORBA::Object_var groupObj = _gen_i->SObjectToObject( groupSO );
1880 if ( CORBA::is_nil( groupObj )) return newShape;
1881 GEOM::GEOM_Object_var geomGroup = GEOM::GEOM_Object::_narrow( groupObj );
1883 // get indices of group items
1884 set<int> curIndices;
1885 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1886 GEOM::GEOM_IGroupOperations_wrap groupOp =
1887 geomGen->GetIGroupOperations( _gen_i->GetCurrentStudyID() );
1888 GEOM::ListOfLong_var ids = groupOp->GetObjects( geomGroup );
1889 for ( int i = 0; i < ids->length(); ++i )
1890 curIndices.insert( ids[i] );
1892 if ( groupData._indices == curIndices )
1893 return newShape; // group not changed
1896 groupData._indices = curIndices;
1898 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1899 if ( !geomClient ) return newShape;
1900 CORBA::String_var groupIOR = geomGen->GetStringFromIOR( geomGroup );
1901 geomClient->RemoveShapeFromBuffer( groupIOR.in() );
1902 newShape = _gen_i->GeomObjectToShape( geomGroup );
1905 if ( newShape.IsNull() ) {
1906 // geom group becomes empty - return empty compound
1907 TopoDS_Compound compound;
1908 BRep_Builder().MakeCompound(compound);
1909 newShape = compound;
1916 //-----------------------------------------------------------------------------
1918 * \brief Storage of shape and index used in CheckGeomGroupModif()
1920 struct TIndexedShape
1923 TopoDS_Shape _shape;
1924 TIndexedShape( int i, const TopoDS_Shape& s ):_index(i), _shape(s) {}
1926 //-----------------------------------------------------------------------------
1928 * \brief Data to re-create a group on geometry
1930 struct TGroupOnGeomData
1934 SMDSAbs_ElementType _type;
1936 Quantity_Color _color;
1940 //=============================================================================
1942 * \brief Update data if geometry changes
1946 //=============================================================================
1948 void SMESH_Mesh_i::CheckGeomModif()
1950 if ( !_impl->HasShapeToMesh() ) return;
1952 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
1953 if ( study->_is_nil() ) return;
1955 GEOM::GEOM_Object_var mainGO = _gen_i->ShapeToGeomObject( _impl->GetShapeToMesh() );
1956 if ( mainGO->_is_nil() ) return;
1958 if ( mainGO->GetType() == GEOM_GROUP ||
1959 mainGO->GetTick() == _mainShapeTick )
1961 CheckGeomGroupModif();
1965 GEOM_Client* geomClient = _gen_i->GetShapeReader();
1966 if ( !geomClient ) return;
1967 GEOM::GEOM_Gen_var geomGen = _gen_i->GetGeomEngine();
1968 if ( geomGen->_is_nil() ) return;
1970 CORBA::String_var ior = geomGen->GetStringFromIOR( mainGO );
1971 geomClient->RemoveShapeFromBuffer( ior.in() );
1973 // Update data taking into account that
1974 // all sub-shapes change but IDs of sub-shapes remain (except for geom groups)
1977 TopoDS_Shape newShape = _gen_i->GeomObjectToShape( mainGO );
1978 if ( newShape.IsNull() )
1981 _mainShapeTick = mainGO->GetTick();
1983 SMESHDS_Mesh * meshDS = _impl->GetMeshDS();
1985 // store data of groups on geometry
1986 vector< TGroupOnGeomData > groupsData;
1987 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
1988 groupsData.reserve( groups.size() );
1989 set<SMESHDS_GroupBase*>::const_iterator g = groups.begin();
1990 for ( ; g != groups.end(); ++g )
1991 if ( const SMESHDS_GroupOnGeom* group = dynamic_cast< SMESHDS_GroupOnGeom* >( *g ))
1993 TGroupOnGeomData data;
1994 data._oldID = group->GetID();
1995 data._shapeID = meshDS->ShapeToIndex( group->GetShape() );
1996 data._type = group->GetType();
1997 data._name = group->GetStoreName();
1998 data._color = group->GetColor();
1999 groupsData.push_back( data );
2001 // store assigned hypotheses
2002 vector< pair< int, THypList > > ids2Hyps;
2003 const ShapeToHypothesis & hyps = meshDS->GetHypotheses();
2004 for ( ShapeToHypothesis::Iterator s2hyps( hyps ); s2hyps.More(); s2hyps.Next() )
2006 const TopoDS_Shape& s = s2hyps.Key();
2007 const THypList& hyps = s2hyps.ChangeValue();
2008 ids2Hyps.push_back( make_pair( meshDS->ShapeToIndex( s ), hyps ));
2011 // change shape to mesh
2012 int oldNbSubShapes = meshDS->MaxShapeIndex();
2013 _impl->ShapeToMesh( TopoDS_Shape() );
2014 _impl->ShapeToMesh( newShape );
2016 // re-add shapes of geom groups
2017 list<TGeomGroupData>::iterator data = _geomGroupData.begin();
2018 for ( ; data != _geomGroupData.end(); ++data )
2020 TopoDS_Shape newShape = newGroupShape( *data );
2021 if ( !newShape.IsNull() )
2023 if ( meshDS->ShapeToIndex( newShape ) > 0 ) // a group reduced to one sub-shape
2025 TopoDS_Compound compound;
2026 BRep_Builder().MakeCompound( compound );
2027 BRep_Builder().Add( compound, newShape );
2028 newShape = compound;
2030 _impl->GetSubMesh( newShape );
2033 if ( oldNbSubShapes != meshDS->MaxShapeIndex() )
2034 THROW_SALOME_CORBA_EXCEPTION( "SMESH_Mesh_i::CheckGeomModif() bug",
2035 SALOME::INTERNAL_ERROR );
2037 // re-assign hypotheses
2038 for ( size_t i = 0; i < ids2Hyps.size(); ++i )
2040 const TopoDS_Shape& s = meshDS->IndexToShape( ids2Hyps[i].first );
2041 const THypList& hyps = ids2Hyps[i].second;
2042 THypList::const_iterator h = hyps.begin();
2043 for ( ; h != hyps.end(); ++h )
2044 _impl->AddHypothesis( s, (*h)->GetID() );
2048 for ( size_t i = 0; i < groupsData.size(); ++i )
2050 const TGroupOnGeomData& data = groupsData[i];
2052 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i2g = _mapGroups.find( data._oldID );
2053 if ( i2g == _mapGroups.end() ) continue;
2055 SMESH_GroupBase_i* gr_i = SMESH::DownCast<SMESH_GroupBase_i*>( i2g->second );
2056 if ( !gr_i ) continue;
2059 SMESH_Group* g = _impl->AddGroup( data._type, data._name.c_str(), id,
2060 meshDS->IndexToShape( data._shapeID ));
2063 _mapGroups.erase( i2g );
2067 g->GetGroupDS()->SetColor( data._color );
2068 gr_i->changeLocalId( id );
2069 _mapGroups[ id ] = i2g->second;
2070 if ( data._oldID != id )
2071 _mapGroups.erase( i2g );
2075 // update _mapSubMesh
2076 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
2077 for ( ; i_sm != _mapSubMesh.end(); ++i_sm )
2078 i_sm->second = _impl->GetSubMesh( meshDS->IndexToShape( i_sm->first ));
2082 //=============================================================================
2084 * \brief Update objects depending on changed geom groups
2086 * NPAL16168: geometrical group edition from a submesh don't modifiy mesh computation
2087 * issue 0020210: Update of a smesh group after modification of the associated geom group
2089 //=============================================================================
2091 void SMESH_Mesh_i::CheckGeomGroupModif()
2093 if ( !_impl->HasShapeToMesh() ) return;
2095 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
2096 if ( study->_is_nil() ) return;
2098 CORBA::Long nbEntities = NbNodes() + NbElements();
2100 // Check if group contents changed
2102 typedef map< string, TopoDS_Shape > TEntry2Geom;
2103 TEntry2Geom newGroupContents;
2105 list<TGeomGroupData>::iterator
2106 data = _geomGroupData.begin(), dataEnd = _geomGroupData.end();
2107 for ( ; data != dataEnd; ++data )
2109 pair< TEntry2Geom::iterator, bool > it_new =
2110 newGroupContents.insert( make_pair( data->_groupEntry, TopoDS_Shape() ));
2111 bool processedGroup = !it_new.second;
2112 TopoDS_Shape& newShape = it_new.first->second;
2113 if ( !processedGroup )
2114 newShape = newGroupShape( *data );
2115 if ( newShape.IsNull() )
2116 continue; // no changes
2119 _preMeshInfo->ForgetOrLoad();
2121 if ( processedGroup ) { // update group indices
2122 list<TGeomGroupData>::iterator data2 = data;
2123 for ( --data2; data2->_groupEntry != data->_groupEntry; --data2) {}
2124 data->_indices = data2->_indices;
2127 // Update SMESH objects according to new GEOM group contents
2129 SMESH::SMESH_subMesh_var submesh = SMESH::SMESH_subMesh::_narrow( data->_smeshObject );
2130 if ( !submesh->_is_nil() ) // -------------- Sub mesh ---------------------
2132 int oldID = submesh->GetId();
2133 if ( !_mapSubMeshIor.count( oldID ))
2135 TopoDS_Shape oldShape = _mapSubMesh[oldID]->GetSubShape();
2137 // update hypotheses
2138 list <const SMESHDS_Hypothesis * > hyps = _impl->GetHypothesisList(oldShape);
2139 list <const SMESHDS_Hypothesis * >::iterator hypIt;
2140 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2142 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2143 _impl->AddHypothesis ( newShape, (*hypIt)->GetID());
2145 // care of submeshes
2146 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( newShape );
2147 int newID = newSubmesh->GetId();
2148 if ( newID != oldID ) {
2149 _mapSubMesh [ newID ] = newSubmesh;
2150 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2151 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2152 _mapSubMesh. erase(oldID);
2153 _mapSubMesh_i. erase(oldID);
2154 _mapSubMeshIor.erase(oldID);
2155 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2160 SMESH::SMESH_GroupOnGeom_var smeshGroup =
2161 SMESH::SMESH_GroupOnGeom::_narrow( data->_smeshObject );
2162 if ( !smeshGroup->_is_nil() ) // ------------ GROUP -----------------------
2164 SMESH_GroupOnGeom_i* group_i = SMESH::DownCast<SMESH_GroupOnGeom_i*>( smeshGroup );
2166 ::SMESH_Group* group = _impl->GetGroup( group_i->GetLocalID() );
2167 SMESHDS_GroupOnGeom* ds = static_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() );
2168 ds->SetShape( newShape );
2173 SMESH::SMESH_Mesh_var mesh = SMESH::SMESH_Mesh::_narrow( data->_smeshObject );
2174 if ( !mesh->_is_nil() ) // -------------- MESH ----------------------------
2176 // Remove groups and submeshes basing on removed sub-shapes
2178 TopTools_MapOfShape newShapeMap;
2179 TopoDS_Iterator shapeIt( newShape );
2180 for ( ; shapeIt.More(); shapeIt.Next() )
2181 newShapeMap.Add( shapeIt.Value() );
2183 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
2184 for ( shapeIt.Initialize( meshDS->ShapeToMesh() ); shapeIt.More(); shapeIt.Next() )
2186 if ( newShapeMap.Contains( shapeIt.Value() ))
2188 TopTools_IndexedMapOfShape oldShapeMap;
2189 TopExp::MapShapes( shapeIt.Value(), oldShapeMap );
2190 for ( int i = 1; i <= oldShapeMap.Extent(); ++i )
2192 const TopoDS_Shape& oldShape = oldShapeMap(i);
2193 int oldInd = meshDS->ShapeToIndex( oldShape );
2195 map<int, SMESH::SMESH_subMesh_ptr>::iterator i_smIor = _mapSubMeshIor.find( oldInd );
2196 if ( i_smIor != _mapSubMeshIor.end() ) {
2197 RemoveSubMesh( i_smIor->second ); // one submesh per shape index
2200 map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_grp = _mapGroups.begin();
2201 for ( ; i_grp != _mapGroups.end(); ++i_grp )
2203 // check if a group bases on oldInd shape
2204 SMESHDS_GroupOnGeom* grpOnGeom = 0;
2205 if ( ::SMESH_Group* g = _impl->GetGroup( i_grp->first ))
2206 grpOnGeom = dynamic_cast<SMESHDS_GroupOnGeom*>( g->GetGroupDS() );
2207 if ( grpOnGeom && oldShape.IsSame( grpOnGeom->GetShape() ))
2209 RemoveGroup( i_grp->second ); // several groups can base on same shape
2210 i_grp = _mapGroups.begin(); // _mapGroups changed - restart iteration
2215 // Reassign hypotheses and update groups after setting the new shape to mesh
2217 // collect anassigned hypotheses
2218 typedef list< pair< TIndexedShape, list<const SMESHDS_Hypothesis*> > > TShapeHypList;
2219 list <const SMESHDS_Hypothesis * >::const_iterator hypIt;
2220 TShapeHypList assignedHyps;
2221 for ( int i = 1; i <= meshDS->MaxShapeIndex(); ++i )
2223 const TopoDS_Shape& oldShape = meshDS->IndexToShape(i);
2224 list<const SMESHDS_Hypothesis*> hyps = meshDS->GetHypothesis( oldShape );// copy
2225 if ( !hyps.empty() ) {
2226 assignedHyps.push_back( make_pair( TIndexedShape(i,oldShape), hyps ));
2227 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2228 _impl->RemoveHypothesis( oldShape, (*hypIt)->GetID());
2231 // collect shapes supporting groups
2232 typedef list < pair< TIndexedShape, SMDSAbs_ElementType > > TShapeTypeList;
2233 TShapeTypeList groupData;
2234 const set<SMESHDS_GroupBase*>& groups = meshDS->GetGroups();
2235 set<SMESHDS_GroupBase*>::const_iterator grIt = groups.begin();
2236 for ( ; grIt != groups.end(); ++grIt )
2238 if ( SMESHDS_GroupOnGeom* gog = dynamic_cast<SMESHDS_GroupOnGeom*>( *grIt ))
2240 ( make_pair( TIndexedShape( gog->GetID(),gog->GetShape()), gog->GetType()));
2242 // set new shape to mesh -> DS of submeshes and geom groups is deleted
2243 _impl->ShapeToMesh( newShape );
2245 // reassign hypotheses
2246 TShapeHypList::iterator indS_hyps = assignedHyps.begin();
2247 for ( ; indS_hyps != assignedHyps.end(); ++indS_hyps )
2249 TIndexedShape& geom = indS_hyps->first;
2250 list<const SMESHDS_Hypothesis*>& hyps = indS_hyps->second;
2251 int oldID = geom._index;
2252 int newID = meshDS->ShapeToIndex( geom._shape );
2253 if ( oldID == 1 ) { // main shape
2255 geom._shape = newShape;
2259 for ( hypIt = hyps.begin(); hypIt != hyps.end(); ++hypIt )
2260 _impl->AddHypothesis( geom._shape, (*hypIt)->GetID());
2261 // care of submeshes
2262 SMESH_subMesh* newSubmesh = _impl->GetSubMesh( geom._shape );
2263 if ( newID != oldID ) {
2264 _mapSubMesh [ newID ] = newSubmesh;
2265 _mapSubMesh_i [ newID ] = _mapSubMesh_i [ oldID ];
2266 _mapSubMeshIor[ newID ] = _mapSubMeshIor[ oldID ];
2267 _mapSubMesh. erase(oldID);
2268 _mapSubMesh_i. erase(oldID);
2269 _mapSubMeshIor.erase(oldID);
2270 _mapSubMesh_i [ newID ]->changeLocalId( newID );
2274 TShapeTypeList::iterator geomType = groupData.begin();
2275 for ( ; geomType != groupData.end(); ++geomType )
2277 const TIndexedShape& geom = geomType->first;
2278 int oldID = geom._index;
2279 if ( _mapGroups.find( oldID ) == _mapGroups.end() )
2282 SALOMEDS::SObject_wrap groupSO = _gen_i->ObjectToSObject( study,_mapGroups[oldID] );
2283 CORBA::String_var name = groupSO->GetName();
2285 SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>(_mapGroups[oldID] );
2287 if ( group_i && _impl->AddGroup( geomType->second, name.in(), newID, geom._shape ))
2288 group_i->changeLocalId( newID );
2291 break; // everything has been updated
2294 } // loop on group data
2298 CORBA::Long newNbEntities = NbNodes() + NbElements();
2299 list< SALOMEDS::SObject_wrap > soToUpdateIcons;
2300 if ( newNbEntities != nbEntities )
2302 // Add all SObjects with icons to soToUpdateIcons
2303 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, _this() )); // mesh
2305 for (map<int, SMESH::SMESH_subMesh_ptr>::iterator i_sm = _mapSubMeshIor.begin();
2306 i_sm != _mapSubMeshIor.end(); ++i_sm ) // submeshes
2307 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_sm->second ));
2309 for ( map<int, SMESH::SMESH_GroupBase_ptr>::iterator i_gr = _mapGroups.begin();
2310 i_gr != _mapGroups.end(); ++i_gr ) // groups
2311 soToUpdateIcons.push_back( _gen_i->ObjectToSObject( study, i_gr->second ));
2314 list< SALOMEDS::SObject_wrap >::iterator so = soToUpdateIcons.begin();
2315 for ( ; so != soToUpdateIcons.end(); ++so )
2316 _gen_i->SetPixMap( *so, "ICON_SMESH_TREE_MESH_WARN" );
2319 //=============================================================================
2321 * \brief Create standalone group from a group on geometry or filter
2323 //=============================================================================
2325 SMESH::SMESH_Group_ptr SMESH_Mesh_i::ConvertToStandalone( SMESH::SMESH_GroupBase_ptr theGroup )
2326 throw (SALOME::SALOME_Exception)
2328 SMESH::SMESH_Group_var aGroup;
2333 _preMeshInfo->FullLoadFromFile();
2335 if ( theGroup->_is_nil() )
2336 return aGroup._retn();
2338 SMESH_GroupBase_i* aGroupToRem = SMESH::DownCast<SMESH_GroupBase_i*>( theGroup );
2340 return aGroup._retn();
2342 const bool isOnFilter = ( SMESH::DownCast< SMESH_GroupOnFilter_i* > ( theGroup ));
2344 const int anId = aGroupToRem->GetLocalID();
2345 if ( !_impl->ConvertToStandalone( anId ) )
2346 return aGroup._retn();
2347 removeGeomGroupData( theGroup );
2349 SMESH_GroupBase_i* aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2351 // remove old instance of group from own map
2352 { SMESH::SMESH_GroupBase_var var( _mapGroups[anId] ); } // decref CORBA object
2353 _mapGroups.erase( anId );
2355 SALOMEDS::StudyBuilder_var builder;
2356 SALOMEDS::SObject_wrap aGroupSO;
2357 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2358 if ( !aStudy->_is_nil() ) {
2359 builder = aStudy->NewBuilder();
2360 aGroupSO = _gen_i->ObjectToSObject( aStudy, theGroup );
2361 if ( !aGroupSO->_is_nil() )
2363 // remove reference to geometry
2364 SALOMEDS::ChildIterator_wrap chItr = aStudy->NewChildIterator(aGroupSO);
2365 for ( ; chItr->More(); chItr->Next() )
2366 // Remove group's child SObject
2367 builder->RemoveObject( chItr->Value() );
2369 // Update Python script
2370 TPythonDump() << aGroupSO << " = " << SMESH::SMESH_Mesh_var(_this())
2371 << ".ConvertToStandalone( " << aGroupSO << " )";
2373 // change icon of Group on Filter
2376 SMESH::array_of_ElementType_var elemTypes = aGroupImpl->GetTypes();
2377 const int isEmpty = ( elemTypes->length() == 0 );
2380 SALOMEDS::GenericAttribute_wrap anAttr =
2381 builder->FindOrCreateAttribute( aGroupSO, "AttributePixMap" );
2382 SALOMEDS::AttributePixMap_wrap pm = anAttr;
2383 pm->SetPixMap( "ICON_SMESH_TREE_GROUP" );
2389 // remember new group in own map
2390 aGroup = SMESH::SMESH_Group::_narrow( aGroupImpl->_this() );
2391 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2393 // register CORBA object for persistence
2394 _gen_i->RegisterObject( aGroup );
2396 CORBA::String_var ior = _gen_i->GetORB()->object_to_string( aGroup );
2397 builder->SetIOR( aGroupSO, ior.in() ); // == aGroup->Register();
2398 //aGroup->Register();
2399 aGroupToRem->UnRegister();
2401 SMESH_CATCH( SMESH::throwCorbaException );
2403 return aGroup._retn();
2406 //=============================================================================
2410 //=============================================================================
2412 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::createSubMesh( GEOM::GEOM_Object_ptr theSubShapeObject )
2414 if(MYDEBUG) MESSAGE( "createSubMesh" );
2415 TopoDS_Shape myLocSubShape = _gen_i->GeomObjectToShape(theSubShapeObject);
2416 ::SMESH_subMesh * mySubMesh = _impl->GetSubMesh(myLocSubShape);
2417 const int subMeshId = mySubMesh->GetId();
2419 SMESH_subMesh_i * subMeshServant = new SMESH_subMesh_i(myPOA, _gen_i, this, subMeshId);
2420 SMESH::SMESH_subMesh_var subMesh = subMeshServant->_this();
2422 _mapSubMesh [subMeshId] = mySubMesh;
2423 _mapSubMesh_i [subMeshId] = subMeshServant;
2424 _mapSubMeshIor[subMeshId] = SMESH::SMESH_subMesh::_duplicate( subMesh );
2426 subMeshServant->Register();
2428 // register CORBA object for persistence
2429 int nextId = _gen_i->RegisterObject( subMesh );
2430 if(MYDEBUG) { MESSAGE( "Add submesh to map with id = "<< nextId); }
2431 else { nextId = 0; } // avoid "unused variable" warning
2433 // to track changes of GEOM groups
2434 addGeomGroupData( theSubShapeObject, subMesh );
2436 return subMesh._retn();
2439 //=======================================================================
2440 //function : getSubMesh
2442 //=======================================================================
2444 SMESH::SMESH_subMesh_ptr SMESH_Mesh_i::getSubMesh(int shapeID)
2446 map<int, SMESH::SMESH_subMesh_ptr>::iterator it = _mapSubMeshIor.find( shapeID );
2447 if ( it == _mapSubMeshIor.end() )
2448 return SMESH::SMESH_subMesh::_nil();
2450 return SMESH::SMESH_subMesh::_duplicate( (*it).second );
2453 //=============================================================================
2457 //=============================================================================
2459 bool SMESH_Mesh_i::removeSubMesh (SMESH::SMESH_subMesh_ptr theSubMesh,
2460 GEOM::GEOM_Object_ptr theSubShapeObject )
2462 bool isHypChanged = false;
2463 if ( theSubMesh->_is_nil() /*|| theSubShapeObject->_is_nil()*/ )
2464 return isHypChanged;
2466 const int subMeshId = theSubMesh->GetId();
2468 if ( theSubShapeObject->_is_nil() ) // not published shape (IPAL13617)
2470 if ( _mapSubMesh.find( subMeshId ) != _mapSubMesh.end())
2472 TopoDS_Shape S = _mapSubMesh[ subMeshId ]->GetSubShape();
2475 list<const SMESHDS_Hypothesis*> hyps = _impl->GetHypothesisList( S );
2476 isHypChanged = !hyps.empty();
2477 list<const SMESHDS_Hypothesis*>::const_iterator hyp = hyps.begin();
2478 for ( ; hyp != hyps.end(); ++hyp )
2479 _impl->RemoveHypothesis(S, (*hyp)->GetID());
2486 SMESH::ListOfHypothesis_var aHypList = GetHypothesisList( theSubShapeObject );
2487 isHypChanged = ( aHypList->length() > 0 );
2488 for ( int i = 0, n = aHypList->length(); i < n; i++ ) {
2489 removeHypothesis( theSubShapeObject, aHypList[i] );
2492 catch( const SALOME::SALOME_Exception& ) {
2493 INFOS("SMESH_Mesh_i::removeSubMesh(): exception caught!");
2495 removeGeomGroupData( theSubShapeObject );
2499 std::map<int, SMESH_subMesh_i*>::iterator id_smi = _mapSubMesh_i.find( subMeshId );
2500 if ( id_smi != _mapSubMesh_i.end() )
2501 id_smi->second->UnRegister();
2503 // remove a CORBA object
2504 std::map<int, SMESH::SMESH_subMesh_ptr>::iterator id_smptr = _mapSubMeshIor.find( subMeshId );
2505 if ( id_smptr != _mapSubMeshIor.end() )
2506 SMESH::SMESH_subMesh_var( id_smptr->second );
2508 _mapSubMesh.erase(subMeshId);
2509 _mapSubMesh_i.erase(subMeshId);
2510 _mapSubMeshIor.erase(subMeshId);
2512 return isHypChanged;
2515 //=============================================================================
2519 //=============================================================================
2521 SMESH::SMESH_GroupBase_ptr SMESH_Mesh_i::createGroup (SMESH::ElementType theElemType,
2522 const char* theName,
2523 const TopoDS_Shape& theShape,
2524 const SMESH_PredicatePtr& thePredicate )
2526 std::string newName;
2527 if ( !theName || strlen( theName ) == 0 )
2529 std::set< std::string > presentNames;
2530 std::map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator i_gr = _mapGroups.begin();
2531 for ( ; i_gr != _mapGroups.end(); ++i_gr )
2533 CORBA::String_var name = i_gr->second->GetName();
2534 presentNames.insert( name.in() );
2537 newName = "noname_Group_" + SMESH_Comment( presentNames.size() + 1 );
2538 } while ( !presentNames.insert( newName ).second );
2539 theName = newName.c_str();
2542 SMESH::SMESH_GroupBase_var aGroup;
2543 if ( _impl->AddGroup( (SMDSAbs_ElementType)theElemType, theName, anId, theShape, thePredicate ))
2545 SMESH_GroupBase_i* aGroupImpl;
2546 if ( !theShape.IsNull() )
2547 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
2548 else if ( thePredicate )
2549 aGroupImpl = new SMESH_GroupOnFilter_i( SMESH_Gen_i::GetPOA(), this, anId );
2551 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
2553 aGroup = aGroupImpl->_this();
2554 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( aGroup );
2555 aGroupImpl->Register();
2557 // register CORBA object for persistence
2558 int nextId = _gen_i->RegisterObject( aGroup );
2559 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
2560 else { nextId = 0; } // avoid "unused variable" warning in release mode
2562 // to track changes of GEOM groups
2563 if ( !theShape.IsNull() ) {
2564 GEOM::GEOM_Object_var geom = _gen_i->ShapeToGeomObject( theShape );
2565 addGeomGroupData( geom, aGroup );
2568 return aGroup._retn();
2571 //=============================================================================
2573 * SMESH_Mesh_i::removeGroup
2575 * Should be called by ~SMESH_Group_i()
2577 //=============================================================================
2579 void SMESH_Mesh_i::removeGroup( const int theId )
2581 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::removeGroup()" );
2582 if ( _mapGroups.find( theId ) != _mapGroups.end() ) {
2583 SMESH::SMESH_GroupBase_var group = _mapGroups[theId];
2584 _mapGroups.erase( theId );
2585 removeGeomGroupData( group );
2586 if ( !_impl->RemoveGroup( theId ))
2588 // it seems to be a call up from _impl caused by hyp modification (issue 0020918)
2589 RemoveGroup( group );
2591 group->UnRegister();
2595 //=============================================================================
2599 //=============================================================================
2601 SMESH::log_array * SMESH_Mesh_i::GetLog(CORBA::Boolean clearAfterGet)
2602 throw(SALOME::SALOME_Exception)
2604 SMESH::log_array_var aLog;
2608 _preMeshInfo->FullLoadFromFile();
2610 list < SMESHDS_Command * >logDS = _impl->GetLog();
2611 aLog = new SMESH::log_array;
2613 int lg = logDS.size();
2616 list < SMESHDS_Command * >::iterator its = logDS.begin();
2617 while(its != logDS.end()){
2618 SMESHDS_Command *com = *its;
2619 int comType = com->GetType();
2621 int lgcom = com->GetNumber();
2623 const list < int >&intList = com->GetIndexes();
2624 int inum = intList.size();
2626 list < int >::const_iterator ii = intList.begin();
2627 const list < double >&coordList = com->GetCoords();
2628 int rnum = coordList.size();
2630 list < double >::const_iterator ir = coordList.begin();
2631 aLog[indexLog].commandType = comType;
2632 aLog[indexLog].number = lgcom;
2633 aLog[indexLog].coords.length(rnum);
2634 aLog[indexLog].indexes.length(inum);
2635 for(int i = 0; i < rnum; i++){
2636 aLog[indexLog].coords[i] = *ir;
2637 //MESSAGE(" "<<i<<" "<<ir.Value());
2640 for(int i = 0; i < inum; i++){
2641 aLog[indexLog].indexes[i] = *ii;
2642 //MESSAGE(" "<<i<<" "<<ii.Value());
2651 SMESH_CATCH( SMESH::throwCorbaException );
2653 return aLog._retn();
2657 //=============================================================================
2661 //=============================================================================
2663 void SMESH_Mesh_i::ClearLog() throw(SALOME::SALOME_Exception)
2667 SMESH_CATCH( SMESH::throwCorbaException );
2670 //=============================================================================
2674 //=============================================================================
2676 CORBA::Long SMESH_Mesh_i::GetId()throw(SALOME::SALOME_Exception)
2681 //=============================================================================
2685 //=============================================================================
2687 CORBA::Long SMESH_Mesh_i::GetStudyId()throw(SALOME::SALOME_Exception)
2692 //=============================================================================
2695 //!< implementation of struct used to call methods of SMESH_Mesh_i from SMESH_Mesh
2696 // issue 0020918: groups removal is caused by hyp modification
2697 // issue 0021208: to forget not loaded mesh data at hyp modification
2698 struct TCallUp_i : public SMESH_Mesh::TCallUp
2700 SMESH_Mesh_i* _mesh;
2701 TCallUp_i(SMESH_Mesh_i* mesh):_mesh(mesh) {}
2702 virtual void RemoveGroup (const int theGroupID) { _mesh->removeGroup( theGroupID ); }
2703 virtual void HypothesisModified () { _mesh->onHypothesisModified(); }
2704 virtual void Load () { _mesh->Load(); }
2708 //================================================================================
2710 * \brief callback from _impl to forget not loaded mesh data (issue 0021208)
2712 //================================================================================
2714 void SMESH_Mesh_i::onHypothesisModified()
2717 _preMeshInfo->ForgetOrLoad();
2720 //=============================================================================
2724 //=============================================================================
2726 void SMESH_Mesh_i::SetImpl(::SMESH_Mesh * impl)
2728 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::SetImpl");
2731 _impl->SetCallUp( new TCallUp_i(this));
2734 //=============================================================================
2738 //=============================================================================
2740 ::SMESH_Mesh & SMESH_Mesh_i::GetImpl()
2742 if(MYDEBUG) MESSAGE("SMESH_Mesh_i::GetImpl()");
2746 //=============================================================================
2748 * Return mesh editor
2750 //=============================================================================
2752 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditor()
2753 throw (SALOME::SALOME_Exception)
2755 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2759 _preMeshInfo->FullLoadFromFile();
2761 // Create MeshEditor
2763 _editor = new SMESH_MeshEditor_i( this, false );
2764 aMeshEdVar = _editor->_this();
2766 // Update Python script
2767 TPythonDump() << _editor << " = "
2768 << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshEditor()";
2770 SMESH_CATCH( SMESH::throwCorbaException );
2772 return aMeshEdVar._retn();
2775 //=============================================================================
2777 * Return mesh edition previewer
2779 //=============================================================================
2781 SMESH::SMESH_MeshEditor_ptr SMESH_Mesh_i::GetMeshEditPreviewer()
2782 throw (SALOME::SALOME_Exception)
2784 SMESH::SMESH_MeshEditor_var aMeshEdVar;
2788 _preMeshInfo->FullLoadFromFile();
2790 if ( !_previewEditor )
2791 _previewEditor = new SMESH_MeshEditor_i( this, true );
2792 aMeshEdVar = _previewEditor->_this();
2794 SMESH_CATCH( SMESH::throwCorbaException );
2796 return aMeshEdVar._retn();
2799 //================================================================================
2801 * \brief Return true if the mesh has been edited since a last total re-compute
2802 * and those modifications may prevent successful partial re-compute
2804 //================================================================================
2806 CORBA::Boolean SMESH_Mesh_i::HasModificationsToDiscard() throw(SALOME::SALOME_Exception)
2808 Unexpect aCatch(SALOME_SalomeException);
2809 return _impl->HasModificationsToDiscard();
2812 //================================================================================
2814 * \brief Returns a random unique color
2816 //================================================================================
2818 static SALOMEDS::Color getUniqueColor( const std::list<SALOMEDS::Color>& theReservedColors )
2820 const int MAX_ATTEMPTS = 100;
2822 double tolerance = 0.5;
2823 SALOMEDS::Color col;
2827 // generate random color
2828 double red = (double)rand() / RAND_MAX;
2829 double green = (double)rand() / RAND_MAX;
2830 double blue = (double)rand() / RAND_MAX;
2831 // check existence in the list of the existing colors
2832 bool matched = false;
2833 std::list<SALOMEDS::Color>::const_iterator it;
2834 for ( it = theReservedColors.begin(); it != theReservedColors.end() && !matched; ++it ) {
2835 SALOMEDS::Color color = *it;
2836 double tol = fabs( color.R - red ) + fabs( color.G - green ) + fabs( color.B - blue );
2837 matched = tol < tolerance;
2839 if ( (cnt+1) % 20 == 0 ) tolerance = tolerance/2;
2840 ok = ( ++cnt == MAX_ATTEMPTS ) || !matched;
2848 //=============================================================================
2850 * Sets auto-color mode. If it is on, groups get unique random colors
2852 //=============================================================================
2854 void SMESH_Mesh_i::SetAutoColor(CORBA::Boolean theAutoColor) throw(SALOME::SALOME_Exception)
2856 Unexpect aCatch(SALOME_SalomeException);
2857 _impl->SetAutoColor(theAutoColor);
2859 TPythonDump pyDump; // not to dump group->SetColor() from below code
2860 pyDump << SMESH::SMESH_Mesh_var(_this()) <<".SetAutoColor( "<<theAutoColor<<" )";
2862 std::list<SALOMEDS::Color> aReservedColors;
2863 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.begin();
2864 for ( ; it != _mapGroups.end(); it++ ) {
2865 if ( CORBA::is_nil( it->second )) continue;
2866 SALOMEDS::Color aColor = getUniqueColor( aReservedColors );
2867 it->second->SetColor( aColor );
2868 aReservedColors.push_back( aColor );
2872 //=============================================================================
2874 * Returns true if auto-color mode is on
2876 //=============================================================================
2878 CORBA::Boolean SMESH_Mesh_i::GetAutoColor() throw(SALOME::SALOME_Exception)
2880 Unexpect aCatch(SALOME_SalomeException);
2881 return _impl->GetAutoColor();
2884 //=============================================================================
2886 * Checks if there are groups with equal names
2888 //=============================================================================
2890 CORBA::Boolean SMESH_Mesh_i::HasDuplicatedGroupNamesMED()
2892 return _impl->HasDuplicatedGroupNamesMED();
2895 //================================================================================
2897 * \brief Care of a file before exporting mesh into it
2899 //================================================================================
2901 void SMESH_Mesh_i::PrepareForWriting (const char* file, bool overwrite)
2903 SMESH_File aFile( file );
2905 if (aFile.exists()) {
2906 // existing filesystem node
2907 if ( !aFile.isDirectory() ) {
2908 if ( aFile.openForWriting() ) {
2909 if ( overwrite && ! aFile.remove()) {
2910 msg << "Can't replace " << aFile.getName();
2913 msg << "Can't write into " << aFile.getName();
2916 msg << "Location " << aFile.getName() << " is not a file";
2920 // nonexisting file; check if it can be created
2921 if ( !aFile.openForWriting() ) {
2922 msg << "You cannot create the file "
2924 << ". Check the directory existance and access rights";
2932 THROW_SALOME_CORBA_EXCEPTION(msg.c_str(), SALOME::BAD_PARAM);
2936 //================================================================================
2938 * \brief Prepares a file for export and pass names of mesh groups from study to mesh DS
2939 * \param file - file name
2940 * \param overwrite - to erase the file or not
2941 * \retval string - mesh name
2943 //================================================================================
2945 string SMESH_Mesh_i::prepareMeshNameAndGroups(const char* file,
2946 CORBA::Boolean overwrite)
2949 PrepareForWriting(file, overwrite);
2950 string aMeshName = "Mesh";
2951 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
2952 if ( !aStudy->_is_nil() ) {
2953 SALOMEDS::SObject_wrap aMeshSO = _gen_i->ObjectToSObject( aStudy, _this() );
2954 if ( !aMeshSO->_is_nil() ) {
2955 CORBA::String_var name = aMeshSO->GetName();
2957 // asv : 27.10.04 : fix of 6903: check for StudyLocked before adding attributes
2958 if ( !aStudy->GetProperties()->IsLocked() )
2960 SALOMEDS::GenericAttribute_wrap anAttr;
2961 SALOMEDS::StudyBuilder_var aStudyBuilder = aStudy->NewBuilder();
2962 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeExternalFileDef");
2963 SALOMEDS::AttributeExternalFileDef_wrap aFileName = anAttr;
2964 ASSERT(!aFileName->_is_nil());
2965 aFileName->SetValue(file);
2966 anAttr=aStudyBuilder->FindOrCreateAttribute(aMeshSO, "AttributeFileType");
2967 SALOMEDS::AttributeFileType_wrap aFileType = anAttr;
2968 ASSERT(!aFileType->_is_nil());
2969 aFileType->SetValue("FICHIERMED");
2973 // Update Python script
2974 // set name of mesh before export
2975 TPythonDump() << _gen_i << ".SetName("
2976 << SMESH::SMESH_Mesh_var(_this()) << ", '" << aMeshName.c_str() << "')";
2978 // check names of groups
2984 //================================================================================
2986 * \brief Export to med file
2988 //================================================================================
2990 void SMESH_Mesh_i::ExportToMEDX (const char* file,
2991 CORBA::Boolean auto_groups,
2992 SMESH::MED_VERSION theVersion,
2993 CORBA::Boolean overwrite,
2994 CORBA::Boolean autoDimension)
2995 throw(SALOME::SALOME_Exception)
2999 _preMeshInfo->FullLoadFromFile();
3001 string aMeshName = prepareMeshNameAndGroups(file, overwrite);
3002 _impl->ExportMED( file, aMeshName.c_str(), auto_groups, theVersion, 0, autoDimension );
3004 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportToMEDX( r'"
3005 << file << "', " << auto_groups << ", "
3006 << theVersion << ", " << overwrite << ", "
3007 << autoDimension << " )";
3009 SMESH_CATCH( SMESH::throwCorbaException );
3012 //================================================================================
3014 * \brief Export a mesh to a med file
3016 //================================================================================
3018 void SMESH_Mesh_i::ExportToMED (const char* file,
3019 CORBA::Boolean auto_groups,
3020 SMESH::MED_VERSION theVersion)
3021 throw(SALOME::SALOME_Exception)
3023 ExportToMEDX(file,auto_groups,theVersion,true);
3026 //================================================================================
3028 * \brief Export a mesh to a med file
3030 //================================================================================
3032 void SMESH_Mesh_i::ExportMED (const char* file,
3033 CORBA::Boolean auto_groups)
3034 throw(SALOME::SALOME_Exception)
3036 ExportToMEDX(file,auto_groups,SMESH::MED_V2_2,true);
3039 //================================================================================
3041 * \brief Export a mesh to a SAUV file
3043 //================================================================================
3045 void SMESH_Mesh_i::ExportSAUV (const char* file,
3046 CORBA::Boolean auto_groups)
3047 throw(SALOME::SALOME_Exception)
3049 Unexpect aCatch(SALOME_SalomeException);
3051 _preMeshInfo->FullLoadFromFile();
3053 string aMeshName = prepareMeshNameAndGroups(file, true);
3054 TPythonDump() << SMESH::SMESH_Mesh_var( _this())
3055 << ".ExportSAUV( r'" << file << "', " << auto_groups << " )";
3056 _impl->ExportSAUV(file, aMeshName.c_str(), auto_groups);
3060 //================================================================================
3062 * \brief Export a mesh to a DAT file
3064 //================================================================================
3066 void SMESH_Mesh_i::ExportDAT (const char *file)
3067 throw(SALOME::SALOME_Exception)
3069 Unexpect aCatch(SALOME_SalomeException);
3071 _preMeshInfo->FullLoadFromFile();
3073 // Update Python script
3074 // check names of groups
3076 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportDAT( r'" << file << "' )";
3079 PrepareForWriting(file);
3080 _impl->ExportDAT(file);
3083 //================================================================================
3085 * \brief Export a mesh to an UNV file
3087 //================================================================================
3089 void SMESH_Mesh_i::ExportUNV (const char *file)
3090 throw(SALOME::SALOME_Exception)
3092 Unexpect aCatch(SALOME_SalomeException);
3094 _preMeshInfo->FullLoadFromFile();
3096 // Update Python script
3097 // check names of groups
3099 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportUNV( r'" << file << "' )";
3102 PrepareForWriting(file);
3103 _impl->ExportUNV(file);
3106 //================================================================================
3108 * \brief Export a mesh to an STL file
3110 //================================================================================
3112 void SMESH_Mesh_i::ExportSTL (const char *file, const bool isascii)
3113 throw(SALOME::SALOME_Exception)
3115 Unexpect aCatch(SALOME_SalomeException);
3117 _preMeshInfo->FullLoadFromFile();
3119 // Update Python script
3120 // check names of groups
3122 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3123 << ".ExportSTL( r'" << file << "', " << isascii << " )";
3126 PrepareForWriting(file);
3127 _impl->ExportSTL(file, isascii);
3130 //================================================================================
3132 * \brief Export a part of mesh to a med file
3134 //================================================================================
3136 void SMESH_Mesh_i::ExportPartToMED(SMESH::SMESH_IDSource_ptr meshPart,
3138 CORBA::Boolean auto_groups,
3139 SMESH::MED_VERSION version,
3140 CORBA::Boolean overwrite,
3141 CORBA::Boolean autoDimension,
3142 const GEOM::ListOfFields& fields,
3143 const char* geomAssocFields)
3144 throw (SALOME::SALOME_Exception)
3148 _preMeshInfo->FullLoadFromFile();
3151 bool have0dField = false;
3152 if ( fields.length() > 0 )
3154 GEOM::GEOM_Object_var shapeToMesh = GetShapeToMesh();
3155 if ( shapeToMesh->_is_nil() )
3156 THROW_SALOME_CORBA_EXCEPTION( "No shape to mesh", SALOME::INTERNAL_ERROR );
3158 for ( size_t i = 0; i < fields.length(); ++i )
3160 if ( fields[i]->GetDataType() == GEOM::FDT_String )
3161 THROW_SALOME_CORBA_EXCEPTION
3162 ( "Export of string fields is not supported", SALOME::BAD_PARAM);
3163 GEOM::GEOM_Object_var fieldShape = fields[i]->GetShape();
3164 if ( fieldShape->_is_nil() )
3165 THROW_SALOME_CORBA_EXCEPTION( "Null shape under a field", SALOME::INTERNAL_ERROR );
3166 if ( !fieldShape->IsSame( shapeToMesh ) )
3167 THROW_SALOME_CORBA_EXCEPTION
3168 ( "Field defined not on shape", SALOME::BAD_PARAM);
3169 if ( fields[i]->GetDimension() == 0 )
3172 if ( geomAssocFields )
3173 for ( int i = 0; geomAssocFields[i]; ++i )
3174 switch ( geomAssocFields[i] ) {
3175 case 'v':case 'e':case 'f':case 's': break;
3176 case 'V':case 'E':case 'F':case 'S': break;
3177 default: THROW_SALOME_CORBA_EXCEPTION
3178 ( "geomAssocFields can include only [vefs] characters", SALOME::BAD_PARAM);
3182 SMESHDS_Mesh* meshDS = _impl->GetMeshDS();
3186 string aMeshName = "Mesh";
3187 SMESHUtils::Deleter< SMESH_MeshPartDS > tmpDSDeleter(0);
3188 if ( CORBA::is_nil( meshPart ) ||
3189 SMESH::DownCast< SMESH_Mesh_i* >( meshPart ))
3191 aMeshName = prepareMeshNameAndGroups(file, overwrite);
3192 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3193 version, 0, autoDimension, /*addODOnVertices=*/have0dField);
3194 meshDS = _impl->GetMeshDS();
3199 _preMeshInfo->FullLoadFromFile();
3201 PrepareForWriting(file, overwrite);
3203 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
3204 if ( !aStudy->_is_nil() ) {
3205 SALOMEDS::SObject_wrap SO = _gen_i->ObjectToSObject( aStudy, meshPart );
3206 if ( !SO->_is_nil() ) {
3207 CORBA::String_var name = SO->GetName();
3211 SMESH_MeshPartDS* partDS = new SMESH_MeshPartDS( meshPart );
3212 _impl->ExportMED( file, aMeshName.c_str(), auto_groups,
3213 version, partDS, autoDimension, /*addODOnVertices=*/have0dField);
3214 meshDS = tmpDSDeleter._obj = partDS;
3219 if ( _impl->HasShapeToMesh() )
3221 DriverMED_W_Field fieldWriter;
3222 fieldWriter.SetFile( file );
3223 fieldWriter.SetMeshName( aMeshName );
3224 fieldWriter.AddODOnVertices( have0dField );
3226 exportMEDFields( fieldWriter, meshDS, fields, geomAssocFields );
3230 GEOM::ListOfGBO_var goList = new GEOM::ListOfGBO;
3231 goList->length( fields.length() );
3232 for ( size_t i = 0; i < fields.length(); ++i )
3234 GEOM::GEOM_BaseObject_var gbo = GEOM::GEOM_BaseObject::_narrow( fields[i] );
3237 TPythonDump() << _this() << ".ExportPartToMED( "
3238 << meshPart << ", r'" << file << "', "
3239 << auto_groups << ", " << version << ", " << overwrite << ", "
3240 << autoDimension << ", " << goList
3241 << ", '" << ( geomAssocFields ? geomAssocFields : "" ) << "'" << " )";
3243 SMESH_CATCH( SMESH::throwCorbaException );
3246 //================================================================================
3248 * Write GEOM fields to MED file
3250 //================================================================================
3252 void SMESH_Mesh_i::exportMEDFields( DriverMED_W_Field& fieldWriter,
3253 SMESHDS_Mesh* meshDS,
3254 const GEOM::ListOfFields& fields,
3255 const char* geomAssocFields)
3257 #define METH "SMESH_Mesh_i::exportMEDFields() "
3259 if (( fields.length() < 1 ) &&
3260 ( !geomAssocFields || !geomAssocFields[0] ))
3263 std::vector< double > dblVals( meshDS->MaxShapeIndex()+1 );
3264 std::vector< int > intVals( meshDS->MaxShapeIndex()+1 );
3265 std::vector< int > subIdsByDim[ 4 ];
3266 const double noneDblValue = 0.;
3267 const double noneIntValue = 0;
3269 for ( size_t iF = 0; iF < fields.length(); ++iF )
3273 int dim = fields[ iF ]->GetDimension();
3274 SMDSAbs_ElementType elemType;
3275 TopAbs_ShapeEnum shapeType;
3277 case 0: elemType = SMDSAbs_0DElement; shapeType = TopAbs_VERTEX; break;
3278 case 1: elemType = SMDSAbs_Edge; shapeType = TopAbs_EDGE; break;
3279 case 2: elemType = SMDSAbs_Face; shapeType = TopAbs_FACE; break;
3280 case 3: elemType = SMDSAbs_Volume; shapeType = TopAbs_SOLID; break;
3282 continue; // skip fields on whole shape
3284 GEOM::field_data_type dataType = fields[ iF ]->GetDataType();
3285 if ( dataType == GEOM::FDT_String )
3287 GEOM::ListOfLong_var stepIDs = fields[ iF ]->GetSteps();
3288 if ( stepIDs->length() < 1 )
3290 GEOM::string_array_var comps = fields[ iF ]->GetComponents();
3291 if ( comps->length() < 1 )
3293 CORBA::String_var name = fields[ iF ]->GetName();
3295 if ( !fieldWriter.Set( meshDS,
3299 /*isIntData=*/false ))//( dataType == GEOM::FDT_Int )))
3302 for ( size_t iC = 0; iC < comps->length(); ++iC )
3303 fieldWriter.SetCompName( iC, comps[ iC ].in() );
3305 // find sub-shape IDs
3307 std::vector< int >& subIds = subIdsByDim[ dim ];
3308 if ( subIds.empty() )
3309 for ( int id = 1; id <= meshDS->MaxShapeIndex(); ++id )
3310 if ( meshDS->IndexToShape( id ).ShapeType() == shapeType )
3311 subIds.push_back( id );
3315 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3319 for ( size_t iS = 0; iS < stepIDs->length(); ++iS )
3321 GEOM::GEOM_FieldStep_var step = fields[ iF ]->GetStep( stepIDs[ iS ]);
3322 if ( step->_is_nil() )
3325 CORBA::Long stamp = step->GetStamp();
3326 CORBA::Long id = step->GetID();
3327 fieldWriter.SetDtIt( int( stamp ), int( id ));
3329 // fill dblVals or intVals
3332 case GEOM::FDT_Double:
3334 GEOM::GEOM_DoubleFieldStep_var dblStep = GEOM::GEOM_DoubleFieldStep::_narrow( step );
3335 if ( dblStep->_is_nil() ) continue;
3336 GEOM::ListOfDouble_var vv = dblStep->GetValues();
3337 if ( vv->length() != subIds.size() )
3338 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3339 for ( size_t i = 0; i < vv->length(); ++i )
3340 dblVals[ subIds[ i ]] = vv[ i ];
3345 GEOM::GEOM_IntFieldStep_var intStep = GEOM::GEOM_IntFieldStep::_narrow( step );
3346 if ( intStep->_is_nil() ) continue;
3347 GEOM::ListOfLong_var vv = intStep->GetValues();
3348 if ( vv->length() != subIds.size() )
3349 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3350 for ( size_t i = 0; i < vv->length(); ++i )
3351 intVals[ subIds[ i ]] = (int) vv[ i ];
3354 case GEOM::FDT_Bool:
3356 GEOM::GEOM_BoolFieldStep_var boolStep = GEOM::GEOM_BoolFieldStep::_narrow( step );
3357 if ( boolStep->_is_nil() ) continue;
3358 GEOM::short_array_var vv = boolStep->GetValues();
3359 if ( vv->length() != subIds.size() )
3360 THROW_SALOME_CORBA_EXCEPTION( METH "BUG: wrong nb subIds", SALOME::INTERNAL_ERROR );
3361 for ( size_t i = 0; i < vv->length(); ++i )
3362 intVals[ subIds[ i ]] = (int) vv[ i ];
3368 // pass values to fieldWriter
3369 elemIt = fieldWriter.GetOrderedElems();
3370 if ( dataType == GEOM::FDT_Double )
3371 while ( elemIt->more() )
3373 const SMDS_MeshElement* e = elemIt->next();
3374 const int shapeID = e->getshapeId();
3375 if ( shapeID < 1 || shapeID >= dblVals.size() )
3376 fieldWriter.AddValue( noneDblValue );
3378 fieldWriter.AddValue( dblVals[ shapeID ]);
3381 while ( elemIt->more() )
3383 const SMDS_MeshElement* e = elemIt->next();
3384 const int shapeID = e->getshapeId();
3385 if ( shapeID < 1 || shapeID >= intVals.size() )
3386 fieldWriter.AddValue( (double) noneIntValue );
3388 fieldWriter.AddValue( (double) intVals[ shapeID ]);
3392 fieldWriter.Perform();
3393 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3394 if ( res && res->IsKO() )
3396 if ( res->myComment.empty() )
3397 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3399 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3405 if ( !geomAssocFields || !geomAssocFields[0] )
3408 // write geomAssocFields
3410 std::vector< int > shapeDim( TopAbs_SHAPE + 1 );
3411 shapeDim[ TopAbs_COMPOUND ] = 3;
3412 shapeDim[ TopAbs_COMPSOLID ] = 3;
3413 shapeDim[ TopAbs_SOLID ] = 3;
3414 shapeDim[ TopAbs_SHELL ] = 2;
3415 shapeDim[ TopAbs_FACE ] = 2;
3416 shapeDim[ TopAbs_WIRE ] = 1;
3417 shapeDim[ TopAbs_EDGE ] = 1;
3418 shapeDim[ TopAbs_VERTEX ] = 0;
3419 shapeDim[ TopAbs_SHAPE ] = 3;
3421 for ( int iF = 0; geomAssocFields[ iF ]; ++iF )
3423 std::vector< std::string > compNames;
3424 switch ( geomAssocFields[ iF ]) {
3426 fieldWriter.Set( meshDS, "_vertices_", SMDSAbs_Node, /*nbComps=*/2, /*isInt=*/false );
3427 compNames.push_back( "dim" );
3430 fieldWriter.Set( meshDS, "_edges_", SMDSAbs_Edge, /*nbComps=*/1, /*isInt=*/false );
3433 fieldWriter.Set( meshDS, "_faces_", SMDSAbs_Face, /*nbComps=*/1, /*isInt=*/false );
3436 fieldWriter.Set( meshDS, "_solids_", SMDSAbs_Volume, /*nbComps=*/1, /*isInt=*/false );
3440 compNames.push_back( "id" );
3441 for ( size_t iC = 0; iC < compNames.size(); ++iC )
3442 fieldWriter.SetCompName( iC, compNames[ iC ].c_str() );
3444 fieldWriter.SetDtIt( -1, -1 );
3446 SMDS_ElemIteratorPtr elemIt = fieldWriter.GetOrderedElems();
3450 if ( compNames.size() == 2 ) // _vertices_
3451 while ( elemIt->more() )
3453 const SMDS_MeshElement* e = elemIt->next();
3454 const int shapeID = e->getshapeId();
3457 fieldWriter.AddValue( (double) -1 );
3458 fieldWriter.AddValue( (double) -1 );
3462 const TopoDS_Shape& S = meshDS->IndexToShape( shapeID );
3463 fieldWriter.AddValue( (double) ( S.IsNull() ? -1 : shapeDim[ S.ShapeType() ]));
3464 fieldWriter.AddValue( (double) shapeID );
3468 while ( elemIt->more() )
3470 const SMDS_MeshElement* e = elemIt->next();
3471 const int shapeID = e->getshapeId();
3473 fieldWriter.AddValue( (double) -1 );
3475 fieldWriter.AddValue( (double) shapeID );
3479 fieldWriter.Perform();
3480 SMESH_ComputeErrorPtr res = fieldWriter.GetError();
3481 if ( res && res->IsKO() )
3483 if ( res->myComment.empty() )
3484 { THROW_SALOME_CORBA_EXCEPTION( METH "Fatal error", SALOME::INTERNAL_ERROR ); }
3486 { THROW_SALOME_CORBA_EXCEPTION( res->myComment.c_str(), SALOME::INTERNAL_ERROR ); }
3489 } // loop on geomAssocFields
3494 //================================================================================
3496 * \brief Export a part of mesh to a DAT file
3498 //================================================================================
3500 void SMESH_Mesh_i::ExportPartToDAT(::SMESH::SMESH_IDSource_ptr meshPart,
3502 throw (SALOME::SALOME_Exception)
3504 Unexpect aCatch(SALOME_SalomeException);
3506 _preMeshInfo->FullLoadFromFile();
3508 PrepareForWriting(file);
3510 SMESH_MeshPartDS partDS( meshPart );
3511 _impl->ExportDAT(file,&partDS);
3513 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3514 << ".ExportPartToDAT( " << meshPart << ", r'" << file << "' )";
3516 //================================================================================
3518 * \brief Export a part of mesh to an UNV file
3520 //================================================================================
3522 void SMESH_Mesh_i::ExportPartToUNV(::SMESH::SMESH_IDSource_ptr meshPart,
3524 throw (SALOME::SALOME_Exception)
3526 Unexpect aCatch(SALOME_SalomeException);
3528 _preMeshInfo->FullLoadFromFile();
3530 PrepareForWriting(file);
3532 SMESH_MeshPartDS partDS( meshPart );
3533 _impl->ExportUNV(file, &partDS);
3535 TPythonDump() << SMESH::SMESH_Mesh_var(_this())
3536 << ".ExportPartToUNV( " << meshPart<< ", r'" << file << "' )";
3538 //================================================================================
3540 * \brief Export a part of mesh to an STL file
3542 //================================================================================
3544 void SMESH_Mesh_i::ExportPartToSTL(::SMESH::SMESH_IDSource_ptr meshPart,
3546 ::CORBA::Boolean isascii)
3547 throw (SALOME::SALOME_Exception)
3549 Unexpect aCatch(SALOME_SalomeException);
3551 _preMeshInfo->FullLoadFromFile();
3553 PrepareForWriting(file);
3555 SMESH_MeshPartDS partDS( meshPart );
3556 _impl->ExportSTL(file, isascii, &partDS);
3558 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportPartToSTL( "
3559 << meshPart<< ", r'" << file << "', " << isascii << ")";
3562 //================================================================================
3564 * \brief Export a part of mesh to an STL file
3566 //================================================================================
3568 void SMESH_Mesh_i::ExportCGNS(::SMESH::SMESH_IDSource_ptr meshPart,
3570 CORBA::Boolean overwrite)
3571 throw (SALOME::SALOME_Exception)
3574 Unexpect aCatch(SALOME_SalomeException);
3576 _preMeshInfo->FullLoadFromFile();
3578 PrepareForWriting(file,overwrite);
3580 SMESH_MeshPartDS partDS( meshPart );
3581 _impl->ExportCGNS(file, &partDS);
3583 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportCGNS( "
3584 << meshPart<< ", r'" << file << "', " << overwrite << ")";
3586 THROW_SALOME_CORBA_EXCEPTION("CGNS library is unavailable", SALOME::INTERNAL_ERROR);
3590 //================================================================================
3592 * \brief Export a part of mesh to a GMF file
3594 //================================================================================
3596 void SMESH_Mesh_i::ExportGMF(::SMESH::SMESH_IDSource_ptr meshPart,
3598 bool withRequiredGroups)
3599 throw (SALOME::SALOME_Exception)
3601 Unexpect aCatch(SALOME_SalomeException);
3603 _preMeshInfo->FullLoadFromFile();
3605 PrepareForWriting(file,/*overwrite=*/true);
3607 SMESH_MeshPartDS partDS( meshPart );
3608 _impl->ExportGMF(file, &partDS, withRequiredGroups);
3610 TPythonDump() << SMESH::SMESH_Mesh_var(_this()) << ".ExportGMF( "
3611 << meshPart<< ", r'"
3613 << withRequiredGroups << ")";
3616 //=============================================================================
3618 * Return computation progress [0.,1]
3620 //=============================================================================
3622 CORBA::Double SMESH_Mesh_i::GetComputeProgress()
3626 return _impl->GetComputeProgress();
3628 SMESH_CATCH( SMESH::doNothing );
3632 CORBA::Long SMESH_Mesh_i::NbNodes()throw(SALOME::SALOME_Exception)
3634 Unexpect aCatch(SALOME_SalomeException);
3636 return _preMeshInfo->NbNodes();
3638 return _impl->NbNodes();
3641 CORBA::Long SMESH_Mesh_i::NbElements()throw (SALOME::SALOME_Exception)
3643 Unexpect aCatch(SALOME_SalomeException);
3645 return _preMeshInfo->NbElements();
3647 return Nb0DElements() + NbEdges() + NbFaces() + NbVolumes() + NbBalls();
3650 CORBA::Long SMESH_Mesh_i::Nb0DElements()throw (SALOME::SALOME_Exception)
3652 Unexpect aCatch(SALOME_SalomeException);
3654 return _preMeshInfo->Nb0DElements();
3656 return _impl->Nb0DElements();
3659 CORBA::Long SMESH_Mesh_i::NbBalls() throw (SALOME::SALOME_Exception)
3661 Unexpect aCatch(SALOME_SalomeException);
3663 return _preMeshInfo->NbBalls();
3665 return _impl->NbBalls();
3668 CORBA::Long SMESH_Mesh_i::NbEdges()throw(SALOME::SALOME_Exception)
3670 Unexpect aCatch(SALOME_SalomeException);
3672 return _preMeshInfo->NbEdges();
3674 return _impl->NbEdges();
3677 CORBA::Long SMESH_Mesh_i::NbEdgesOfOrder(SMESH::ElementOrder order)
3678 throw(SALOME::SALOME_Exception)
3680 Unexpect aCatch(SALOME_SalomeException);
3682 return _preMeshInfo->NbEdges( (SMDSAbs_ElementOrder) order );
3684 return _impl->NbEdges( (SMDSAbs_ElementOrder) order);
3687 //=============================================================================
3689 CORBA::Long SMESH_Mesh_i::NbFaces()throw(SALOME::SALOME_Exception)
3691 Unexpect aCatch(SALOME_SalomeException);
3693 return _preMeshInfo->NbFaces();
3695 return _impl->NbFaces();
3698 CORBA::Long SMESH_Mesh_i::NbTriangles()throw(SALOME::SALOME_Exception)
3700 Unexpect aCatch(SALOME_SalomeException);
3702 return _preMeshInfo->NbTriangles();
3704 return _impl->NbTriangles();
3707 CORBA::Long SMESH_Mesh_i::NbBiQuadTriangles()throw(SALOME::SALOME_Exception)
3709 Unexpect aCatch(SALOME_SalomeException);
3711 return _preMeshInfo->NbBiQuadTriangles();
3713 return _impl->NbBiQuadTriangles();
3716 CORBA::Long SMESH_Mesh_i::NbQuadrangles()throw(SALOME::SALOME_Exception)
3718 Unexpect aCatch(SALOME_SalomeException);
3720 return _preMeshInfo->NbQuadrangles();
3722 return _impl->NbQuadrangles();
3725 CORBA::Long SMESH_Mesh_i::NbBiQuadQuadrangles()throw(SALOME::SALOME_Exception)
3727 Unexpect aCatch(SALOME_SalomeException);
3729 return _preMeshInfo->NbBiQuadQuadrangles();
3731 return _impl->NbBiQuadQuadrangles();
3734 CORBA::Long SMESH_Mesh_i::NbPolygons()throw(SALOME::SALOME_Exception)
3736 Unexpect aCatch(SALOME_SalomeException);
3738 return _preMeshInfo->NbPolygons();
3740 return _impl->NbPolygons();
3743 CORBA::Long SMESH_Mesh_i::NbFacesOfOrder(SMESH::ElementOrder order)
3744 throw(SALOME::SALOME_Exception)
3746 Unexpect aCatch(SALOME_SalomeException);
3748 return _preMeshInfo->NbFaces( (SMDSAbs_ElementOrder) order );
3750 return _impl->NbFaces( (SMDSAbs_ElementOrder) order);
3753 CORBA::Long SMESH_Mesh_i::NbTrianglesOfOrder(SMESH::ElementOrder order)
3754 throw(SALOME::SALOME_Exception)
3756 Unexpect aCatch(SALOME_SalomeException);
3758 return _preMeshInfo->NbTriangles( (SMDSAbs_ElementOrder) order );
3760 return _impl->NbTriangles( (SMDSAbs_ElementOrder) order);
3763 CORBA::Long SMESH_Mesh_i::NbQuadranglesOfOrder(SMESH::ElementOrder order)
3764 throw(SALOME::SALOME_Exception)
3766 Unexpect aCatch(SALOME_SalomeException);
3768 return _preMeshInfo->NbQuadrangles( (SMDSAbs_ElementOrder) order );
3770 return _impl->NbQuadrangles( (SMDSAbs_ElementOrder) order);
3773 //=============================================================================
3775 CORBA::Long SMESH_Mesh_i::NbVolumes()throw(SALOME::SALOME_Exception)
3777 Unexpect aCatch(SALOME_SalomeException);
3779 return _preMeshInfo->NbVolumes();
3781 return _impl->NbVolumes();
3784 CORBA::Long SMESH_Mesh_i::NbTetras()throw(SALOME::SALOME_Exception)
3786 Unexpect aCatch(SALOME_SalomeException);
3788 return _preMeshInfo->NbTetras();
3790 return _impl->NbTetras();
3793 CORBA::Long SMESH_Mesh_i::NbHexas()throw(SALOME::SALOME_Exception)
3795 Unexpect aCatch(SALOME_SalomeException);
3797 return _preMeshInfo->NbHexas();
3799 return _impl->NbHexas();
3802 CORBA::Long SMESH_Mesh_i::NbTriQuadraticHexas()throw(SALOME::SALOME_Exception)
3804 Unexpect aCatch(SALOME_SalomeException);
3806 return _preMeshInfo->NbTriQuadHexas();
3808 return _impl->NbTriQuadraticHexas();
3811 CORBA::Long SMESH_Mesh_i::NbPyramids()throw(SALOME::SALOME_Exception)
3813 Unexpect aCatch(SALOME_SalomeException);
3815 return _preMeshInfo->NbPyramids();
3817 return _impl->NbPyramids();
3820 CORBA::Long SMESH_Mesh_i::NbPrisms()throw(SALOME::SALOME_Exception)
3822 Unexpect aCatch(SALOME_SalomeException);
3824 return _preMeshInfo->NbPrisms();
3826 return _impl->NbPrisms();
3829 CORBA::Long SMESH_Mesh_i::NbHexagonalPrisms()throw(SALOME::SALOME_Exception)
3831 Unexpect aCatch(SALOME_SalomeException);
3833 return _preMeshInfo->NbHexPrisms();
3835 return _impl->NbHexagonalPrisms();
3838 CORBA::Long SMESH_Mesh_i::NbPolyhedrons()throw(SALOME::SALOME_Exception)
3840 Unexpect aCatch(SALOME_SalomeException);
3842 return _preMeshInfo->NbPolyhedrons();
3844 return _impl->NbPolyhedrons();
3847 CORBA::Long SMESH_Mesh_i::NbVolumesOfOrder(SMESH::ElementOrder order)
3848 throw(SALOME::SALOME_Exception)
3850 Unexpect aCatch(SALOME_SalomeException);
3852 return _preMeshInfo->NbVolumes( (SMDSAbs_ElementOrder) order );
3854 return _impl->NbVolumes( (SMDSAbs_ElementOrder) order);
3857 CORBA::Long SMESH_Mesh_i::NbTetrasOfOrder(SMESH::ElementOrder order)
3858 throw(SALOME::SALOME_Exception)
3860 Unexpect aCatch(SALOME_SalomeException);
3862 return _preMeshInfo->NbTetras( (SMDSAbs_ElementOrder) order);
3864 return _impl->NbTetras( (SMDSAbs_ElementOrder) order);
3867 CORBA::Long SMESH_Mesh_i::NbHexasOfOrder(SMESH::ElementOrder order)
3868 throw(SALOME::SALOME_Exception)
3870 Unexpect aCatch(SALOME_SalomeException);
3872 return _preMeshInfo->NbHexas( (SMDSAbs_ElementOrder) order);
3874 return _impl->NbHexas( (SMDSAbs_ElementOrder) order);
3877 CORBA::Long SMESH_Mesh_i::NbPyramidsOfOrder(SMESH::ElementOrder order)
3878 throw(SALOME::SALOME_Exception)
3880 Unexpect aCatch(SALOME_SalomeException);
3882 return _preMeshInfo->NbPyramids( (SMDSAbs_ElementOrder) order);
3884 return _impl->NbPyramids( (SMDSAbs_ElementOrder) order);
3887 CORBA::Long SMESH_Mesh_i::NbPrismsOfOrder(SMESH::ElementOrder order)
3888 throw(SALOME::SALOME_Exception)
3890 Unexpect aCatch(SALOME_SalomeException);
3892 return _preMeshInfo->NbPrisms( (SMDSAbs_ElementOrder) order);
3894 return _impl->NbPrisms( (SMDSAbs_ElementOrder) order);
3897 //=============================================================================
3899 * Returns nb of published sub-meshes
3901 //=============================================================================
3903 CORBA::Long SMESH_Mesh_i::NbSubMesh()throw(SALOME::SALOME_Exception)
3905 Unexpect aCatch(SALOME_SalomeException);
3906 return _mapSubMesh_i.size();
3909 //=============================================================================
3911 * Dumps mesh into a string
3913 //=============================================================================
3915 char* SMESH_Mesh_i::Dump()
3919 return CORBA::string_dup( os.str().c_str() );
3922 //=============================================================================
3924 * Method of SMESH_IDSource interface
3926 //=============================================================================
3928 SMESH::long_array* SMESH_Mesh_i::GetIDs()
3930 return GetElementsId();
3933 //=============================================================================
3935 * Returns ids of all elements
3937 //=============================================================================
3939 SMESH::long_array* SMESH_Mesh_i::GetElementsId()
3940 throw (SALOME::SALOME_Exception)
3942 Unexpect aCatch(SALOME_SalomeException);
3944 _preMeshInfo->FullLoadFromFile();
3946 SMESH::long_array_var aResult = new SMESH::long_array();
3947 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3949 if ( aSMESHDS_Mesh == NULL )
3950 return aResult._retn();
3952 long nbElements = NbElements();
3953 aResult->length( nbElements );
3954 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator();
3955 for ( int i = 0, n = nbElements; i < n && anIt->more(); i++ )
3956 aResult[i] = anIt->next()->GetID();
3958 return aResult._retn();
3962 //=============================================================================
3964 * Returns ids of all elements of given type
3966 //=============================================================================
3968 SMESH::long_array* SMESH_Mesh_i::GetElementsByType( SMESH::ElementType theElemType )
3969 throw (SALOME::SALOME_Exception)
3971 Unexpect aCatch(SALOME_SalomeException);
3973 _preMeshInfo->FullLoadFromFile();
3975 SMESH::long_array_var aResult = new SMESH::long_array();
3976 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
3978 if ( aSMESHDS_Mesh == NULL )
3979 return aResult._retn();
3981 long nbElements = NbElements();
3983 // No sense in returning ids of elements along with ids of nodes:
3984 // when theElemType == SMESH::ALL, return node ids only if
3985 // there are no elements
3986 if ( theElemType == SMESH::NODE || (theElemType == SMESH::ALL && nbElements == 0) )
3987 return GetNodesId();
3989 aResult->length( nbElements );
3993 SMDS_ElemIteratorPtr anIt = aSMESHDS_Mesh->elementsIterator( (SMDSAbs_ElementType)theElemType );
3994 while ( i < nbElements && anIt->more() )
3995 aResult[i++] = anIt->next()->GetID();
3997 aResult->length( i );
3999 return aResult._retn();
4002 //=============================================================================
4004 * Returns ids of all nodes
4006 //=============================================================================
4008 SMESH::long_array* SMESH_Mesh_i::GetNodesId()
4009 throw (SALOME::SALOME_Exception)
4011 Unexpect aCatch(SALOME_SalomeException);
4013 _preMeshInfo->FullLoadFromFile();
4015 SMESH::long_array_var aResult = new SMESH::long_array();
4016 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4018 if ( aSMESHDS_Mesh == NULL )
4019 return aResult._retn();
4021 long nbNodes = NbNodes();
4022 aResult->length( nbNodes );
4023 SMDS_NodeIteratorPtr anIt = aSMESHDS_Mesh->nodesIterator(/*idInceasingOrder=*/true);
4024 for ( int i = 0, n = nbNodes; i < n && anIt->more(); i++ )
4025 aResult[i] = anIt->next()->GetID();
4027 return aResult._retn();
4030 //=============================================================================
4034 //=============================================================================
4036 SMESH::ElementType SMESH_Mesh_i::GetElementType( const CORBA::Long id, const bool iselem )
4037 throw (SALOME::SALOME_Exception)
4039 SMESH::ElementType type;
4043 _preMeshInfo->FullLoadFromFile();
4045 type = ( SMESH::ElementType ) _impl->GetElementType( id, iselem );
4047 SMESH_CATCH( SMESH::throwCorbaException );
4052 //=============================================================================
4056 //=============================================================================
4058 SMESH::EntityType SMESH_Mesh_i::GetElementGeomType( const CORBA::Long id )
4059 throw (SALOME::SALOME_Exception)
4062 _preMeshInfo->FullLoadFromFile();
4064 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4066 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4068 return ( SMESH::EntityType ) e->GetEntityType();
4071 //=============================================================================
4075 //=============================================================================
4077 SMESH::GeometryType SMESH_Mesh_i::GetElementShape( const CORBA::Long id )
4078 throw (SALOME::SALOME_Exception)
4081 _preMeshInfo->FullLoadFromFile();
4083 const SMDS_MeshElement* e = _impl->GetMeshDS()->FindElement(id);
4085 THROW_SALOME_CORBA_EXCEPTION( "invalid element id", SALOME::BAD_PARAM );
4087 return ( SMESH::GeometryType ) e->GetGeomType();
4090 //=============================================================================
4092 * Returns ID of elements for given submesh
4094 //=============================================================================
4095 SMESH::long_array* SMESH_Mesh_i::GetSubMeshElementsId(const CORBA::Long ShapeID)
4096 throw (SALOME::SALOME_Exception)
4098 SMESH::long_array_var aResult = new SMESH::long_array();
4102 _preMeshInfo->FullLoadFromFile();
4104 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4105 if(!SM) return aResult._retn();
4107 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4108 if(!SDSM) return aResult._retn();
4110 aResult->length(SDSM->NbElements());
4112 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4114 while ( eIt->more() ) {
4115 aResult[i++] = eIt->next()->GetID();
4118 SMESH_CATCH( SMESH::throwCorbaException );
4120 return aResult._retn();
4123 //=============================================================================
4125 * Returns ID of nodes for given submesh
4126 * If param all==true - returns all nodes, else -
4127 * returns only nodes on shapes.
4129 //=============================================================================
4131 SMESH::long_array* SMESH_Mesh_i::GetSubMeshNodesId(const CORBA::Long ShapeID,
4133 throw (SALOME::SALOME_Exception)
4135 SMESH::long_array_var aResult = new SMESH::long_array();
4139 _preMeshInfo->FullLoadFromFile();
4141 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4142 if(!SM) return aResult._retn();
4144 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4145 if(!SDSM) return aResult._retn();
4148 if( !all || (SDSM->NbElements()==0) ) { // internal nodes or vertex submesh
4149 SMDS_NodeIteratorPtr nIt = SDSM->GetNodes();
4150 while ( nIt->more() ) {
4151 const SMDS_MeshNode* elem = nIt->next();
4152 theElems.insert( elem->GetID() );
4155 else { // all nodes of submesh elements
4156 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4157 while ( eIt->more() ) {
4158 const SMDS_MeshElement* anElem = eIt->next();
4159 SMDS_ElemIteratorPtr nIt = anElem->nodesIterator();
4160 while ( nIt->more() ) {
4161 const SMDS_MeshElement* elem = nIt->next();
4162 theElems.insert( elem->GetID() );
4167 aResult->length(theElems.size());
4168 set<int>::iterator itElem;
4170 for ( itElem = theElems.begin(); itElem != theElems.end(); itElem++ )
4171 aResult[i++] = *itElem;
4173 SMESH_CATCH( SMESH::throwCorbaException );
4175 return aResult._retn();
4178 //=============================================================================
4180 * Returns type of elements for given submesh
4182 //=============================================================================
4184 SMESH::ElementType SMESH_Mesh_i::GetSubMeshElementType(const CORBA::Long ShapeID)
4185 throw (SALOME::SALOME_Exception)
4187 SMESH::ElementType type;
4191 _preMeshInfo->FullLoadFromFile();
4193 SMESH_subMesh* SM = _impl->GetSubMeshContaining(ShapeID);
4194 if(!SM) return SMESH::ALL;
4196 SMESHDS_SubMesh* SDSM = SM->GetSubMeshDS();
4197 if(!SDSM) return SMESH::ALL;
4199 if(SDSM->NbElements()==0)
4200 return (SM->GetSubShape().ShapeType() == TopAbs_VERTEX) ? SMESH::NODE : SMESH::ALL;
4202 SMDS_ElemIteratorPtr eIt = SDSM->GetElements();
4203 const SMDS_MeshElement* anElem = eIt->next();
4205 type = ( SMESH::ElementType ) anElem->GetType();
4207 SMESH_CATCH( SMESH::throwCorbaException );
4213 //=============================================================================
4215 * Returns pointer to _impl as an integer value. Is called from constructor of SMESH_Client
4217 //=============================================================================
4219 CORBA::LongLong SMESH_Mesh_i::GetMeshPtr()
4222 _preMeshInfo->FullLoadFromFile();
4224 CORBA::LongLong pointeur = CORBA::LongLong(_impl);
4226 MESSAGE("CORBA::LongLong SMESH_Mesh_i::GetMeshPtr() "<<pointeur);
4231 //=============================================================================
4233 * Get XYZ coordinates of node as list of double
4234 * If there is not node for given ID - returns empty list
4236 //=============================================================================
4238 SMESH::double_array* SMESH_Mesh_i::GetNodeXYZ(const CORBA::Long id)
4241 _preMeshInfo->FullLoadFromFile();
4243 SMESH::double_array_var aResult = new SMESH::double_array();
4244 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4245 if ( aSMESHDS_Mesh == NULL )
4246 return aResult._retn();
4249 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4251 return aResult._retn();
4255 aResult[0] = aNode->X();
4256 aResult[1] = aNode->Y();
4257 aResult[2] = aNode->Z();
4258 return aResult._retn();
4262 //=============================================================================
4264 * For given node returns list of IDs of inverse elements
4265 * If there is not node for given ID - returns empty list
4267 //=============================================================================
4269 SMESH::long_array* SMESH_Mesh_i::GetNodeInverseElements(const CORBA::Long id)
4272 _preMeshInfo->FullLoadFromFile();
4274 SMESH::long_array_var aResult = new SMESH::long_array();
4275 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4276 if ( aSMESHDS_Mesh == NULL )
4277 return aResult._retn();
4280 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4282 return aResult._retn();
4284 // find inverse elements
4285 SMDS_ElemIteratorPtr eIt = aNode->GetInverseElementIterator();
4286 aResult->length( aNode->NbInverseElements() );
4287 for( int i = 0; eIt->more(); ++i )
4289 const SMDS_MeshElement* elem = eIt->next();
4290 aResult[ i ] = elem->GetID();
4292 return aResult._retn();
4295 //=============================================================================
4297 * \brief Return position of a node on shape
4299 //=============================================================================
4301 SMESH::NodePosition* SMESH_Mesh_i::GetNodePosition(CORBA::Long NodeID)
4304 _preMeshInfo->FullLoadFromFile();
4306 SMESH::NodePosition* aNodePosition = new SMESH::NodePosition();
4307 aNodePosition->shapeID = 0;
4308 aNodePosition->shapeType = GEOM::SHAPE;
4310 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4311 if ( !mesh ) return aNodePosition;
4313 if ( const SMDS_MeshNode* aNode = mesh->FindNode(NodeID) )
4315 if ( SMDS_PositionPtr pos = aNode->GetPosition() )
4317 aNodePosition->shapeID = aNode->getshapeId();
4318 switch ( pos->GetTypeOfPosition() ) {
4320 aNodePosition->shapeType = GEOM::EDGE;
4321 aNodePosition->params.length(1);
4322 aNodePosition->params[0] =
4323 static_cast<SMDS_EdgePosition*>( pos )->GetUParameter();
4326 aNodePosition->shapeType = GEOM::FACE;
4327 aNodePosition->params.length(2);
4328 aNodePosition->params[0] =
4329 static_cast<SMDS_FacePosition*>( pos )->GetUParameter();
4330 aNodePosition->params[1] =
4331 static_cast<SMDS_FacePosition*>( pos )->GetVParameter();
4333 case SMDS_TOP_VERTEX:
4334 aNodePosition->shapeType = GEOM::VERTEX;
4336 case SMDS_TOP_3DSPACE:
4337 if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SOLID).More() )
4338 aNodePosition->shapeType = GEOM::SOLID;
4339 else if ( TopExp_Explorer(_impl->GetShapeToMesh(), TopAbs_SHELL).More() )
4340 aNodePosition->shapeType = GEOM::SHELL;
4346 return aNodePosition;
4349 //=============================================================================
4351 * \brief Return position of an element on shape
4353 //=============================================================================
4355 SMESH::ElementPosition SMESH_Mesh_i::GetElementPosition(CORBA::Long ElemID)
4358 _preMeshInfo->FullLoadFromFile();
4360 SMESH::ElementPosition anElementPosition;
4361 anElementPosition.shapeID = 0;
4362 anElementPosition.shapeType = GEOM::SHAPE;
4364 SMESHDS_Mesh* mesh = _impl->GetMeshDS();
4365 if ( !mesh ) return anElementPosition;
4367 if ( const SMDS_MeshElement* anElem = mesh->FindElement( ElemID ) )
4369 anElementPosition.shapeID = anElem->getshapeId();
4370 const TopoDS_Shape& aSp = mesh->IndexToShape( anElem->getshapeId() );
4371 if ( !aSp.IsNull() ) {
4372 switch ( aSp.ShapeType() ) {
4374 anElementPosition.shapeType = GEOM::EDGE;
4377 anElementPosition.shapeType = GEOM::FACE;
4380 anElementPosition.shapeType = GEOM::VERTEX;
4383 anElementPosition.shapeType = GEOM::SOLID;
4386 anElementPosition.shapeType = GEOM::SHELL;
4392 return anElementPosition;
4395 //=============================================================================
4397 * If given element is node returns IDs of shape from position
4398 * If there is not node for given ID - returns -1
4400 //=============================================================================
4402 CORBA::Long SMESH_Mesh_i::GetShapeID(const CORBA::Long id)
4405 _preMeshInfo->FullLoadFromFile();
4407 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4408 if ( aSMESHDS_Mesh == NULL )
4412 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(id);
4414 return aNode->getshapeId();
4421 //=============================================================================
4423 * For given element returns ID of result shape after
4424 * ::FindShape() from SMESH_MeshEditor
4425 * If there is not element for given ID - returns -1
4427 //=============================================================================
4429 CORBA::Long SMESH_Mesh_i::GetShapeIDForElem(const CORBA::Long id)
4432 _preMeshInfo->FullLoadFromFile();
4434 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4435 if ( aSMESHDS_Mesh == NULL )
4438 // try to find element
4439 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4443 ::SMESH_MeshEditor aMeshEditor(_impl);
4444 int index = aMeshEditor.FindShape( elem );
4452 //=============================================================================
4454 * Returns number of nodes for given element
4455 * If there is not element for given ID - returns -1
4457 //=============================================================================
4459 CORBA::Long SMESH_Mesh_i::GetElemNbNodes(const CORBA::Long id)
4462 _preMeshInfo->FullLoadFromFile();
4464 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4465 if ( aSMESHDS_Mesh == NULL ) return -1;
4466 // try to find element
4467 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4468 if(!elem) return -1;
4469 return elem->NbNodes();
4473 //=============================================================================
4475 * Returns ID of node by given index for given element
4476 * If there is not element for given ID - returns -1
4477 * If there is not node for given index - returns -2
4479 //=============================================================================
4481 CORBA::Long SMESH_Mesh_i::GetElemNode(const CORBA::Long id, const CORBA::Long index)
4484 _preMeshInfo->FullLoadFromFile();
4486 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4487 if ( aSMESHDS_Mesh == NULL ) return -1;
4488 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4489 if(!elem) return -1;
4490 if( index>=elem->NbNodes() || index<0 ) return -1;
4491 return elem->GetNode(index)->GetID();
4494 //=============================================================================
4496 * Returns IDs of nodes of given element
4498 //=============================================================================
4500 SMESH::long_array* SMESH_Mesh_i::GetElemNodes(const CORBA::Long id)
4503 _preMeshInfo->FullLoadFromFile();
4505 SMESH::long_array_var aResult = new SMESH::long_array();
4506 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4508 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id) )
4510 aResult->length( elem->NbNodes() );
4511 for ( int i = 0; i < elem->NbNodes(); ++i )
4512 aResult[ i ] = elem->GetNode( i )->GetID();
4515 return aResult._retn();
4518 //=============================================================================
4520 * Returns true if given node is medium node
4521 * in given quadratic element
4523 //=============================================================================
4525 CORBA::Boolean SMESH_Mesh_i::IsMediumNode(const CORBA::Long ide, const CORBA::Long idn)
4528 _preMeshInfo->FullLoadFromFile();
4530 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4531 if ( aSMESHDS_Mesh == NULL ) return false;
4533 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4534 if(!aNode) return false;
4535 // try to find element
4536 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(ide);
4537 if(!elem) return false;
4539 return elem->IsMediumNode(aNode);
4543 //=============================================================================
4545 * Returns true if given node is medium node
4546 * in one of quadratic elements
4548 //=============================================================================
4550 CORBA::Boolean SMESH_Mesh_i::IsMediumNodeOfAnyElem(const CORBA::Long idn,
4551 SMESH::ElementType theElemType)
4554 _preMeshInfo->FullLoadFromFile();
4556 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4557 if ( aSMESHDS_Mesh == NULL ) return false;
4560 const SMDS_MeshNode* aNode = aSMESHDS_Mesh->FindNode(idn);
4561 if(!aNode) return false;
4563 SMESH_MesherHelper aHelper( *(_impl) );
4565 SMDSAbs_ElementType aType;
4566 if(theElemType==SMESH::EDGE) aType = SMDSAbs_Edge;
4567 else if(theElemType==SMESH::FACE) aType = SMDSAbs_Face;
4568 else if(theElemType==SMESH::VOLUME) aType = SMDSAbs_Volume;
4569 else aType = SMDSAbs_All;
4571 return aHelper.IsMedium(aNode,aType);
4575 //=============================================================================
4577 * Returns number of edges for given element
4579 //=============================================================================
4581 CORBA::Long SMESH_Mesh_i::ElemNbEdges(const CORBA::Long id)
4584 _preMeshInfo->FullLoadFromFile();
4586 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4587 if ( aSMESHDS_Mesh == NULL ) return -1;
4588 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4589 if(!elem) return -1;
4590 return elem->NbEdges();
4594 //=============================================================================
4596 * Returns number of faces for given element
4598 //=============================================================================
4600 CORBA::Long SMESH_Mesh_i::ElemNbFaces(const CORBA::Long id)
4603 _preMeshInfo->FullLoadFromFile();
4605 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4606 if ( aSMESHDS_Mesh == NULL ) return -1;
4607 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4608 if(!elem) return -1;
4609 return elem->NbFaces();
4612 //=======================================================================
4613 //function : GetElemFaceNodes
4614 //purpose : Returns nodes of given face (counted from zero) for given element.
4615 //=======================================================================
4617 SMESH::long_array* SMESH_Mesh_i::GetElemFaceNodes(CORBA::Long elemId,
4618 CORBA::Short faceIndex)
4621 _preMeshInfo->FullLoadFromFile();
4623 SMESH::long_array_var aResult = new SMESH::long_array();
4624 if ( SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS() )
4626 if ( const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(elemId) )
4628 SMDS_VolumeTool vtool( elem );
4629 if ( faceIndex < vtool.NbFaces() )
4631 aResult->length( vtool.NbFaceNodes( faceIndex ));
4632 const SMDS_MeshNode** nn = vtool.GetFaceNodes( faceIndex );
4633 for ( int i = 0; i < aResult->length(); ++i )
4634 aResult[ i ] = nn[ i ]->GetID();
4638 return aResult._retn();
4641 //=======================================================================
4642 //function : GetElemFaceNodes
4643 //purpose : Returns three components of normal of given mesh face.
4644 //=======================================================================
4646 SMESH::double_array* SMESH_Mesh_i::GetFaceNormal(CORBA::Long elemId,
4647 CORBA::Boolean normalized)
4650 _preMeshInfo->FullLoadFromFile();
4652 SMESH::double_array_var aResult = new SMESH::double_array();
4654 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4657 if ( SMESH_MeshAlgos::FaceNormal( mesh->FindElement(elemId), normal, normalized ))
4659 aResult->length( 3 );
4660 aResult[ 0 ] = normal.X();
4661 aResult[ 1 ] = normal.Y();
4662 aResult[ 2 ] = normal.Z();
4665 return aResult._retn();
4668 //=======================================================================
4669 //function : FindElementByNodes
4670 //purpose : Returns an element based on all given nodes.
4671 //=======================================================================
4673 CORBA::Long SMESH_Mesh_i::FindElementByNodes(const SMESH::long_array& nodes)
4676 _preMeshInfo->FullLoadFromFile();
4678 CORBA::Long elemID(0);
4679 if ( SMESHDS_Mesh* mesh = _impl->GetMeshDS() )
4681 vector< const SMDS_MeshNode * > nn( nodes.length() );
4682 for ( int i = 0; i < nodes.length(); ++i )
4683 if ( !( nn[i] = mesh->FindNode( nodes[i] )))
4686 const SMDS_MeshElement* elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/false );
4687 if ( !elem && ( _impl->NbEdges ( ORDER_QUADRATIC ) ||
4688 _impl->NbFaces ( ORDER_QUADRATIC ) ||
4689 _impl->NbVolumes( ORDER_QUADRATIC )))
4690 elem = mesh->FindElement( nn, SMDSAbs_All, /*noMedium=*/true );
4692 if ( elem ) elemID = CORBA::Long( elem->GetID() );
4697 //=============================================================================
4699 * Returns true if given element is polygon
4701 //=============================================================================
4703 CORBA::Boolean SMESH_Mesh_i::IsPoly(const CORBA::Long id)
4706 _preMeshInfo->FullLoadFromFile();
4708 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4709 if ( aSMESHDS_Mesh == NULL ) return false;
4710 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4711 if(!elem) return false;
4712 return elem->IsPoly();
4716 //=============================================================================
4718 * Returns true if given element is quadratic
4720 //=============================================================================
4722 CORBA::Boolean SMESH_Mesh_i::IsQuadratic(const CORBA::Long id)
4725 _preMeshInfo->FullLoadFromFile();
4727 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4728 if ( aSMESHDS_Mesh == NULL ) return false;
4729 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4730 if(!elem) return false;
4731 return elem->IsQuadratic();
4734 //=============================================================================
4736 * Returns diameter of ball discrete element or zero in case of an invalid \a id
4738 //=============================================================================
4740 CORBA::Double SMESH_Mesh_i::GetBallDiameter(CORBA::Long id)
4743 _preMeshInfo->FullLoadFromFile();
4745 if ( const SMDS_BallElement* ball =
4746 dynamic_cast<const SMDS_BallElement*>( _impl->GetMeshDS()->FindElement( id )))
4747 return ball->GetDiameter();
4752 //=============================================================================
4754 * Returns bary center for given element
4756 //=============================================================================
4758 SMESH::double_array* SMESH_Mesh_i::BaryCenter(const CORBA::Long id)
4761 _preMeshInfo->FullLoadFromFile();
4763 SMESH::double_array_var aResult = new SMESH::double_array();
4764 SMESHDS_Mesh* aSMESHDS_Mesh = _impl->GetMeshDS();
4765 if ( aSMESHDS_Mesh == NULL )
4766 return aResult._retn();
4768 const SMDS_MeshElement* elem = aSMESHDS_Mesh->FindElement(id);
4770 return aResult._retn();
4772 if(elem->GetType()==SMDSAbs_Volume) {
4773 SMDS_VolumeTool aTool;
4774 if(aTool.Set(elem)) {
4776 if (!aTool.GetBaryCenter( aResult[0], aResult[1], aResult[2]) )
4781 SMDS_ElemIteratorPtr anIt = elem->nodesIterator();
4783 double x=0., y=0., z=0.;
4784 for(; anIt->more(); ) {
4786 const SMDS_MeshNode* aNode = static_cast<const SMDS_MeshNode*>(anIt->next());
4800 return aResult._retn();
4803 //================================================================================
4805 * \brief Create a group of elements preventing computation of a sub-shape
4807 //================================================================================
4809 SMESH::ListOfGroups*
4810 SMESH_Mesh_i::MakeGroupsOfBadInputElements( int theSubShapeID,
4811 const char* theGroupName )
4812 throw ( SALOME::SALOME_Exception )
4814 Unexpect aCatch(SALOME_SalomeException);
4816 if ( !theGroupName || strlen( theGroupName) == 0 )
4817 THROW_SALOME_CORBA_EXCEPTION( "empty group name",SALOME::BAD_PARAM );
4819 SMESH::ListOfGroups_var groups = new SMESH::ListOfGroups;
4821 // submesh by subshape id
4822 if ( !_impl->HasShapeToMesh() ) theSubShapeID = 1;
4823 if ( SMESH_subMesh * sm = _impl->GetSubMeshContaining( theSubShapeID ))
4826 SMESH_ComputeErrorPtr error = sm->GetComputeError();
4827 if ( error && !error->myBadElements.empty())
4829 // sort bad elements by type
4830 vector< const SMDS_MeshElement* > elemsByType[ SMDSAbs_NbElementTypes ];
4831 list<const SMDS_MeshElement*>::iterator elemIt = error->myBadElements.begin();
4832 list<const SMDS_MeshElement*>::iterator elemEnd = error->myBadElements.end();
4833 for ( ; elemIt != elemEnd; ++elemIt )
4835 const SMDS_MeshElement* elem = *elemIt;
4836 if ( !elem ) continue;
4838 if ( elem->GetID() < 1 )
4840 // elem is a temporary element, make a real element
4841 vector< const SMDS_MeshNode* > nodes;
4842 SMDS_NodeIteratorPtr nIt = elem->nodeIterator();
4843 while ( nIt->more() && elem )
4845 nodes.push_back( nIt->next() );
4846 if ( nodes.back()->GetID() < 1 )
4847 elem = 0; // a temporary element on temporary nodes
4851 ::SMESH_MeshEditor editor( _impl );
4852 elem = editor.AddElement( nodes, elem->GetType(), elem->IsPoly() );
4856 elemsByType[ elem->GetType() ].push_back( elem );
4859 // how many groups to create?
4861 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
4862 nbTypes += int( !elemsByType[ i ].empty() );
4863 groups->length( nbTypes );
4866 for ( int i = 0, iG = -1; i < SMDSAbs_NbElementTypes; ++i )
4868 vector< const SMDS_MeshElement* >& elems = elemsByType[ i ];
4869 if ( elems.empty() ) continue;
4871 groups[ ++iG ] = createGroup( SMESH::ElementType(i), theGroupName );
4872 if ( _gen_i->CanPublishInStudy( groups[ iG ] ))
4874 SALOMEDS::Study_var study = _gen_i->GetCurrentStudy();
4875 SMESH::SMESH_Mesh_var mesh = _this();
4876 SALOMEDS::SObject_wrap aSO =
4877 _gen_i->PublishGroup( study, mesh, groups[ iG ],
4878 GEOM::GEOM_Object::_nil(), theGroupName);
4880 SMESH_GroupBase_i* grp_i = SMESH::DownCast< SMESH_GroupBase_i* >( groups[ iG ]);
4881 if ( !grp_i ) continue;
4883 if ( SMESHDS_Group* grpDS = dynamic_cast< SMESHDS_Group* >( grp_i->GetGroupDS() ))
4884 for ( size_t iE = 0; iE < elems.size(); ++iE )
4885 grpDS->SMDSGroup().Add( elems[ iE ]);
4890 return groups._retn();
4893 //=============================================================================
4895 * Create and publish group servants if any groups were imported or created anyhow
4897 //=============================================================================
4899 void SMESH_Mesh_i::CreateGroupServants()
4901 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
4902 SMESH::SMESH_Mesh_var aMesh = _this();
4905 ::SMESH_Mesh::GroupIteratorPtr groupIt = _impl->GetGroups();
4906 while ( groupIt->more() )
4908 ::SMESH_Group* group = groupIt->next();
4909 int anId = group->GetGroupDS()->GetID();
4911 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(anId);
4912 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4914 addedIDs.insert( anId );
4916 SMESH_GroupBase_i* aGroupImpl;
4918 if ( SMESHDS_GroupOnGeom* groupOnGeom =
4919 dynamic_cast<SMESHDS_GroupOnGeom*>( group->GetGroupDS() ))
4921 aGroupImpl = new SMESH_GroupOnGeom_i( SMESH_Gen_i::GetPOA(), this, anId );
4922 shape = groupOnGeom->GetShape();
4925 aGroupImpl = new SMESH_Group_i( SMESH_Gen_i::GetPOA(), this, anId );
4928 SMESH::SMESH_GroupBase_var groupVar = aGroupImpl->_this();
4929 _mapGroups[anId] = SMESH::SMESH_GroupBase::_duplicate( groupVar );
4930 aGroupImpl->Register();
4932 // register CORBA object for persistence
4933 int nextId = _gen_i->RegisterObject( groupVar );
4934 if(MYDEBUG) { MESSAGE( "Add group to map with id = "<< nextId); }
4935 else { nextId = 0; } // avoid "unused variable" warning in release mode
4937 // publishing the groups in the study
4938 if ( !aStudy->_is_nil() ) {
4939 GEOM::GEOM_Object_var shapeVar = _gen_i->ShapeToGeomObject( shape );
4940 _gen_i->PublishGroup( aStudy, aMesh, groupVar, shapeVar, group->GetName());
4943 if ( !addedIDs.empty() )
4946 set<int>::iterator id = addedIDs.begin();
4947 for ( ; id != addedIDs.end(); ++id )
4949 map<int, SMESH::SMESH_GroupBase_ptr>::iterator it = _mapGroups.find(*id);
4950 int i = std::distance( _mapGroups.begin(), it );
4951 TPythonDump() << it->second << " = " << aMesh << ".GetGroups()[ "<< i << " ]";
4956 //=============================================================================
4958 * \brief Return groups cantained in _mapGroups by their IDs
4960 //=============================================================================
4962 SMESH::ListOfGroups* SMESH_Mesh_i::GetGroups(const list<int>& groupIDs) const
4964 int nbGroups = groupIDs.size();
4965 SMESH::ListOfGroups_var aList = new SMESH::ListOfGroups();
4966 aList->length( nbGroups );
4968 list<int>::const_iterator ids = groupIDs.begin();
4969 for ( nbGroups = 0; ids != groupIDs.end(); ++ids )
4971 map<int, SMESH::SMESH_GroupBase_ptr>::const_iterator it = _mapGroups.find( *ids );
4972 if ( it != _mapGroups.end() && !CORBA::is_nil( it->second ))
4973 aList[nbGroups++] = SMESH::SMESH_GroupBase::_duplicate( it->second );
4975 aList->length( nbGroups );
4976 return aList._retn();
4979 //=============================================================================
4981 * \brief Return information about imported file
4983 //=============================================================================
4985 SMESH::MedFileInfo* SMESH_Mesh_i::GetMEDFileInfo()
4987 SMESH::MedFileInfo_var res( _medFileInfo );
4988 if ( !res.operator->() ) {
4989 res = new SMESH::MedFileInfo;
4991 res->fileSize = res->major = res->minor = res->release = -1;
4996 //=============================================================================
4998 * \brief Pass names of mesh groups from study to mesh DS
5000 //=============================================================================
5002 void SMESH_Mesh_i::checkGroupNames()
5004 int nbGrp = NbGroups();
5008 SALOMEDS::Study_var aStudy = _gen_i->GetCurrentStudy();
5009 if ( aStudy->_is_nil() )
5010 return; // nothing to do
5012 SMESH::ListOfGroups* grpList = 0;
5013 // avoid dump of "GetGroups"
5015 // store python dump into a local variable inside local scope
5016 SMESH::TPythonDump pDump; // do not delete this line of code
5017 grpList = GetGroups();
5020 for ( int gIndx = 0; gIndx < nbGrp; gIndx++ ) {
5021 SMESH::SMESH_GroupBase_ptr aGrp = (*grpList)[ gIndx ];
5024 SALOMEDS::SObject_wrap aGrpSO = _gen_i->ObjectToSObject( aStudy, aGrp );
5025 if ( aGrpSO->_is_nil() )
5027 // correct name of the mesh group if necessary
5028 const char* guiName = aGrpSO->GetName();
5029 if ( strcmp(guiName, aGrp->GetName()) )
5030 aGrp->SetName( guiName );
5034 //=============================================================================
5036 * \brief Sets list of notebook variables used for Mesh operations separated by ":" symbol
5038 //=============================================================================
5039 void SMESH_Mesh_i::SetParameters(const char* theParameters)
5041 SMESH_Gen_i::GetSMESHGen()->UpdateParameters( CORBA::Object_var( _this() ).in(),
5045 //=============================================================================
5047 * \brief Returns list of notebook variables used for Mesh operations separated by ":" symbol
5049 //=============================================================================
5051 char* SMESH_Mesh_i::GetParameters()
5053 return SMESH_Gen_i::GetSMESHGen()->GetParameters( SMESH::SMESH_Mesh_var( _this()) );
5056 //=============================================================================
5058 * \brief Returns list of notebook variables used for last Mesh operation
5060 //=============================================================================
5061 SMESH::string_array* SMESH_Mesh_i::GetLastParameters()
5063 SMESH::string_array_var aResult = new SMESH::string_array();
5064 SMESH_Gen_i *gen = SMESH_Gen_i::GetSMESHGen();
5066 CORBA::String_var aParameters = GetParameters();
5067 SALOMEDS::Study_var aStudy = gen->GetCurrentStudy();
5068 if ( !aStudy->_is_nil()) {
5069 SALOMEDS::ListOfListOfStrings_var aSections = aStudy->ParseVariables(aParameters);
5070 if(aSections->length() > 0) {
5071 SALOMEDS::ListOfStrings aVars = aSections[aSections->length()-1];
5072 aResult->length(aVars.length());
5073 for(int i = 0;i < aVars.length();i++)
5074 aResult[i] = CORBA::string_dup( aVars[i]);
5078 return aResult._retn();
5081 //=======================================================================
5082 //function : GetTypes
5083 //purpose : Returns types of elements it contains
5084 //=======================================================================
5086 SMESH::array_of_ElementType* SMESH_Mesh_i::GetTypes()
5089 return _preMeshInfo->GetTypes();
5091 SMESH::array_of_ElementType_var types = new SMESH::array_of_ElementType;
5095 if (_impl->NbEdges()) types[nbTypes++] = SMESH::EDGE;
5096 if (_impl->NbFaces()) types[nbTypes++] = SMESH::FACE;
5097 if (_impl->NbVolumes()) types[nbTypes++] = SMESH::VOLUME;
5098 if (_impl->Nb0DElements()) types[nbTypes++] = SMESH::ELEM0D;
5099 if (_impl->NbBalls()) types[nbTypes++] = SMESH::BALL;
5100 types->length( nbTypes );
5102 return types._retn();
5105 //=======================================================================
5106 //function : GetMesh
5107 //purpose : Returns self
5108 //=======================================================================
5110 SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh()
5112 return SMESH::SMESH_Mesh::_duplicate( _this() );
5115 //=======================================================================
5116 //function : IsMeshInfoCorrect
5117 //purpose : * Returns false if GetMeshInfo() returns incorrect information that may
5118 // * happen if mesh data is not yet fully loaded from the file of study.
5119 //=======================================================================
5121 bool SMESH_Mesh_i::IsMeshInfoCorrect()
5123 return _preMeshInfo ? _preMeshInfo->IsMeshInfoCorrect() : true;
5126 //=============================================================================
5128 * \brief Returns number of mesh elements per each \a EntityType
5130 //=============================================================================
5132 SMESH::long_array* SMESH_Mesh_i::GetMeshInfo()
5135 return _preMeshInfo->GetMeshInfo();
5137 SMESH::long_array_var aRes = new SMESH::long_array();
5138 aRes->length(SMESH::Entity_Last);
5139 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5141 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5143 return aRes._retn();
5144 const SMDS_MeshInfo& aMeshInfo = aMeshDS->GetMeshInfo();
5145 for (int i = SMESH::Entity_Node; i < SMESH::Entity_Last; i++)
5146 aRes[i] = aMeshInfo.NbEntities((SMDSAbs_EntityType)i);
5147 return aRes._retn();
5150 //=============================================================================
5152 * \brief Returns number of mesh elements per each \a ElementType
5154 //=============================================================================
5156 SMESH::long_array* SMESH_Mesh_i::GetNbElementsByType()
5158 SMESH::long_array_var aRes = new SMESH::long_array();
5159 aRes->length(SMESH::NB_ELEMENT_TYPES);
5160 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5163 const SMDS_MeshInfo* meshInfo = 0;
5165 meshInfo = _preMeshInfo;
5166 else if ( SMESHDS_Mesh* meshDS = _impl->GetMeshDS() )
5167 meshInfo = & meshDS->GetMeshInfo();
5170 for (int i = 0; i < SMESH::NB_ELEMENT_TYPES; i++)
5171 aRes[i] = meshInfo->NbElements((SMDSAbs_ElementType)i);
5173 return aRes._retn();
5176 //=============================================================================
5178 * Collect statistic of mesh elements given by iterator
5180 //=============================================================================
5182 void SMESH_Mesh_i::CollectMeshInfo(const SMDS_ElemIteratorPtr theItr,
5183 SMESH::long_array& theInfo)
5185 if (!theItr) return;
5186 while (theItr->more())
5187 theInfo[ theItr->next()->GetEntityType() ]++;
5189 //=============================================================================
5191 * Returns mesh unstructed grid information.
5193 //=============================================================================
5195 SALOMEDS::TMPFile* SMESH_Mesh_i::GetVtkUgStream()
5197 SALOMEDS::TMPFile_var SeqFile;
5198 if ( SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS() ) {
5199 SMDS_UnstructuredGrid* aGrid = aMeshDS->getGrid();
5201 vtkUnstructuredGridWriter* aWriter = vtkUnstructuredGridWriter::New();
5202 aWriter->WriteToOutputStringOn();
5203 aWriter->SetInputData(aGrid);
5204 aWriter->SetFileTypeToBinary();
5206 char* str = aWriter->GetOutputString();
5207 int size = aWriter->GetOutputStringLength();
5209 //Allocate octect buffer of required size
5210 CORBA::Octet* OctetBuf = SALOMEDS::TMPFile::allocbuf(size);
5211 //Copy ostrstream content to the octect buffer
5212 memcpy(OctetBuf, str, size);
5213 //Create and return TMPFile
5214 SeqFile = new SALOMEDS::TMPFile(size, size, OctetBuf, 1);
5218 return SeqFile._retn();
5221 //=============================================================================
5222 namespace /* Iterators used in SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_var obj,
5223 * SMESH::ElementType type) */
5225 using namespace SMESH::Controls;
5226 //-----------------------------------------------------------------------------
5227 struct PredicateIterator : public SMDS_ElemIterator
5229 SMDS_ElemIteratorPtr _elemIter;
5230 PredicatePtr _predicate;
5231 const SMDS_MeshElement* _elem;
5233 PredicateIterator( SMDS_ElemIteratorPtr iterator,
5234 PredicatePtr predicate):
5235 _elemIter(iterator), _predicate(predicate)
5243 virtual const SMDS_MeshElement* next()
5245 const SMDS_MeshElement* res = _elem;
5247 while ( _elemIter->more() && !_elem )
5249 _elem = _elemIter->next();
5250 if ( _elem && ( !_predicate->IsSatisfy( _elem->GetID() )))
5257 //-----------------------------------------------------------------------------
5258 struct IDSourceIterator : public SMDS_ElemIterator
5260 const CORBA::Long* _idPtr;
5261 const CORBA::Long* _idEndPtr;
5262 SMESH::long_array_var _idArray;
5263 const SMDS_Mesh* _mesh;
5264 const SMDSAbs_ElementType _type;
5265 const SMDS_MeshElement* _elem;
5267 IDSourceIterator( const SMDS_Mesh* mesh,
5268 const CORBA::Long* ids,
5270 SMDSAbs_ElementType type):
5271 _idPtr( ids ), _idEndPtr( ids + nbIds ), _mesh( mesh ), _type( type ), _elem( 0 )
5273 if ( _idPtr && nbIds && _mesh )
5276 IDSourceIterator( const SMDS_Mesh* mesh,
5277 SMESH::long_array* idArray,
5278 SMDSAbs_ElementType type):
5279 _idPtr( 0 ), _idEndPtr( 0 ), _idArray( idArray), _mesh( mesh ), _type( type ), _elem( 0 )
5281 if ( idArray && _mesh )
5283 _idPtr = &_idArray[0];
5284 _idEndPtr = _idPtr + _idArray->length();
5292 virtual const SMDS_MeshElement* next()
5294 const SMDS_MeshElement* res = _elem;
5296 while ( _idPtr < _idEndPtr && !_elem )
5298 if ( _type == SMDSAbs_Node )
5300 _elem = _mesh->FindNode( *_idPtr++ );
5302 else if ((_elem = _mesh->FindElement( *_idPtr++ )) &&
5303 (_elem->GetType() != _type && _type != SMDSAbs_All ))
5311 //-----------------------------------------------------------------------------
5313 struct NodeOfElemIterator : public SMDS_ElemIterator
5315 TColStd_MapOfInteger _checkedNodeIDs;
5316 SMDS_ElemIteratorPtr _elemIter;
5317 SMDS_ElemIteratorPtr _nodeIter;
5318 const SMDS_MeshElement* _node;
5320 NodeOfElemIterator( SMDS_ElemIteratorPtr iter ): _elemIter( iter ), _node( 0 )
5322 if ( _elemIter && _elemIter->more() )
5324 _nodeIter = _elemIter->next()->nodesIterator();
5332 virtual const SMDS_MeshElement* next()
5334 const SMDS_MeshElement* res = _node;
5336 while (( _elemIter->more() || _nodeIter->more() ) && !_node )
5338 if ( _nodeIter->more() )
5340 _node = _nodeIter->next();
5341 if ( !_checkedNodeIDs.Add( _node->GetID() ))
5346 _nodeIter = _elemIter->next()->nodesIterator();
5354 //=============================================================================
5356 * Return iterator on elements of given type in given object
5358 //=============================================================================
5360 SMDS_ElemIteratorPtr SMESH_Mesh_i::GetElements(SMESH::SMESH_IDSource_ptr theObject,
5361 SMESH::ElementType theType)
5363 SMDS_ElemIteratorPtr elemIt;
5364 bool typeOK = false;
5365 SMDSAbs_ElementType elemType = SMDSAbs_ElementType( theType );
5367 SMESH::SMESH_Mesh_var meshVar = theObject->GetMesh();
5368 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( meshVar );
5369 if ( !mesh_i ) return elemIt;
5370 SMESHDS_Mesh* meshDS = mesh_i->GetImpl().GetMeshDS();
5372 if ( SMESH::DownCast<SMESH_Mesh_i*>( theObject ))
5374 elemIt = meshDS->elementsIterator( elemType );
5377 else if ( SMESH_subMesh_i* submesh_i = SMESH::DownCast<SMESH_subMesh_i*>( theObject ))
5379 SMESHDS_SubMesh* sm = ((SMESHDS_Mesh*) meshDS)->MeshElements( submesh_i->GetId() );
5382 elemIt = sm->GetElements();
5383 if ( elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5385 typeOK = ( elemIt && elemIt->more() && elemIt->next()->GetType() == elemType );
5386 elemIt = typeOK ? sm->GetElements() : SMDS_ElemIteratorPtr();
5390 else if ( SMESH_GroupBase_i* group_i = SMESH::DownCast<SMESH_GroupBase_i*>( theObject ))
5392 SMESHDS_GroupBase* groupDS = group_i->GetGroupDS();
5393 if ( groupDS && ( elemType == groupDS->GetType() ||
5394 elemType == SMDSAbs_Node ||
5395 elemType == SMDSAbs_All ))
5397 elemIt = groupDS->GetElements();
5398 typeOK = ( groupDS->GetType() == elemType || elemType == SMDSAbs_All );
5401 else if ( SMESH::Filter_i* filter_i = SMESH::DownCast<SMESH::Filter_i*>( theObject ))
5403 if ( filter_i->GetElementType() == theType ||
5404 elemType == SMDSAbs_Node ||
5405 elemType == SMDSAbs_All)
5407 SMESH::Predicate_i* pred_i = filter_i->GetPredicate_i();
5408 if ( pred_i && pred_i->GetPredicate() )
5410 SMDSAbs_ElementType filterType = SMDSAbs_ElementType( filter_i->GetElementType() );
5411 SMDS_ElemIteratorPtr allElemIt = meshDS->elementsIterator( filterType );
5412 elemIt = SMDS_ElemIteratorPtr( new PredicateIterator( allElemIt, pred_i->GetPredicate() ));
5413 typeOK = ( filterType == elemType || elemType == SMDSAbs_All );
5419 SMESH::array_of_ElementType_var types = theObject->GetTypes();
5420 const bool isNodes = ( types->length() == 1 && types[0] == SMESH::NODE );
5421 if ( isNodes && elemType != SMDSAbs_Node && elemType != SMDSAbs_All )
5423 if ( SMESH_MeshEditor_i::IsTemporaryIDSource( theObject ))
5426 if ( CORBA::Long* ids = SMESH_MeshEditor_i::GetTemporaryIDs( theObject, nbIds ))
5427 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids, nbIds, elemType ));
5431 SMESH::long_array_var ids = theObject->GetIDs();
5432 elemIt = SMDS_ElemIteratorPtr( new IDSourceIterator( meshDS, ids._retn(), elemType ));
5434 typeOK = ( isNodes == ( elemType == SMDSAbs_Node )) || ( elemType == SMDSAbs_All );
5437 if ( elemIt && elemIt->more() && !typeOK )
5439 if ( elemType == SMDSAbs_Node )
5441 elemIt = SMDS_ElemIteratorPtr( new NodeOfElemIterator( elemIt ));
5445 elemIt = SMDS_ElemIteratorPtr();
5451 //=============================================================================
5452 namespace // Finding concurrent hypotheses
5453 //=============================================================================
5457 * \brief mapping of mesh dimension into shape type
5459 TopAbs_ShapeEnum shapeTypeByDim(const int theDim)
5461 TopAbs_ShapeEnum aType = TopAbs_SOLID;
5463 case 0: aType = TopAbs_VERTEX; break;
5464 case 1: aType = TopAbs_EDGE; break;
5465 case 2: aType = TopAbs_FACE; break;
5467 default:aType = TopAbs_SOLID; break;
5472 //-----------------------------------------------------------------------------
5474 * \brief Internal structure used to find concurent submeshes
5476 * It represents a pair < submesh, concurent dimension >, where
5477 * 'concurrent dimension' is dimension of shape where the submesh can concurent
5478 * with another submesh. In other words, it is dimension of a hypothesis assigned
5485 int _dim; //!< a dimension the algo can build (concurrent dimension)
5486 int _ownDim; //!< dimension of shape of _subMesh (>=_dim)
5487 TopTools_MapOfShape _shapeMap;
5488 SMESH_subMesh* _subMesh;
5489 list<const SMESHDS_Hypothesis*> _hypotheses; //!< algo is first, then its parameters
5491 //-----------------------------------------------------------------------------
5492 // Return the algorithm
5493 const SMESH_Algo* GetAlgo() const
5494 { return _hypotheses.empty() ? 0 : dynamic_cast<const SMESH_Algo*>( _hypotheses.front() ); }
5496 //-----------------------------------------------------------------------------
5498 SMESH_DimHyp(const SMESH_subMesh* theSubMesh,
5500 const TopoDS_Shape& theShape)
5502 _subMesh = (SMESH_subMesh*)theSubMesh;
5503 SetShape( theDim, theShape );
5506 //-----------------------------------------------------------------------------
5508 void SetShape(const int theDim,
5509 const TopoDS_Shape& theShape)
5512 _ownDim = SMESH_Gen::GetShapeDim(theShape);
5513 if (_dim >= _ownDim)
5514 _shapeMap.Add( theShape );
5516 TopExp_Explorer anExp( theShape, shapeTypeByDim(theDim) );
5517 for( ; anExp.More(); anExp.Next() )
5518 _shapeMap.Add( anExp.Current() );
5522 //-----------------------------------------------------------------------------
5523 //! Check sharing of sub-shapes
5524 static bool isShareSubShapes(const TopTools_MapOfShape& theToCheck,
5525 const TopTools_MapOfShape& theToFind,
5526 const TopAbs_ShapeEnum theType)
5528 bool isShared = false;
5529 TopTools_MapIteratorOfMapOfShape anItr( theToCheck );
5530 for (; !isShared && anItr.More(); anItr.Next() )
5532 const TopoDS_Shape aSubSh = anItr.Key();
5533 // check for case when concurrent dimensions are same
5534 isShared = theToFind.Contains( aSubSh );
5535 // check for sub-shape with concurrent dimension
5536 TopExp_Explorer anExp( aSubSh, theType );
5537 for ( ; !isShared && anExp.More(); anExp.Next() )
5538 isShared = theToFind.Contains( anExp.Current() );
5543 //-----------------------------------------------------------------------------
5544 //! check algorithms
5545 static bool checkAlgo(const SMESHDS_Hypothesis* theA1,
5546 const SMESHDS_Hypothesis* theA2)
5548 if ( !theA1 || !theA2 ||
5549 theA1->GetType() == SMESHDS_Hypothesis::PARAM_ALGO ||
5550 theA2->GetType() == SMESHDS_Hypothesis::PARAM_ALGO )
5551 return false; // one of the hypothesis is not algorithm
5552 // check algorithm names (should be equal)
5553 return strcmp( theA1->GetName(), theA2->GetName() ) == 0;
5557 //-----------------------------------------------------------------------------
5558 //! Check if sub-shape hypotheses are concurrent
5559 bool IsConcurrent(const SMESH_DimHyp* theOther) const
5561 if ( _subMesh == theOther->_subMesh )
5562 return false; // same sub-shape - should not be
5564 // if ( <own dim of either of submeshes> == <concurrent dim> &&
5565 // any of the two submeshes is not on COMPOUND shape )
5566 // -> no concurrency
5567 bool meIsCompound = (_subMesh->GetSubMeshDS() &&
5568 _subMesh->GetSubMeshDS()->IsComplexSubmesh());
5569 bool otherIsCompound = (theOther->_subMesh->GetSubMeshDS() &&
5570 theOther->_subMesh->GetSubMeshDS()->IsComplexSubmesh());
5571 if ( (_ownDim == _dim || theOther->_ownDim == _dim ) && (!meIsCompound || !otherIsCompound))
5574 // bool checkSubShape = ( _dim >= theOther->_dim )
5575 // ? isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(theOther->_dim) )
5576 // : isShareSubShapes( theOther->_shapeMap, _shapeMap, shapeTypeByDim(_dim) ) ;
5577 bool checkSubShape = isShareSubShapes( _shapeMap, theOther->_shapeMap, shapeTypeByDim(_dim));
5578 if ( !checkSubShape )
5581 // check algorithms to be same
5582 if ( !checkAlgo( this->GetAlgo(), theOther->GetAlgo() ))
5583 return true; // different algorithms -> concurrency !
5585 // check hypothesises for concurrence (skip first as algorithm)
5587 // pointers should be same, because it is referened from mesh hypothesis partition
5588 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = _hypotheses.begin();
5589 list <const SMESHDS_Hypothesis*>::const_iterator otheEndIt = theOther->_hypotheses.end();
5590 for ( hypIt++ /*skip first as algo*/; hypIt != _hypotheses.end(); hypIt++ )
5591 if ( find( theOther->_hypotheses.begin(), otheEndIt, *hypIt ) != otheEndIt )
5593 // the submeshes are concurrent if their algorithms has different parameters
5594 return nbSame != theOther->_hypotheses.size() - 1;
5597 // Return true if algorithm of this SMESH_DimHyp is used if no
5598 // sub-mesh order is imposed by the user
5599 bool IsHigherPriorityThan( const SMESH_DimHyp* theOther ) const
5601 // NeedDiscreteBoundary() algo has a higher priority
5602 if ( this ->GetAlgo()->NeedDiscreteBoundary() !=
5603 theOther->GetAlgo()->NeedDiscreteBoundary() )
5604 return !this->GetAlgo()->NeedDiscreteBoundary();
5606 return ( this->_subMesh->GetId() < theOther->_subMesh->GetId() );
5609 }; // end of SMESH_DimHyp
5610 //-----------------------------------------------------------------------------
5612 typedef list<const SMESH_DimHyp*> TDimHypList;
5614 //-----------------------------------------------------------------------------
5616 void addDimHypInstance(const int theDim,
5617 const TopoDS_Shape& theShape,
5618 const SMESH_Algo* theAlgo,
5619 const SMESH_subMesh* theSubMesh,
5620 const list <const SMESHDS_Hypothesis*>& theHypList,
5621 TDimHypList* theDimHypListArr )
5623 TDimHypList& listOfdimHyp = theDimHypListArr[theDim];
5624 if ( listOfdimHyp.empty() || listOfdimHyp.back()->_subMesh != theSubMesh ) {
5625 SMESH_DimHyp* dimHyp = new SMESH_DimHyp( theSubMesh, theDim, theShape );
5626 dimHyp->_hypotheses.push_front(theAlgo);
5627 listOfdimHyp.push_back( dimHyp );
5630 SMESH_DimHyp* dimHyp = const_cast<SMESH_DimHyp*>( listOfdimHyp.back() );
5631 dimHyp->_hypotheses.insert( dimHyp->_hypotheses.end(),
5632 theHypList.begin(), theHypList.end() );
5635 //-----------------------------------------------------------------------------
5636 void addInOrderOfPriority( const SMESH_DimHyp* theDimHyp,
5637 TDimHypList& theListOfConcurr)
5639 if ( theListOfConcurr.empty() )
5641 theListOfConcurr.push_back( theDimHyp );
5645 TDimHypList::iterator hypIt = theListOfConcurr.begin();
5646 while ( hypIt != theListOfConcurr.end() &&
5647 !theDimHyp->IsHigherPriorityThan( *hypIt ))
5649 theListOfConcurr.insert( hypIt, theDimHyp );
5653 //-----------------------------------------------------------------------------
5654 void findConcurrents(const SMESH_DimHyp* theDimHyp,
5655 const TDimHypList& theListOfDimHyp,
5656 TDimHypList& theListOfConcurrHyp,
5657 set<int>& theSetOfConcurrId )
5659 TDimHypList::const_reverse_iterator rIt = theListOfDimHyp.rbegin();
5660 for ( ; rIt != theListOfDimHyp.rend(); rIt++ )
5662 const SMESH_DimHyp* curDimHyp = *rIt;
5663 if ( curDimHyp == theDimHyp )
5664 break; // meet own dimHyp pointer in same dimension
5666 if ( theDimHyp->IsConcurrent( curDimHyp ) &&
5667 theSetOfConcurrId.insert( curDimHyp->_subMesh->GetId() ).second )
5669 addInOrderOfPriority( curDimHyp, theListOfConcurrHyp );
5674 //-----------------------------------------------------------------------------
5675 void unionLists(TListOfInt& theListOfId,
5676 TListOfListOfInt& theListOfListOfId,
5679 TListOfListOfInt::iterator it = theListOfListOfId.begin();
5680 for ( int i = 0; it != theListOfListOfId.end(); it++, i++ ) {
5682 continue; //skip already treated lists
5683 // check if other list has any same submesh object
5684 TListOfInt& otherListOfId = *it;
5685 if ( find_first_of( theListOfId.begin(), theListOfId.end(),
5686 otherListOfId.begin(), otherListOfId.end() ) == theListOfId.end() )
5689 // union two lists (from source into target)
5690 TListOfInt::iterator it2 = otherListOfId.begin();
5691 for ( ; it2 != otherListOfId.end(); it2++ ) {
5692 if ( find( theListOfId.begin(), theListOfId.end(), (*it2) ) == theListOfId.end() )
5693 theListOfId.push_back(*it2);
5695 // clear source list
5696 otherListOfId.clear();
5699 //-----------------------------------------------------------------------------
5701 //! free memory allocated for dimension-hypothesis objects
5702 void removeDimHyps( TDimHypList* theArrOfList )
5704 for (int i = 0; i < 4; i++ ) {
5705 TDimHypList& listOfdimHyp = theArrOfList[i];
5706 TDimHypList::const_iterator it = listOfdimHyp.begin();
5707 for ( ; it != listOfdimHyp.end(); it++ )
5712 //-----------------------------------------------------------------------------
5714 * \brief find common submeshes with given submesh
5715 * \param theSubMeshList list of already collected submesh to check
5716 * \param theSubMesh given submesh to intersect with other
5717 * \param theCommonSubMeshes collected common submeshes
5719 void findCommonSubMesh (list<const SMESH_subMesh*>& theSubMeshList,
5720 const SMESH_subMesh* theSubMesh,
5721 set<const SMESH_subMesh*>& theCommon )
5725 list<const SMESH_subMesh*>::const_iterator it = theSubMeshList.begin();
5726 for ( ; it != theSubMeshList.end(); it++ )
5727 theSubMesh->FindIntersection( *it, theCommon );
5728 theSubMeshList.push_back( theSubMesh );
5729 //theCommon.insert( theSubMesh );
5732 //-----------------------------------------------------------------------------
5733 bool isSubMeshInList ( int smID, const TListOfListOfInt& smLists )
5735 TListOfListOfInt::const_iterator listsIt = smLists.begin();
5736 for ( ; listsIt != smLists.end(); ++listsIt )
5738 const TListOfInt& smIDs = *listsIt;
5739 if ( std::find( smIDs.begin(), smIDs.end(), smID ) != smIDs.end() )
5747 //=============================================================================
5749 * \brief Return \c true if a meshing order not yet set for a concurrent sub-mesh
5751 //=============================================================================
5753 CORBA::Boolean SMESH_Mesh_i::IsUnorderedSubMesh(CORBA::Long submeshID)
5755 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5756 if ( isSubMeshInList( submeshID, anOrder ))
5759 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5760 return isSubMeshInList( submeshID, allConurrent );
5763 //=============================================================================
5765 * \brief Return submesh objects list in meshing order
5767 //=============================================================================
5769 SMESH::submesh_array_array* SMESH_Mesh_i::GetMeshOrder()
5771 SMESH::submesh_array_array_var aResult = new SMESH::submesh_array_array();
5773 SMESHDS_Mesh* aMeshDS = _impl->GetMeshDS();
5775 return aResult._retn();
5777 TListOfListOfInt anOrder = GetImpl().GetMeshOrder(); // already defined order
5778 TListOfListOfInt allConurrent = findConcurrentSubMeshes();
5779 anOrder.splice( anOrder.end(), allConurrent );
5782 TListOfListOfInt::iterator listIt = anOrder.begin();
5783 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5784 unionLists( *listIt, anOrder, listIndx + 1 );
5786 // convert submesh ids into interface instances
5787 // and dump command into python
5788 convertMeshOrder( anOrder, aResult, false );
5790 return aResult._retn();
5793 //=============================================================================
5795 * \brief Finds concurrent sub-meshes
5797 //=============================================================================
5799 TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes()
5801 TListOfListOfInt anOrder;
5802 ::SMESH_Mesh& mesh = GetImpl();
5804 // collect submeshes and detect concurrent algorithms and hypothesises
5805 TDimHypList dimHypListArr[4]; // dimHyp list for each shape dimension
5807 map<int, ::SMESH_subMesh*>::iterator i_sm = _mapSubMesh.begin();
5808 for ( ; i_sm != _mapSubMesh.end(); i_sm++ ) {
5809 ::SMESH_subMesh* sm = (*i_sm).second;
5811 const TopoDS_Shape& aSubMeshShape = sm->GetSubShape();
5813 // list of assigned hypothesises
5814 const list <const SMESHDS_Hypothesis*>& hypList = mesh.GetHypothesisList(aSubMeshShape);
5815 // Find out dimensions where the submesh can be concurrent.
5816 // We define the dimensions by algo of each of hypotheses in hypList
5817 list <const SMESHDS_Hypothesis*>::const_iterator hypIt = hypList.begin();
5818 for( ; hypIt != hypList.end(); hypIt++ ) {
5819 SMESH_Algo* anAlgo = 0;
5820 const SMESH_Hypothesis* hyp = dynamic_cast<const SMESH_Hypothesis*>(*hypIt);
5821 if ( hyp->GetType() != SMESHDS_Hypothesis::PARAM_ALGO )
5822 // hyp it-self is algo
5823 anAlgo = (SMESH_Algo*)dynamic_cast<const SMESH_Algo*>(hyp);
5825 // try to find algorithm with help of sub-shapes
5826 TopExp_Explorer anExp( aSubMeshShape, shapeTypeByDim(hyp->GetDim()) );
5827 for ( ; !anAlgo && anExp.More(); anExp.Next() )
5828 anAlgo = mesh.GetGen()->GetAlgo( mesh, anExp.Current() );
5831 continue; // no algorithm assigned to a current submesh
5833 int dim = anAlgo->GetDim(); // top concurrent dimension (see comment to SMESH_DimHyp)
5834 // the submesh can concurrent at <dim> (or lower dims if !anAlgo->NeedDiscreteBoundary())
5836 // create instance of dimension-hypothesis for found concurrent dimension(s) and algorithm
5837 for ( int j = anAlgo->NeedDiscreteBoundary() ? dim : 1, jn = dim; j <= jn; j++ )
5838 addDimHypInstance( j, aSubMeshShape, anAlgo, sm, hypList, dimHypListArr );
5840 } // end iterations on submesh
5842 // iterate on created dimension-hypotheses and check for concurrents
5843 for ( int i = 0; i < 4; i++ ) {
5844 const TDimHypList& listOfDimHyp = dimHypListArr[i];
5845 // check for concurrents in own and other dimensions (step-by-step)
5846 TDimHypList::const_iterator dhIt = listOfDimHyp.begin();
5847 for ( ; dhIt != listOfDimHyp.end(); dhIt++ ) {
5848 const SMESH_DimHyp* dimHyp = *dhIt;
5849 TDimHypList listOfConcurr;
5850 set<int> setOfConcurrIds;
5851 // looking for concurrents and collect into own list
5852 for ( int j = i; j < 4; j++ )
5853 findConcurrents( dimHyp, dimHypListArr[j], listOfConcurr, setOfConcurrIds );
5854 // check if any concurrents found
5855 if ( listOfConcurr.size() > 0 ) {
5856 // add own submesh to list of concurrent
5857 addInOrderOfPriority( dimHyp, listOfConcurr );
5858 list<int> listOfConcurrIds;
5859 TDimHypList::iterator hypIt = listOfConcurr.begin();
5860 for ( ; hypIt != listOfConcurr.end(); ++hypIt )
5861 listOfConcurrIds.push_back( (*hypIt)->_subMesh->GetId() );
5862 anOrder.push_back( listOfConcurrIds );
5867 removeDimHyps(dimHypListArr);
5869 // now, minimise the number of concurrent groups
5870 // Here we assume that lists of submeshes can have same submesh
5871 // in case of multi-dimension algorithms, as result
5872 // list with common submesh has to be united into one list
5874 TListOfListOfInt::iterator listIt = anOrder.begin();
5875 for(; listIt != anOrder.end(); listIt++, listIndx++ )
5876 unionLists( *listIt, anOrder, listIndx + 1 );
5882 //=============================================================================
5884 * \brief Set submesh object order
5885 * \param theSubMeshArray submesh array order
5887 //=============================================================================
5889 ::CORBA::Boolean SMESH_Mesh_i::SetMeshOrder(const SMESH::submesh_array_array& theSubMeshArray)
5892 _preMeshInfo->ForgetOrLoad();
5895 ::SMESH_Mesh& mesh = GetImpl();
5897 TPythonDump aPythonDump; // prevent dump of called methods
5898 aPythonDump << "isDone = " << SMESH::SMESH_Mesh_var(_this()) << ".SetMeshOrder( [ ";
5900 TListOfListOfInt subMeshOrder;
5901 for ( int i = 0, n = theSubMeshArray.length(); i < n; i++ )
5903 const SMESH::submesh_array& aSMArray = theSubMeshArray[i];
5904 TListOfInt subMeshIds;
5906 aPythonDump << ", ";
5907 aPythonDump << "[ ";
5908 // Collect subMeshes which should be clear
5909 // do it list-by-list, because modification of submesh order
5910 // take effect between concurrent submeshes only
5911 set<const SMESH_subMesh*> subMeshToClear;
5912 list<const SMESH_subMesh*> subMeshList;
5913 for ( int j = 0, jn = aSMArray.length(); j < jn; j++ )
5915 const SMESH::SMESH_subMesh_var subMesh = SMESH::SMESH_subMesh::_duplicate(aSMArray[j]);
5917 aPythonDump << ", ";
5918 aPythonDump << subMesh;
5919 subMeshIds.push_back( subMesh->GetId() );
5920 // detect common parts of submeshes
5921 if ( _mapSubMesh.find(subMesh->GetId()) != _mapSubMesh.end() )
5922 findCommonSubMesh( subMeshList, _mapSubMesh[ subMesh->GetId() ], subMeshToClear );
5924 aPythonDump << " ]";
5925 subMeshOrder.push_back( subMeshIds );
5927 // clear collected submeshes
5928 set<const SMESH_subMesh*>::iterator clrIt = subMeshToClear.begin();
5929 for ( ; clrIt != subMeshToClear.end(); clrIt++ )
5930 if ( SMESH_subMesh* sm = (SMESH_subMesh*)*clrIt )
5931 sm->ComputeStateEngine( SMESH_subMesh::CLEAN );
5933 aPythonDump << " ])";
5935 mesh.SetMeshOrder( subMeshOrder );
5941 //=============================================================================
5943 * \brief Convert submesh ids into submesh interfaces
5945 //=============================================================================
5947 void SMESH_Mesh_i::convertMeshOrder (const TListOfListOfInt& theIdsOrder,
5948 SMESH::submesh_array_array& theResOrder,
5949 const bool theIsDump)
5951 int nbSet = theIdsOrder.size();
5952 TPythonDump aPythonDump; // prevent dump of called methods
5954 aPythonDump << "[ ";
5955 theResOrder.length(nbSet);
5956 TListOfListOfInt::const_iterator it = theIdsOrder.begin();
5958 for( ; it != theIdsOrder.end(); it++ ) {
5959 // translate submesh identificators into submesh objects
5960 // takeing into account real number of concurrent lists
5961 const TListOfInt& aSubOrder = (*it);
5962 if (!aSubOrder.size())
5965 aPythonDump << "[ ";
5966 // convert shape indeces into interfaces
5967 SMESH::submesh_array_var aResSubSet = new SMESH::submesh_array();
5968 aResSubSet->length(aSubOrder.size());
5969 TListOfInt::const_iterator subIt = aSubOrder.begin();
5971 for( j = 0; subIt != aSubOrder.end(); subIt++ ) {
5972 if ( _mapSubMeshIor.find(*subIt) == _mapSubMeshIor.end() )
5974 SMESH::SMESH_subMesh_var subMesh =
5975 SMESH::SMESH_subMesh::_duplicate( _mapSubMeshIor[*subIt] );
5978 aPythonDump << ", ";
5979 aPythonDump << subMesh;
5981 aResSubSet[ j++ ] = subMesh;
5984 aPythonDump << " ]";
5986 theResOrder[ listIndx++ ] = aResSubSet;
5988 // correct number of lists
5989 theResOrder.length( listIndx );
5992 // finilise python dump
5993 aPythonDump << " ]";
5994 aPythonDump << " = " << SMESH::SMESH_Mesh_var(_this()) << ".GetMeshOrder()";
5998 //================================================================================
6000 // Implementation of SMESH_MeshPartDS
6002 SMESH_MeshPartDS::SMESH_MeshPartDS(SMESH::SMESH_IDSource_ptr meshPart):
6003 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true)
6005 SMESH::SMESH_Mesh_var mesh = meshPart->GetMesh();
6006 SMESH_Mesh_i* mesh_i = SMESH::DownCast<SMESH_Mesh_i*>( mesh );
6008 _meshDS = mesh_i->GetImpl().GetMeshDS();
6010 SetPersistentId( _meshDS->GetPersistentId() );
6012 if ( mesh_i == SMESH::DownCast<SMESH_Mesh_i*>( meshPart ))
6014 // <meshPart> is the whole mesh
6015 myInfo = _meshDS->GetMeshInfo(); // copy mesh info;
6017 set<SMESHDS_GroupBase*>& myGroupSet = const_cast<set<SMESHDS_GroupBase*>&>( GetGroups() );
6018 myGroupSet = _meshDS->GetGroups();
6023 SMESH::long_array_var anIDs = meshPart->GetIDs();
6024 SMESH::array_of_ElementType_var types = meshPart->GetTypes();
6025 if ( types->length() == 1 && types[0] == SMESH::NODE ) // group of nodes
6027 for (int i=0; i < anIDs->length(); i++)
6028 if ( const SMDS_MeshNode * n = _meshDS->FindNode(anIDs[i]))
6029 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6034 for (int i=0; i < anIDs->length(); i++)
6035 if ( const SMDS_MeshElement * e = _meshDS->FindElement(anIDs[i]))
6036 if ( _elements[ e->GetType() ].insert( e ).second )
6039 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6040 while ( nIt->more() )
6042 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6043 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6050 ShapeToMesh( _meshDS->ShapeToMesh() );
6052 _meshDS = 0; // to enforce iteration on _elements and _nodes
6055 // -------------------------------------------------------------------------------------
6056 SMESH_MeshPartDS::SMESH_MeshPartDS(const std::list< const SMDS_MeshElement* > & meshPart):
6057 SMESHDS_Mesh( /*meshID=*/-1, /*isEmbeddedMode=*/true), _meshDS(0)
6060 list< const SMDS_MeshElement* >::const_iterator partIt = meshPart.begin();
6061 for ( ; partIt != meshPart.end(); ++partIt )
6062 if ( const SMDS_MeshElement * e = *partIt )
6063 if ( _elements[ e->GetType() ].insert( e ).second )
6066 SMDS_ElemIteratorPtr nIt = e->nodesIterator();
6067 while ( nIt->more() )
6069 const SMDS_MeshNode * n = (const SMDS_MeshNode*) nIt->next();
6070 if ( _elements[ SMDSAbs_Node ].insert( n ).second )
6076 // -------------------------------------------------------------------------------------
6077 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementGeomIterator(SMDSAbs_GeometryType geomType) const
6079 if ( _meshDS ) return _meshDS->elementGeomIterator( geomType );
6081 typedef SMDS_SetIterator
6082 <const SMDS_MeshElement*,
6083 TIDSortedElemSet::const_iterator,
6084 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6085 SMDS_MeshElement::GeomFilter
6088 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( geomType );
6090 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6091 _elements[type].end(),
6092 SMDS_MeshElement::GeomFilter( geomType )));
6094 // -------------------------------------------------------------------------------------
6095 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementEntityIterator(SMDSAbs_EntityType entity) const
6097 if ( _meshDS ) return _meshDS->elementEntityIterator( entity );
6099 typedef SMDS_SetIterator
6100 <const SMDS_MeshElement*,
6101 TIDSortedElemSet::const_iterator,
6102 SMDS::SimpleAccessor<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator>,
6103 SMDS_MeshElement::EntityFilter
6106 SMDSAbs_ElementType type = SMDS_MeshCell::toSmdsType( entity );
6108 return SMDS_ElemIteratorPtr( new TIter( _elements[type].begin(),
6109 _elements[type].end(),
6110 SMDS_MeshElement::EntityFilter( entity )));
6112 // -------------------------------------------------------------------------------------
6113 SMDS_ElemIteratorPtr SMESH_MeshPartDS::elementsIterator(SMDSAbs_ElementType type) const
6115 typedef SMDS_SetIterator<const SMDS_MeshElement*, TIDSortedElemSet::const_iterator > TIter;
6116 if ( type == SMDSAbs_All && !_meshDS )
6118 typedef vector< SMDS_ElemIteratorPtr > TIterVec;
6120 for ( int i = 0; i < SMDSAbs_NbElementTypes; ++i )
6121 if ( !_elements[i].empty() && i != SMDSAbs_Node )
6123 ( SMDS_ElemIteratorPtr( new TIter( _elements[i].begin(), _elements[i].end() )));
6125 typedef SMDS_IteratorOnIterators<const SMDS_MeshElement*, TIterVec > TIterOnIters;
6126 return SMDS_ElemIteratorPtr( new TIterOnIters( iterVec ));
6128 return _meshDS ? _meshDS->elementsIterator(type) : SMDS_ElemIteratorPtr
6129 ( new TIter( _elements[type].begin(), _elements[type].end() ));
6131 // -------------------------------------------------------------------------------------
6132 #define _GET_ITER_DEFINE( iterType, methName, elem, elemType) \
6133 iterType SMESH_MeshPartDS::methName( bool idInceasingOrder) const \
6135 typedef SMDS_SetIterator<const elem*, TIDSortedElemSet::const_iterator > TIter; \
6136 return _meshDS ? _meshDS->methName(idInceasingOrder) : iterType \
6137 ( new TIter( _elements[elemType].begin(), _elements[elemType].end() )); \
6139 // -------------------------------------------------------------------------------------
6140 _GET_ITER_DEFINE( SMDS_NodeIteratorPtr, nodesIterator, SMDS_MeshNode, SMDSAbs_Node )
6141 _GET_ITER_DEFINE( SMDS_EdgeIteratorPtr, edgesIterator, SMDS_MeshEdge, SMDSAbs_Edge )
6142 _GET_ITER_DEFINE( SMDS_FaceIteratorPtr, facesIterator, SMDS_MeshFace, SMDSAbs_Face )
6143 _GET_ITER_DEFINE( SMDS_VolumeIteratorPtr, volumesIterator, SMDS_MeshVolume, SMDSAbs_Volume)
6144 #undef _GET_ITER_DEFINE
6146 // END Implementation of SMESH_MeshPartDS
6148 //================================================================================